[
  {
    "path": ".github/workflows/build_test.yml",
    "content": "name: Build/Test\n\non:\n  # Trigger on every pull request\n  pull_request:\n\npermissions:\n  contents: read\n\njobs:\n  build-test:\n    runs-on: macos-13\n    steps:\n      - name: Checkout epoxy\n        uses: actions/checkout@v4\n\n      - name: Setting up Java 17\n        uses: actions/setup-java@v4\n        with:\n          distribution: temurin\n          java-version: '17'\n\n      - name: Setup Gradle\n        uses: gradle/actions/setup-gradle@v4\n        with:\n          cache-read-only: ${{ github.ref != 'refs/heads/master' }}\n\n      - name: Build / Unit tests / Lint\n        run: \"./gradlew check --stacktrace\"\n\n      - name: Run UI Tests\n        uses: reactivecircus/android-emulator-runner@v2.32.0\n        with:\n          api-level: 21\n          target: default\n          arch: x86_64\n          emulator-options: -no-skin -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect\n          disable-animations: true\n          script: ./gradlew :epoxy-composeinterop-maverickssample:connectedDebugAndroidTest --stacktrace\n"
  },
  {
    "path": ".gitignore",
    "content": "# macOS\n.DS_Store\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.war\n*.ear\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n# IntelliJ\n*.iml\n.idea/\n!.idea/codeStyles/\n!.idea/codeStyleSettings.xml\n\n# Android\n.gradle\nbuild/\nlocal.properties\n\n# Kotlin\n.kotlin\n"
  },
  {
    "path": ".idea/codeStyleSettings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectCodeStyleSettingsManager\">\n    <option name=\"PER_PROJECT_SETTINGS\">\n      <value>\n        <option name=\"OTHER_INDENT_OPTIONS\">\n          <value>\n            <option name=\"INDENT_SIZE\" value=\"2\" />\n            <option name=\"CONTINUATION_INDENT_SIZE\" value=\"8\" />\n            <option name=\"TAB_SIZE\" value=\"8\" />\n            <option name=\"USE_TAB_CHARACTER\" value=\"false\" />\n            <option name=\"SMART_TABS\" value=\"false\" />\n            <option name=\"LABEL_INDENT_SIZE\" value=\"0\" />\n            <option name=\"LABEL_INDENT_ABSOLUTE\" value=\"false\" />\n            <option name=\"USE_RELATIVE_INDENTS\" value=\"false\" />\n          </value>\n        </option>\n        <option name=\"INSERT_INNER_CLASS_IMPORTS\" value=\"true\" />\n        <option name=\"CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"99\" />\n        <option name=\"NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"99\" />\n        <option name=\"PACKAGES_TO_USE_IMPORT_ON_DEMAND\">\n          <value />\n        </option>\n        <option name=\"IMPORT_LAYOUT_TABLE\">\n          <value>\n            <package name=\"android\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"com\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"junit\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"net\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"org\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"java\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"javax\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"\" withSubpackages=\"true\" static=\"false\" />\n            <emptyLine />\n            <package name=\"\" withSubpackages=\"true\" static=\"true\" />\n            <emptyLine />\n          </value>\n        </option>\n        <option name=\"RIGHT_MARGIN\" value=\"100\" />\n        <option name=\"JD_KEEP_INVALID_TAGS\" value=\"false\" />\n        <option name=\"JD_DO_NOT_WRAP_ONE_LINE_COMMENTS\" value=\"true\" />\n        <option name=\"JD_KEEP_EMPTY_PARAMETER\" value=\"false\" />\n        <option name=\"JD_KEEP_EMPTY_EXCEPTION\" value=\"false\" />\n        <option name=\"JD_KEEP_EMPTY_RETURN\" value=\"false\" />\n        <option name=\"WRAP_COMMENTS\" value=\"true\" />\n        <AndroidXmlCodeStyleSettings>\n          <option name=\"USE_CUSTOM_SETTINGS\" value=\"true\" />\n        </AndroidXmlCodeStyleSettings>\n        <JavaCodeStyleSettings>\n          <option name=\"ANNOTATION_PARAMETER_WRAP\" value=\"1\" />\n        </JavaCodeStyleSettings>\n        <MarkdownNavigatorCodeStyleSettings>\n          <option name=\"RIGHT_MARGIN\" value=\"72\" />\n        </MarkdownNavigatorCodeStyleSettings>\n        <Objective-C-extensions>\n          <file>\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Import\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Macro\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Typedef\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Enum\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Constant\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Global\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Struct\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"FunctionPredecl\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Function\" />\n          </file>\n          <class>\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Property\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Synthesize\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InitMethod\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"StaticMethod\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InstanceMethod\" />\n            <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"DeallocMethod\" />\n          </class>\n          <extensions>\n            <pair source=\"cpp\" header=\"h\" />\n            <pair source=\"c\" header=\"h\" />\n          </extensions>\n        </Objective-C-extensions>\n        <XML>\n          <option name=\"XML_KEEP_LINE_BREAKS\" value=\"false\" />\n          <option name=\"XML_KEEP_BLANK_LINES\" value=\"1\" />\n          <option name=\"XML_ALIGN_ATTRIBUTES\" value=\"false\" />\n          <option name=\"XML_SPACE_INSIDE_EMPTY_TAG\" value=\"true\" />\n          <option name=\"XML_LEGACY_SETTINGS_IMPORTED\" value=\"true\" />\n        </XML>\n        <codeStyleSettings language=\"Groovy\">\n          <indentOptions>\n            <option name=\"INDENT_SIZE\" value=\"2\" />\n            <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n            <option name=\"TAB_SIZE\" value=\"8\" />\n          </indentOptions>\n        </codeStyleSettings>\n        <codeStyleSettings language=\"JAVA\">\n          <option name=\"KEEP_BLANK_LINES_IN_DECLARATIONS\" value=\"1\" />\n          <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n          <option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"0\" />\n          <option name=\"BLANK_LINES_AROUND_METHOD_IN_INTERFACE\" value=\"0\" />\n          <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n          <option name=\"CALL_PARAMETERS_WRAP\" value=\"1\" />\n          <option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\" />\n          <option name=\"RESOURCE_LIST_WRAP\" value=\"1\" />\n          <option name=\"THROWS_LIST_WRAP\" value=\"1\" />\n          <option name=\"EXTENDS_KEYWORD_WRAP\" value=\"1\" />\n          <option name=\"THROWS_KEYWORD_WRAP\" value=\"1\" />\n          <option name=\"METHOD_CALL_CHAIN_WRAP\" value=\"1\" />\n          <option name=\"BINARY_OPERATION_WRAP\" value=\"1\" />\n          <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n          <option name=\"TERNARY_OPERATION_WRAP\" value=\"1\" />\n          <option name=\"KEEP_SIMPLE_CLASSES_IN_ONE_LINE\" value=\"true\" />\n          <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n          <option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\" />\n          <option name=\"ASSIGNMENT_WRAP\" value=\"1\" />\n          <option name=\"ASSERT_STATEMENT_WRAP\" value=\"1\" />\n          <option name=\"IF_BRACE_FORCE\" value=\"3\" />\n          <option name=\"FOR_BRACE_FORCE\" value=\"3\" />\n          <option name=\"WRAP_LONG_LINES\" value=\"true\" />\n          <option name=\"FIELD_ANNOTATION_WRAP\" value=\"1\" />\n          <option name=\"PARAMETER_ANNOTATION_WRAP\" value=\"1\" />\n          <option name=\"VARIABLE_ANNOTATION_WRAP\" value=\"1\" />\n          <option name=\"ENUM_CONSTANTS_WRAP\" value=\"2\" />\n          <indentOptions>\n            <option name=\"INDENT_SIZE\" value=\"2\" />\n            <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n            <option name=\"TAB_SIZE\" value=\"8\" />\n          </indentOptions>\n        </codeStyleSettings>\n        <codeStyleSettings language=\"XML\">\n          <option name=\"FORCE_REARRANGE_MODE\" value=\"1\" />\n          <indentOptions>\n            <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n          </indentOptions>\n          <arrangement>\n            <rules>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>xmlns:android</NAME>\n                      <XML_NAMESPACE>Namespace:</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>xmlns:.*</NAME>\n                      <XML_NAMESPACE>Namespace:</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:id</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:name</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>name</NAME>\n                      <XML_NAMESPACE>^$</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>style</NAME>\n                      <XML_NAMESPACE>^$</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*</NAME>\n                      <XML_NAMESPACE>^$</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:layout_width</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:layout_height</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:layout_.*</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:width</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*:height</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*</NAME>\n                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n              <section>\n                <rule>\n                  <match>\n                    <AND>\n                      <NAME>.*</NAME>\n                      <XML_NAMESPACE>.*</XML_NAMESPACE>\n                    </AND>\n                  </match>\n                  <order>BY_NAME</order>\n                </rule>\n              </section>\n            </rules>\n          </arrangement>\n        </codeStyleSettings>\n        <codeStyleSettings language=\"kotlin\">\n          <option name=\"CODE_STYLE_DEFAULTS\" value=\"KOTLIN_OFFICIAL\" />\n          <option name=\"KEEP_FIRST_COLUMN_COMMENT\" value=\"false\" />\n          <option name=\"KEEP_BLANK_LINES_IN_DECLARATIONS\" value=\"1\" />\n          <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n          <option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"1\" />\n          <option name=\"ALIGN_MULTILINE_PARAMETERS_IN_CALLS\" value=\"true\" />\n          <option name=\"ALIGN_MULTILINE_EXTENDS_LIST\" value=\"true\" />\n        </codeStyleSettings>\n      </value>\n    </option>\n    <option name=\"USE_PER_PROJECT_SETTINGS\" value=\"true\" />\n  </component>\n</project>\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# 5.2.1\n\nFix some issues in KSP2 when multiple processing rounds occur (https://github.com/airbnb/epoxy/pull/1396)\n\n# 5.2.0\n\nMigrate to KSP 2 (#1393)\n\n# 5.1.4\nChange the way the Compose interop works to avoid Android 12 bug (#1370)\n\n# 5.1.3\nUpdate to kotlin 1.8.21\nFix click listener kapt bug (#1327)\nResolve unchecked call warning for WrappedEpoxyModelClickListener (#1337)\nFix refresh KDoc (#1334)\nepoxy-kspsample : use ksp block to specify arguments (#1347)\n\n# 5.1.2\n\nUpdates kotlin, ksp, and the xprocessing library.\n\nNotably, the androidx.room:room-compiler-processing library (aka xprocessing) has been updated to 2.6.0-alpha01. This version is incompatible with previous versions due to a breaking API change. All annotation processors using this library must be on the same version. Other annotation processors such as Epoxy and Paris also use xprocessing and if you use them you need to use a version of them that also uses xprocessing 2.6.0-alpha01\n\n# 5.1.1\nRemove incorrect ksp symbol validation in processing of @EpoxyModelClass\n\n# 5.1.0\nUpdates Kotlin to 1.7.20 and KSP to 1.7.20-1.0.7, as well as the room compiler processing (xprocessing) library to 2.5.0-beta01.\n\nAlso deletes the epoxy-paging artifact in favor of the newer epoxy-paging3\n\n# 5.0.0\nThis adds support for Kotlin Symbol Processing, while maintaining backwards compatibility with java annotation processing via the xprocessing library from Room.\n\nThis includes a major version bump to 5.0.0 because there may be slight behavior differences with KSP, especially for generic types in generated code. For example, if you previously had an epoxy attribute in java source code with a raw type it may now appear in the generated code with a wildcard type, which may require tweaking the type that is passed to the model.\n\nAdditionally, some type checking was improved, for example more accurate validation of proper equals and hashcode implementations.\n\nTo use Epoxy with KSP, simply apply it with the ksp gradle plugin instead of kapt (https://github.com/google/ksp/blob/main/docs/quickstart.md). See the new epoxy-kspsample module for an example.\n\nNote that unfortunately the databinding processor does NOT support KSP, simply because Android databinding itself uses KAPT and KSP cannot currently depend on KAPT sources. The code changes are in place to enable KSP with databinding once the databinding plugin from Android supports KSP (although this is unlikely) - alternatively it may be possible to configure the KSP plugin to run after KAPT and depend on its outputs (you're on your own if you want to try that).\n\nAlso, parallel processing support was removed because it is not compatible with KSP.\n\nWe have also added easy interop with Jetpack Compose via functions in the `epoxy-composeinterop` artifact.\nSee the epoxy-composesample module for example usage.\n\n# 4.6.4 (September 23, 2021)\n- Clean up dependency for the experimental epoxy module\n\n# 4.6.3 (September 11, 2021)\n- Add EpoxyModel#preBind hook(#1225)\n- Add unbind extension to ItemViewBindingEpoxyHolder (#1223)\n- Add missing loadStateFlow to PagingDataEpoxyController (#1209)\n\n# 4.6.2 (June 11, 2021)\nFix Drag n Drop not working in 4.6.1 (#1195)\n\n# 4.6.1 (May 13, 2021)\nAdds \"epoxyDisableDslMarker\" annotation processor flag which you can use to delay migration to the model building scope DLSMarker introduced in 4.6.0 if it is a large breaking change for your project.\n\nNote that this only applies to your project modules that you apply it to, and does not apply to the handful of models that ship with the Epoxy library (like the Carousel or `group` builder).\n\nFor example:\n```groovy\nproject.android.buildTypes.all { buildType ->\n    buildType.javaCompileOptions.annotationProcessorOptions.arguments =\n            [\n                    epoxyDisableDslMarker     : \"true\",\n            ]\n}\n```\n\n# 4.6.0 (May 12, 2021)\n- View Binder Support (#1175) Bind epoxy models to views outside of a RecyclerView.\n\n### Potentially Breaking\n- Use kotlin dsl marker for model building receivers (#1180)\n\nThis change uses Kotlin's DSL marker annotation to enforce proper usage of model building extension\nfunctions. You may now need to change some references in your model building code to explicitly reference properties with `this`.\n\n# 4.5.0 (April 13, 2021)\n- Fix generated code consistency in builder interfaces (#1166)\n- Provided support to invalidate `modelCache` in `PagingDataEpoxyController` (#1161)\n- Explicitly add public modifier (#1162)\n- Unwrap context to find parent activity in order to share viewpool when using Hilt (#1157)\n\n# 4.4.4 (Mar 24, 2021)\n- Provide support for snapshot() function in PagingDataEpoxyController (#1144)\n\n# 4.4.3 (Mar 17, 2021)\n- Fixed interface model related regression introduced in the previous release.\n\n# 4.4.2 (Mar 1, 2021)\n- Updated package name of the model class generated for an interface\n\n# 4.4.1 (Feb 22, 2021)\n- Support for Paging3 (#1126) (Thanks to @osipxd and @anhanh11001!)\n- Update KotlinPoet to 1.7.2 (#1117)\n\n# 4.4.0 (Feb 18, 2021)\nBad release, don't use\n\n# 4.3.1 (Dec 2, 2020)\n- Fix ANR and view pool resolution in nested group (#1101)\n\n# 4.3.0 (Dec 1, 2020)\n- ModelGroupHolder get recycle pool from parent (#1097)\n- Add support for `EpoxyModelGroup` in the `EpoxyVisibilityTracker` (#1091)\n- Convert EpoxyVisibilityTracker code to Kotlin (#1090)\n\n## Breaking Changes\nNote that due to the conversion of EpoxyVisibilityTracker to kotlin you now need to access `EpoxyVisibilityTracker.partialImpressionThresholdPercentage` as a property\n`epoxyVisibilityTracker.setPartialImpressionThresholdPercentage(value)` -> `epoxyVisibilityTracker.partialImpressionThresholdPercentage = value`\n\nAlso, the ModelGroupHolder improvement required the `ModelGroupHolder#createNewHolder` function to change its signature to accept a `ViewParent` parameter.\n\nIf you override `createNewHolder()` anywhere you will need to change it to `createNewHolder(@NonNull ViewParent parent)`\n\n# 4.2.0 (Nov 11, 2020)\n- Add notify model changed method (#1063)\n- Update to Kotlin 1.4.20-RC and remove dependency on kotlin-android-extensions\n\n# 4.1.0 (Sept 17, 2020)\n- Fix some synchronization issues with the parallel Epoxy processing option\n- Add view visibility checks to EpoxyVisibilityItem and decouple RecyclerView #1052\n\n# 4.0.0 (Sept 5, 2020)\n\n## New\n- Incremental annotation processing for faster builds\n- Support for Android Jetpack Paging v3 library in new `epoxy-paging3` artifact\n- Model group building with Kotlin DSL (#1012)\n- A new annotation processor argument `logEpoxyTimings` can be set to get a detailed breakdown of how long the processors took and where they spent their time (off by default)\n- Another new argument `enableParallelEpoxyProcessing` can be set to true to have the annotation processor process annotations and generate files in parallel (via coroutines).\n\nYou can enable these processor options in your build.gradle file like so:\n```\nproject.android.buildTypes.all { buildType ->\n  buildType.javaCompileOptions.annotationProcessorOptions.arguments =\n      [\n          logEpoxyTimings  : \"true\",\n          enableParallelEpoxyProcessing     : \"true\"\n      ]\n}\n```\n\nParallel processing can greatly speed up processing time (moreso than the incremental support), but given the hairy nature of parallel processing it is still incubating.\nPlease report any issues or crashes that you notice.\n(We are currently using parallel mode in our large project at Airbnb with no problems.)\n\n- Add options to skip generation of functions for getters, reset, and method overloads to reduce generated code\n    - New annotation processor options are:\n        - epoxyDisableGenerateOverloads\n        - epoxyDisableGenerateGetters\n        - epoxyDisableGenerateReset\n\n\n## Fixes\n- Synchronize ListUpdateCallback and PagedListModelCache functions (#987)\n- Avoid generating bitset checks in models when not needed (reduces code size)\n- Fix minor memory leak\n\n## Breaking\n\n- Annotations that previously targeted package elements now target types (classes or interfaces).\n  This includes: `EpoxyDataBindingPattern`, `EpoxyDataBindingLayouts`, `PackageModelViewConfig`, `PackageEpoxyConfig`\n  This was necessary to work around an incremental annotation processor issue where annotation on package-info elements are not properly recompiled\n\n- In order to enable incremental annotation processing a change had to be made in how the processor of\n  `@AutoModel` annotations work. If you use `@AutoModel` in an EpoxyController the annotated Model types\n  must be either declared in a different module from the EpoxyController, or in the same module in the same java package.\n\n  Also make sure you have kapt error types enabled.\n\n  However, generally `@AutoModel` is considered legacy and is not recommended. It is a relic of Java Epoxy usage\n  and instead the current best practice is to use Kotlin with the Kotlin model extension functions to build models.\n\n- Removed support for generating Epoxy models from Litho components\n\n# 4.0.0-beta6 (July 15, 2020)\n- PackageModelViewConfig can now be applied to classes and interfaces in addition to package-info.java\n\n# 4.0.0-beta5 (July 9, 2020)\nFixes:\n- An occasional processor crash when the option to log timings is enabled\n- Incremental annotation processing of databinding models would fail to generate models (#1014)\n\nBreaking!\n- The annotation that support databinding, `EpoxyDataBindingLayouts` and `EpoxyDataBindingPattern`,\nmust now be placed on a class or interface instead of in a `package-info.java` file. The interface\nor class must be in Java, Kotlin is not supported. This is necessary to support incremental processing.\n\nExample usage:\n```java\npackage com.example.app;\n\nimport com.airbnb.epoxy.EpoxyDataBindingLayouts;\nimport com.airbnb.epoxy.EpoxyDataBindingPattern;\n\n@EpoxyDataBindingPattern(rClass = R.class, layoutPrefix = \"my_view_prefix\")\n@EpoxyDataBindingLayouts({R.layout.my_model_layout})\ninterface EpoxyDataBindingConfig {} \n```\n\n# 4.0.0-beta4 (June 1, 2020)\nFixes:\n- Synchronize ListUpdateCallback and PagedListModelCache functions (#987)\n- 4.0.0.beta1 generating duplicate method layout(int) #988\n\n# 4.0.0-beta3 (May 27, 2020)\n- Sort functions in generated kotlin extension function files deterministically to prevent generated sources from changing\n- Avoid generating bitset checks in models when not needed\n- Add options to skip generation of functions for getters, reset, and method overloads to reduce generated code\n\nNew annotation processor options are:\n- epoxyDisableGenerateOverloads\n- epoxyDisableGenerateGetters\n- epoxyDisableGenerateReset\n\nThese can also be controlled (and overridden) on a per package level with the `PackageModelViewConfig` package annotation.\n\n# 4.0.0-beta1 (May 22, 2020)\n- Support for incremental annotation processing as an Aggregating processor (#972)\n- Removed Litho support\n- A new annotation processor argument `logEpoxyTimings` can be set to get a detailed breakdown of how long the processors took and where they spent their time (off by default)\n- Another new argument `enableParallelEpoxyProcessing` can be set to true to have the annotation processor process annotations and generate files in parallel (via coroutines).\n\nYou can enable these processor options in your build.gradle file like so:\n```\nproject.android.buildTypes.all { buildType ->\n  buildType.javaCompileOptions.annotationProcessorOptions.arguments =\n      [\n          logEpoxyTimings  : \"true\",\n          enableParallelEpoxyProcessing     : \"true\"\n      ]\n}\n```\n\nParallel processing can greatly speed up processing time (moreso than the incremental support), but given the nature of parallel processing it is still incubating.\nPlease report any issues or crashes that you notice.\n(We are currently using parallel mode in our large project at Airbnb with no problems.)\n\n## Breaking\nIn order to enable incremental annotation processing a change had to be made in how the processor of\n`@AutoModel` annotations work. If you use `@AutoModel` in an EpoxyController the annotated Model types\nmust be either declared in a different module from the EpoxyController, or in the same module in the same java package.\n\nAlso make sure you have kapt error types enabled.\n\nHowever, generally `@AutoModel` is considered legacy and is not recommended. It is a relic of Java Epoxy usage\nand instead the current best practice is to use Kotlin with the Kotlin model extension functions to build models.\n \n# 3.11.0 (May 20, 2020)\n- Introduce partial impression visibility states (#973)\n- Fix sticky header crash (#976)\n\n# 3.10.0 (May 15, 2020)\n- Carousel building with Kotlin DSL (#967)\n- Android ViewBinding: added an example in the sample project. (#939)\n- Fix setter with default value lookup in kotlin 1.4 (#966)\n- Change \"result\" property name in generated model (#965)\n- Add support for Sticky Headers (#842)\n- Use measured width/height if it exists in Carousel. (#915)\n- Add a getter to EpoxyViewHolder.getHolder(). (#952) (#953)\n- Fix visibility tracking during RecyclerView animations (#962)\n- Fix leak in ActivityRecyclerPool ((#906)\n- Rename ResultCallack to ResultCallback in AsyncEpoxyDiffer (#899)\n- Fix incorrect license attributes in POM file (#898)\n\n# 3.9.0 (Dec 17, 2019)\n- Fix reading EpoxyDataBindingPattern enableDoNotHash (#837) \n- Make EpoxyRecyclerView.setItemSpacingPx() open (#829)\n- Use same version for Mockito Core and Inline (#860)\n- Minor documentation and variable name updates. (#870)\n- Move epoxy-modelfactory tests to their own module (#834) \n- Remove executable bit from non-executable files (#864)\n- Various repo clean ups and version bumps\n\n# 3.8.0 (Sept 16, 2019)\n- Add support for Kotlin delegation via annotated interface properties #812\n- Fix checked change crash and improve debug errors #806\n- Remove extra space in Kotlin extensions #777\n- Update project to AGP 3.5, Kotlin 1.3.50, Gradle 5.6\n\n# 3.7.0 (July 1, 2019)\n- **New** Add a method to request visibility check externally (https://github.com/airbnb/epoxy/pull/775)\n\n# 3.6.0 (June 18, 2019)\n- **New** Preloader system with glide extensions https://github.com/airbnb/epoxy/pull/766\n- **Fixed** model click listener crashing on nested model https://github.com/airbnb/epoxy/pull/767\n\n# 3.5.1 (May 21, 2019)\n- Bumped Kotlin to 1.3.31\n\n# 3.5.0 (May 8, 2019)\n- **New** Converted EpoxyRecyclerView to Kotlin (you may need to update your usage for this). Also added built in support for `EpoxyRecyclerView#withModels` for easy inline model building with Kotlin.\n- **Fixed** Crashes in visibility tracking\n\n# 3.4.2 (April 18, 2019)\n- **Fixed** Kotlin default param handling had issues with overloaded functions\n\n# 3.4.1 (April 16, 2019)\n- **New** Support kotlin default parameters in @ModelView classes (https://github.com/airbnb/epoxy/pull/722)\n\n# 3.4.0 (April 10, 2019)\n- **New** Generate OnModelCheckedChangeListener override for props of type `CompoundButton.OnCheckedChangeListener` (https://github.com/airbnb/epoxy/pull/725)\n- **New** Extract ID generation methods to new public IdUtils class (https://github.com/airbnb/epoxy/pull/724)\n- **Changed** Reset controller state on failed model build (https://github.com/airbnb/epoxy/pull/720)\n- **Changed** Disabled the auto-detach behavior on Carousels by default (https://github.com/airbnb/epoxy/pull/688)\n\n# 3.3.0 (Feb 5, 2019)\n- **Fixed** Two issues related to the recent EpoxyModelGroup changes (https://github.com/airbnb/epoxy/pull/676)\n\n# 3.2.0 (Jan 21, 2019)\n- **New** Enable recycling of views within EpoxyModelGroup (https://github.com/airbnb/epoxy/pull/657)\n- **New** Add support to tracking visibility in nested RecyclerViews (https://github.com/airbnb/epoxy/pull/633)\n- **New** Add method to clear cache in paging controller (https://github.com/airbnb/epoxy/pull/586)\n- **Fix** Crashes from synchronization in PagedListEpoxyController (https://github.com/airbnb/epoxy/pull/656)\n- **Fix** Get onSwipeProgressChanged callbacks on return to original item position (https://github.com/airbnb/epoxy/pull/654)\n\n# 3.1.0 (Dec 4, 2018)\n- **Fix** Memory leak in debug mode is removed (https://github.com/airbnb/epoxy/pull/613)\n- **Fix** For visibility callbacks, wrong visibility when the view becomes not visible (https://github.com/airbnb/epoxy/pull/619)\n\n# 3.0.0 (Nov 13, 2018)\n\n- **Breaking** Migrated to androidx packages (Big thanks to jeffreydelooff!)\n\n- **Breaking** The `Carousel.Padding` class changed the ordering of its parameters to match Android's ordering of \"left, top, right, bottom\". (https://github.com/airbnb/epoxy/pull/536 thanks to martinbonnin)\n    \n   This change won't break compilation, so you _must_ manually change your parameter ordering, otherwise you will get unexpected padding results.\n\n# 2.19.0 (Oct 18, 2018)\nThis release adds built in support for monitoring visibility of views in the RecyclerView. (https://github.com/airbnb/epoxy/pull/560)\n\nUsage instructions and details are in the wiki - https://github.com/airbnb/epoxy/wiki/Visibility-Events\n\nHuge thanks to Emmanuel Boudrant for contributing this!\n\n# 2.18.0 (Sep 26, 2018)\n- **New** A new `PagedListEpoxyController` to improve integration with the Android Paging architecture component (#533 Thanks to Yigit!)\n          With this change the old `PagingEpoxyController` has been deprecated, and [the wiki](https://github.com/airbnb/epoxy/wiki/Paging-Support) is updated.\n\n- **New** Add databinding option to not auto apply DoNotHash (#539)\n- **Fixed** Fix AsyncEpoxyController constructor to correctly use boolean setting (#537)\n- **Fixed** `app_name` is removed from module manifests (#543 Thanks @kettsun0123!)\n\n\n# 2.17.0 (Sep 6, 2018)\n- **New** Add support for setting the Padding via resource or directly in dp (https://github.com/airbnb/epoxy/pull/528 Thanks to pwillmann!)\n- **Fixed** Strip kotlin metadata annotation from generated classes (https://github.com/airbnb/epoxy/pull/523)\n- **Fixed** Reflect the annotations declared in constructor params (https://github.com/airbnb/epoxy/pull/519 Thanks to Shaishav Gandhi!)\n\n# 2.16.4 (Aug 29, 2018)\n- **New** `EpoxyAsyncUtil` and `AsyncEpoxyController` make it easier to use Epoxy's async behavior out of the box\n- **New** Epoxy's background diffing posts messages back to the main thread asynchronously so they are not blocked by waiting for vsync\n\n# 2.16.3 (Aug 24, 2018)\n- **New** Add `AsyncEpoxyController` for easy access to async support. Change background diffing to post asynchronously to the main thread (https://github.com/airbnb/epoxy/pull/509)\n\n# 2.16.2 (Aug 23, 2018)\n- **Fix** Kotlin lambdas can be used in model constructors (https://github.com/airbnb/epoxy/pull/501)\n- **New** Added function to check whether a model build is pending (https://github.com/airbnb/epoxy/pull/506)\n\n# 2.16.1 (Aug 15, 2018)\n- **Fix** Update EpoxyController async model building so threading works with tests (https://github.com/airbnb/epoxy/pull/504)\n\n# 2.16.0 (Aug 7, 2018)\n- **New** EpoxyController now supports asynchronous model building and diffing by allowing you to provide a custom Handler to run these tasks. See the [wiki](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#asynchronous-support) for more details.\n\n- **New** The `EpoxyController#addModelBuildListener` method was added to support listening for when model changes are dispatched to the recyclerview.\n\n# 2.15.0 (July 29, 2018)\n- **New** Added kotlin sample code for building models. Updated wiki with info (https://github.com/airbnb/epoxy/wiki/Kotlin-Model-Examples)\n\n- **Fix**  Generated kotlin extension functions now work with Models with type variables (https://github.com/airbnb/epoxy/pull/478)\n- **Fix**  Backup is not enabled in manifest now (https://github.com/airbnb/epoxy/pull/481)\n- **Fix**  Click listener setter on generated model has correct nullability annotation (https://github.com/airbnb/epoxy/pull/458)\n- **Fix**  Avoid kotlin crash using toString on lambdas (https://github.com/airbnb/epoxy/pull/482)\n- **Fix**  If EpoxyModelGroup has annotations the generated class now calls super methods correctly.  (https://github.com/airbnb/epoxy/pull/483)\n\n# 2.14.0 (June 27, 2018)\n- **New** Experimental support for creating Epoxy models from arbitrary data formats (#450)\n\n# 2.13.0 (June 19, 2018)\n- **Fix** Reduce memory usage in model groups and differ (#433)\n- **Fix** Support for wildcards in private epoxy attributes (#451)\n- **Fix** Generated Kotlin Extensions Don't Adhere to Constructor Nullability (#449)\n- **Fix** Infinite loop in annotation processor (#447)\n\n# 2.12.0 (April 18, 2018)\n\n- **Breaking** Several updates to the Paging Library integration were made (https://github.com/airbnb/epoxy/pull/421)\n    - The `PagingEpoxyController` class had the methods `setNumPagesToLoad` and `setPageSizeHint` removed\n    - Page hints are now taken from the `Config` object off of the PagedList. See the `setConfig` javadoc for information on how config values are used: https://github.com/airbnb/epoxy/blob/master/epoxy-paging/src/main/java/com/airbnb/epoxy/paging/PagingEpoxyController.java#L220\n    - Several tweaks were made to how the page size and prefetch distance affect model rebuilding. Take some time to make sure your config values make sense and produce good results for your use case\n    - A crash on empty list was fixed (https://github.com/airbnb/epoxy/issues/420)\n\n- **New** The [Paris](https://github.com/airbnb/paris) library is now officially supported to allow dynamically styling RecyclerView items though Epoxy models. See [the wiki](https://github.com/airbnb/epoxy/wiki/Paris-Integration-(Dynamic-Styling)) for more info.\n\n\n# 2.11.0 (April 7, 2018)\n\n- **Fix** Make databinding work with Android Studio 3.1 (https://github.com/airbnb/epoxy/pull/418)\n- Make `EpoxyController#isBuildingModels` public (https://github.com/airbnb/epoxy/pull/406\n\n\n# 2.10.0 (February 25, 2018)\n\n- **Improved** Allow the `Model_` class suffix for models generated via `@ModelView` to be customized (https://github.com/airbnb/epoxy/pull/402 Big thanks to geralt-encore!)\n\n# 2.9.0 (January 29, 2018)\n- **Improved** Global defaults for EpoxyController settings. Set duplicate filtering and exception handlers for all your controllers. (https://github.com/airbnb/epoxy/pull/394)\n- **Improved** Add `@NonNull` annotations in EpoxyModel for better Kotlin interop\n\n- **Fixed** Model click listeners now rebind correctly on partial model diffs (https://github.com/airbnb/epoxy/pull/393)\n- **Fixed** Update Android Paging library to fix placeholder support (Thanks @wkranich! https://github.com/airbnb/epoxy/pull/360)\n- **Fixed** Improve error message for inaccessible private fields (https://github.com/airbnb/epoxy/pull/388)\n\n# 2.8.0 (December 22, 2017)\n\n- **New** Use `@ModelProp` directly on fields to avoid creating a setter (https://github.com/airbnb/epoxy/pull/343)\n- **New** Set EpoxyRecyclerView item spacing via xml attribute (https://github.com/airbnb/epoxy/pull/364)\n- **New** More flexibility over setting Carousel padding values (https://github.com/airbnb/epoxy/pull/369)\n- **New** Allow custom EpoxyModelGroup root view (https://github.com/airbnb/epoxy/pull/370)\n\n- **Fixed** Public visibility settings of the Carousel snap helper settings (https://github.com/airbnb/epoxy/pull/356)\n- **Fixed** Add more nullability annotations to better support Kotlin\n- **Fixed** Saving view state now works better (https://github.com/airbnb/epoxy/pull/367)\n\n# 2.7.3 (November 21, 2017)\n\n- **Fixed** When a model changed and a partial update was bound to an existing view the wrong values could be set for prop groups (https://github.com/airbnb/epoxy/pull/347)\n\n# 2.7.2 (October 28, 2017)\n\n- **Fixed** Using `EpoxyDataBindingPattern` could result in the wrong package being used for the BR class in generated models.\n\n# 2.7.1 (October 24, 2017)\nSeveral fixes:\n\n- https://github.com/airbnb/epoxy/pull/332\n- https://github.com/airbnb/epoxy/pull/329\n- https://github.com/airbnb/epoxy/pull/330\n- https://github.com/airbnb/epoxy/pull/331\n\n# 2.7.0 (October 17, 2017)\n\n* **New** If a `@ModelView` generated model has a custom base class the generated model will now inherit constructors from the base class (https://github.com/airbnb/epoxy/pull/315)\n* **New** Use the `EpoxyDataBindingPattern` annotation to specify a naming pattern for databinding layouts. This removes the need to declare every databinding layout explicitly ([Wiki](https://github.com/airbnb/epoxy/wiki/Data-Binding-Support#automatic-based-on-naming-pattern) - https://github.com/airbnb/epoxy/pull/319)\n* **New** If a view with `@ModelView` implements an interface then the generated model will implement a similar interface, enabling polymorphism with models. [Wiki](https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations#view-interfaces)\n\n* **Improvement** `PagingEpoxyController` now has getters to access the underlying data lists (Thanks to @pcqpcq - https://github.com/airbnb/epoxy/pull/317)\n* **Improvement** `EpoxyModelGroup` now supports partial rebinds (https://github.com/airbnb/epoxy/pull/316)\n\n# 2.6.0 (October 10, 2017)\n* **Improvement** If a `OnModelClickListener` is used it will not be called if a view is clicked while it is being removed or otherwise has no position (https://github.com/airbnb/epoxy/issues/293 - Thanks @niccorder!)\n\n* **New** `EpoxyRecyclerView` and `Carousel` provide out of the box integration with Epoxy along with other enhancements over regular RecyclerView (https://github.com/airbnb/epoxy/wiki/EpoxyRecyclerView)\n* **New** `EpoxyPagingController` provides integration with the Android Paging architecture component as well as normal, large lists of items (https://github.com/airbnb/epoxy/wiki/Large-Data-Sets)\n\n#### Kotlin\n* **Improvement** Disable kotlin extension function generation with the annotation processor flag `disableEpoxyKotlinExtensionGeneration` (https://github.com/airbnb/epoxy/pull/309)\n* **Fix** If a model has a non empty constructor the generated extension function will now use it.\n\n\n# 2.5.1 (October 2, 2017)\n* **Fixed** The wrong import was being generated for models using a view holder in 2.5.0 (https://github.com/airbnb/epoxy/pull/294)\n* **Fixed** Fix generated code failing to compile if a subclass of View.OnClickListener is used as an attribute (https://github.com/airbnb/epoxy/pull/296)\n\n\n# 2.5.0 (September 14, 2017)\n* **New Feature** Epoxy now generates a Kotlin DSL to use when building models in your EpoxyController! See [the wiki](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#usage-with-kotlin) for details\n* **New Feature** You can use the `autoLayout` parameter in `@ModelView` instead of needing to create a layout resource for `defaultLayout`. Epoxy will then create your view programmatically (https://github.com/airbnb/epoxy/pull/282).\n\n**Breaking**\n* The `onSwipeProgressChanged` callback in `EpoxyTouchHelper` had a `Canvas` parameter added (https://github.com/airbnb/epoxy/pull/280). You will need to update any of your usages to add this. Sorry for the inconvenience; this will hopefully help you add better swipe animations.\n\n\n# 2.4.0 (September 4, 2017)\n* **Improvement** If you are setting options on a @ModelProp and have no other annotation parameters you can now omit the explicit `options = ` param name (https://github.com/airbnb/epoxy/pull/268)\n* **Improvement** If you are using `@TextProp` you can now specify a default string via a string resource (https://github.com/airbnb/epoxy/pull/269)\n\n* **Fixed** EpoxyModelGroup was not binding model click listeners correctly (https://github.com/airbnb/epoxy/pull/267)\n* **Fixed** A model created with @ModelView could fail to compile if it had nullable prop overloads  (https://github.com/airbnb/epoxy/pull/274)\n\n#### Potentially Breaking Fix\nA model created with @ModelView with a click listener had the wrong setter name for the model click listener overload (https://github.com/airbnb/epoxy/pull/275)\n\nIf you were setting this you will need to update the setter name. If you were setting the click listener to null you may now have to cast it.\n\n\n# 2.3.0 (August 16, 2017)\n* **New** An `AfterPropsSet` annotation for use in `@ModelView` classes. This allows initialization work to be done after all properties are bound from the model. (https://github.com/airbnb/epoxy/pull/242)\n* **New** Annotations `TextProp` and `CallbackProp`  as convenient replacements for `ModelProp`. (https://github.com/airbnb/epoxy/pull/260)\n* **New** Easy support for dragging and swiping via the `EpoxyTouchHelper` class. https://github.com/airbnb/epoxy/wiki/Touch-Support\n* **Change** Added the method `getRootView` to the view holder class in `EpoxyModelGroup` and made the bind methods on `EpoxyModelGroup` non final. This allows access to the root view of the group.\n* **Change** Generated models will now inherit class annotations from the base class (https://github.com/airbnb/epoxy/pull/255 Thanks geralt-encore!)\n\n# 2.2.0 (June 19, 2017)\n* **Main Feature** Models can now be completely generated from a custom view via annotations on the view. This should completely remove the overhead of creating a model manually in many cases! For more info, see [the wiki](https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations)\n\n* **New** Lowered the minimum SDK from 16 to 14.\n* **New** Models that have a `View.OnLongClickListener` as an EpoxyAttribute will now have an overloaded setter on the generated model that allows you to set a long click listener that will return the model, view, and adapter position. This is very similar to the `View.OnClickListener` support added in 2.0.0, but for long click listeners. **Upgrade Note** If you were setting a long click listener value to null anywhere you will need to now cast that to `View.OnLongClickListener` because of the new overloaded method.\n* **New** `id` overload on EpoxyModel to define a model id with multiple strings\n* **New** Option in `EpoxyAttribute` to not include the attribute in the generated `toString` method (Thanks to @geralt-encore!)\n* **New** @AutoModel models are now inherited from usages in super classes (Thanks to @geralt-encore!)\n* **Fixed** Generated getters could recursively call themselves (Thanks to @geralt-encore!)\n\n# 2.1.0 (May 9, 2017)\n\n* **New**: Support for Android Data Binding! Epoxy will now generate an EpoxyModel directly from a Data Binding xml layout, and handle all data binding details automatically. Thanks to @geralt-encore for helping with this! See more details in [the wiki](https://github.com/airbnb/epoxy/wiki/Data-Binding-Support).\n* **New**: Support for Litho. Epoxy will now generate an EpoxyModel for Litho Layout Specs. See more details in [the wiki](https://github.com/airbnb/epoxy/wiki/Litho-Support).\n* **New**: Support for implicitly adding AutoModels to an EpoxyController, this let's you drop the extra `.addTo(this)` line. More details and instructions [here](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#implicit-adding)\n\n# 2.0.0 (March 25, 2017)\n\n* **New**: The `EpoxyController` class helps you manage even models better. This should be used instead of the original `EpoxyAdapter` in most places. Read more about `EpoxyController` in [the wiki](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller).\n* **Change**: In the new EpoxyController, the diffing algorithm uses both `equals` and `hashCode` on each model to check for changes. This is a change from the EpoxyAdapter where only `hashCode` was used. Generated models have both hashCode and equals implemented properly already, but if you have any custom hashCode implementations in your models make sure you have equals implemented as well.\n* **New**: Models that have a `View.OnClickListener` as an EpoxyAttribute will now have an overloaded setter on the generated model that allows you to set a click listener that will return the model, view, and adapter position. **Upgrade Note** If you were setting a click listener value to null anywhere you will need to now cast that to `View.OnClickListener` because of the new overloaded method.\n* **New**: Attach an onBind/onUnbind listener directly to a model instead of overriding the onModelBound method. Generated models will have methods created to set this listener and handle the callback for you.\n* **New**: Support for creating models in Kotlin (Thanks to @geralt-encore! https://github.com/airbnb/epoxy/pull/144)\n* **New**: `EpoxyModelWithView` supports creating a View programmatically instead of inflating from XML.\n* **New**: `EpoxyModelGroup` supports grouping models together in arbitrary formations.\n* **New**: Instead of setting attribute options like `@EpoxyAttribute(hash = false)` you should now do `@EpoxyAttribute(DoNotHash)`. You can also set other options like that.\n* **New**: Annotation processor options can now be set via gradle instead of with `PackageEpoxyConfig`\n* **New**: In an EpoxyController, if a model with the same id changes state Epoxy will include its previous state as a payload in the change notification. The new model will have its `bind(view, previouslyBoundModel)` method called so it can compare what changed since the previous model, and so it can update the view with only the data that changed.\n\n# 1.7.5 (Feb 21, 2017)\n\n* **New**: Models inherit layouts specified in superclass `@EpoxyModelClass` annotations [#119](https://github.com/airbnb/epoxy/pull/119)\n* **New**: Support module configuration options [#124](https://github.com/airbnb/epoxy/pull/124)\n\n# 1.6.2 (Feb 8, 2017)\n\n* New: Support layout resource annotations in library projects (https://github.com/airbnb/epoxy/pull/116)\n\n# 1.6.1 (Feb 6, 2017)\n\n* Allow the default layout resource to be specified in the EpoxyModelClass class annotation [(#109)](https://github.com/airbnb/epoxy/pull/109) [(#111)](https://github.com/airbnb/epoxy/pull/111)\n* Allow the `createNewHolder` method to be omitted and generated automatically [(#105)](https://github.com/airbnb/epoxy/pull/105)\n* Generate a subclass for abstract model classes if the EpoxyModelClass annotation is present [(#105)](https://github.com/airbnb/epoxy/pull/105)\n* Allow strings as model ids [(#107)](https://github.com/airbnb/epoxy/pull/107)\n* Add instructions to readme for avoiding memory leaks [(#106)](https://github.com/airbnb/epoxy/pull/106)\n* Add model callbacks for view attached/detached from window, and onFailedToRecycleView [(#104)](https://github.com/airbnb/epoxy/pull/104)\n* Improve documentation on model unbind behavior [(#103)](https://github.com/airbnb/epoxy/pull/103)\n* Fix generated methods from super classes that have var args [(#100)](https://github.com/airbnb/epoxy/pull/100)\n* Remove apt dependency [(#95)](https://github.com/airbnb/epoxy/pull/95)\n* Add `removeAllModels` method to EpoxyAdapter [(#94)](https://github.com/airbnb/epoxy/pull/94)\n* Use actual param names when generating methods from super classes [(#85)](https://github.com/airbnb/epoxy/pull/85)\n\n# 1.5.0 (11/21/2016)\n\n* Fixes models being used in separate modules\n* Generates a `reset()` method on each model to reset annotated fields to their defaults.\n* Changes `@EpoxyAttribute(hash = false)` to still differentiate between null and non null values in the hashcode implementation\n* Adds a `notifyModelChanged` method to EpoxyAdapter that allows a payload to be specified\n* Generates a `toString()` method on all generated model classes that includes the values of all annotated fields.\n\n# 1.4.0 (10/13/2016)\n\n* Optimizations to the diffing algorithm\n* Setters on generated classes are not created if an @EpoxyAttribute field is marked as `final`\n* Adds @EpoxyModelClass annotation to force a model to have a generated class, even if it doesn't have any @EpoxyAttribute fields\n* Fix to not generate methods for package private @EpoxyAttribute fields that are in a different package from the generated class\n* Have generated classes duplicate any super methods that have the model as the return type to help with chaining\n\n# 1.3.0 (09/15/2016)\n\n* Add support for using the view holder pattern with models. See the readme for more information.\n* Throw an exception if `EpoxyAdapter#notifyDataSetChanged()` is called when diffing is enabled. It doesn't make sense to allow this alongside diffing, and calling this is most likely to be an accidental mixup with `notifyModelsChanged()`.\n* Some performance improvements with the diffing algorithm.\n\n# 1.2.0 (09/07/2016)\n\n* Change signature of `EpoxyAdapter#onModelBound` to include the model position\n* Fix EpoxyModel hashcode to include the layout specified by `getDefaultLayout`\n* Enforce that the id of an `EpoxyModel` cannot change once it has been added to the adapter\n* Add optional hash parameter to the `EpoxyAttribute` annotation to exclude a field from being included in the generated hashcode method.\n\n# 1.1.0 (08/24/2016)\n\n* Initial release\n"
  },
  {
    "path": "CONTRIBUTING.MD",
    "content": "# Epoxy is an Open Source Project\n\nPull requests are welcome! We'd love help improving this library.\n\nWe have a code style setting for the project (checkstyle for Java, ktlint for Kotlin). Please run `Reformat Code` in Android Studio (or Intellij) on changed files before pushing them. Alternatively for Kotlin you can use [ktlint](https://ktlint.github.io/) tasks: check Kotlin code formatting with`./gradlew ktlint` and reformat all Kotlin code with `./gradlew ktlintformat`.\n\nAlso, run `./gradlew check` locally to make sure that style checks and tests pass.\n\nIf you update the model annotation processor you may find the `UpdateProcessorTestResults.kt` script very useful for updating the existing tests with your changes. (run it with kscript)\n - Run ./gradlew testDebug first to get test failures, then run `kscript UpdateProcessorTestResources.kt` to updates sources\n - You may have to repeat this cycle several times for all tests to be updated."
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2018 Airbnb, Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "[![Build Status](https://travis-ci.com/airbnb/epoxy.svg?branch=master)](https://travis-ci.com/github/airbnb/epoxy)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.airbnb.android/epoxy/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.airbnb.android/epoxy)\n[![GitHub license](https://img.shields.io/github/license/airbnb/epoxy)](https://github.com/airbnb/epoxy/blob/master/LICENSE)\n![GitHub contributors](https://img.shields.io/github/contributors/airbnb/epoxy)\n\n# Epoxy\n\nEpoxy is an Android library for building complex screens in a RecyclerView. Models are automatically generated from custom views or databinding layouts via annotation processing. These models are then used in an EpoxyController to declare what items to show in the RecyclerView.\n\nThis abstracts the boilerplate of view holders, diffing items and binding payload changes, item types, item ids, span counts, and more, in order to simplify building screens with multiple view types. Additionally, Epoxy adds support for saving view state and automatic diffing of item changes.\n\n[We developed Epoxy at Airbnb](https://medium.com/airbnb-engineering/epoxy-airbnbs-view-architecture-on-android-c3e1af150394#.xv4ymrtmk) to simplify the process of working with RecyclerViews, and to add the missing functionality we needed. We now use Epoxy for most of the main screens in our app and it has improved our developer experience greatly.\n\n* [Installation](#installation)\n* [Basic Usage](#basic-usage)\n* [Documentation](#documentation)\n* [Min SDK](#min-sdk)\n* [Contributing](#contributing)\n* [Sample App](https://github.com/airbnb/epoxy/wiki/Sample-App)\n\n## Installation\n\nGradle is the only supported build configuration, so just add the dependency to your project `build.gradle` file:\n\n```groovy\ndependencies {\n  implementation \"com.airbnb.android:epoxy:$epoxyVersion\"\n  // Add the annotation processor if you are using Epoxy's annotations (recommended)\n  annotationProcessor \"com.airbnb.android:epoxy-processor:$epoxyVersion\"\n}\n```\n\nReplace the variable `$epoxyVersion` with the latest version : [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.airbnb.android/epoxy/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.airbnb.android/epoxy)\n\nSee the [releases page](https://github.com/airbnb/epoxy/releases) for up to date release versions and details\n\n#### Kotlin with KAPT\nIf you are using Kotlin with KAPT you should also add\n```groovy\napply plugin: 'kotlin-kapt'\n\nkapt {\n    correctErrorTypes = true\n}\n```\n\nso that `AutoModel` annotations work properly. More information [here](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#usage-with-kotlin)\n\nAlso, make sure to use `kapt` instead of `annotationProcessor` in your dependencies in the `build.gradle` file.\n\n#### Kotlin with KSP (Recommended)\nKSP (Kotlin Symbol Processing) is recommended over KAPT as it is significantly faster.\n\nAdd the KSP plugin to your root `build.gradle`:\n```groovy\nplugins {\n    id 'com.google.devtools.ksp' version \"$KSP_VERSION\" apply false\n}\n```\n\nThen apply it in your module's `build.gradle`:\n```groovy\nplugins {\n    id 'com.android.application'\n    id 'kotlin-android'\n    id 'com.google.devtools.ksp'\n}\n\ndependencies {\n    implementation \"com.airbnb.android:epoxy:$epoxyVersion\"\n    ksp \"com.airbnb.android:epoxy-processor:$epoxyVersion\"\n}\n```\n\nYou can configure KSP processor options:\n```groovy\nksp {\n    // Validation and debugging\n    arg(\"validateEpoxyModelUsage\", \"true\")                // Validate model usage at runtime (default: true)\n    arg(\"logEpoxyTimings\", \"false\")                       // Log annotation processing timings (default: false)\n\n    // Code generation options\n    arg(\"epoxyDisableGenerateReset\", \"false\")             // Disable reset() method generation (default: false)\n    arg(\"epoxyDisableGenerateGetters\", \"false\")           // Disable getter generation (default: false)\n    arg(\"epoxyDisableGenerateOverloads\", \"false\")         // Disable builder overload generation (default: false)\n    arg(\"disableEpoxyKotlinExtensionGeneration\", \"false\") // Disable Kotlin extension generation (default: false)\n    arg(\"epoxyDisableDslMarker\", \"false\")                 // Disable DSL marker annotation (default: false)\n\n    // Model requirements\n    arg(\"requireHashCodeInEpoxyModels\", \"false\")          // Require hashCode/equals in models (default: false)\n    arg(\"requireAbstractEpoxyModels\", \"false\")            // Require abstract model classes (default: false)\n    arg(\"implicitlyAddAutoModels\", \"false\")               // Auto-add models to controllers (default: false)\n}\n```\n\n**Important:** DataBinding models are **not supported** with KSP, as Android's DataBinding library itself uses KAPT. If you need DataBinding support, you must continue using KAPT. For custom views with `@ModelView` or ViewHolder models, KSP works perfectly.\n\nSee the [epoxy-kspsample](https://github.com/airbnb/epoxy/tree/master/epoxy-kspsample) module for a complete working example.\n\n## Library Projects\nIf you are using layout resources in Epoxy annotations then for library projects add [Butterknife's gradle plugin](https://github.com/JakeWharton/butterknife#library-projects) to your `buildscript`.\n\n```groovy\nbuildscript {\n  repositories {\n    mavenCentral()\n  }\n  dependencies {\n    classpath 'com.jakewharton:butterknife-gradle-plugin:10.1.0'\n  }\n}\n```\n\nand then apply it in your module:\n```groovy\napply plugin: 'com.android.library'\napply plugin: 'com.jakewharton.butterknife'\n```\n\nNow make sure you use R2 instead of R inside all Epoxy annotations.\n```java\n@ModelView(defaultLayout = R2.layout.view_holder_header)\npublic class HeaderView extends LinearLayout {\n   ....\n}\n```\n\nThis is not necessary if you don't use resources as annotation parameters, such as with [custom view models](https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations).\n\n## Basic Usage\nThere are two main components of Epoxy:\n\n1. The `EpoxyModel`s that describe how your views should be displayed in the RecyclerView.\n2. The `EpoxyController` where the models are used to describe what items to show and with what data.\n\n### Creating Models\nEpoxy generates models for you based on your view or layout. Generated model classes are suffixed with an underscore (`_`) are used directly in your EpoxyController classes.\n\n#### From Custom Views\nAdd the `@ModelView` annotation on a view class. Then, add a \"prop\" annotation on each setter method to mark it as a property for the model.\n\n```java\n@ModelView(autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\npublic class HeaderView extends LinearLayout {\n\n  ... // Initialization omitted\n\n  @TextProp\n  public void setTitle(CharSequence text) {\n    titleView.setText(text);\n  }\n}\n```\n\nA `HeaderViewModel_` is then generated in the same package.\n\n[More Details](https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations)\n\n#### From DataBinding\n\nIf you use Android DataBinding you can simply set up your xml layouts like normal:\n\n```xml\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <data>\n        <variable name=\"title\" type=\"String\" />\n    </data>\n\n    <TextView\n        android:layout_width=\"120dp\"\n        android:layout_height=\"40dp\"\n        android:text=\"@{title}\" />\n</layout>\n```\n\nThen, create an interface or class in any package and add an `EpoxyDataBindingLayouts` annotation to declare your databinding layouts.\n\n```java\npackage com.airbnb.epoxy.sample;\n\nimport com.airbnb.epoxy.EpoxyDataBindingLayouts;\n\n@EpoxyDataBindingLayouts({R.layout.header_view, ... // other layouts })\ninterface EpoxyConfig {}\n```\n\nFrom this layout name Epoxy generates a `HeaderViewBindingModel_`.\n\n[More Details](https://github.com/airbnb/epoxy/wiki/Data-Binding-Support)\n\n#### From ViewHolders\nIf you use xml layouts without databinding you can create a model class to do the  binding.\n\n```java\n@EpoxyModelClass(layout = R.layout.header_view)\npublic abstract class HeaderModel extends EpoxyModelWithHolder<Holder> {\n  @EpoxyAttribute String title;\n\n  @Override\n  public void bind(Holder holder) {\n    holder.header.setText(title);\n  }\n\n  static class Holder extends BaseEpoxyHolder {\n    @BindView(R.id.text) TextView header;\n  }\n}\n```\n\nA `HeaderModel_` class is generated that subclasses HeaderModel and implements the model details.\n\n[More Details](https://github.com/airbnb/epoxy/wiki/ViewHolder-Models)\n\n### Using your models in a controller\n\nA controller defines what items should be shown in the RecyclerView, by adding the corresponding models in the desired order.\n\n The controller's `buildModels` method declares which items to show. You are responsible for calling `requestModelBuild` whenever your data changes, which triggers `buildModels` to run again. Epoxy tracks changes in the models and automatically binds and updates views.\n\nAs an example, our `PhotoController` shows a header, a list of photos, and a loader (if more photos are being loaded). The controller's `setData(photos, loadingMore)` method is called whenever photos are loaded, which triggers a call to `buildModels` so models representing the state of the new data can be built.\n\n```java\npublic class PhotoController extends Typed2EpoxyController<List<Photo>, Boolean> {\n    @AutoModel HeaderModel_ headerModel;\n    @AutoModel LoaderModel_ loaderModel;\n\n    @Override\n    protected void buildModels(List<Photo> photos, Boolean loadingMore) {\n      headerModel\n          .title(\"My Photos\")\n          .description(\"My album description!\")\n          .addTo(this);\n\n      for (Photo photo : photos) {\n        new PhotoModel()\n           .id(photo.id())\n           .url(photo.url())\n           .addTo(this);\n      }\n\n      loaderModel\n          .addIf(loadingMore, this);\n    }\n  }\n```\n\n#### Or with Kotlin\nAn extension function is generated for each model so we can write this:\n```kotlin\nclass PhotoController : Typed2EpoxyController<List<Photo>, Boolean>() {\n\n    override fun buildModels(photos: List<Photo>, loadingMore: Boolean) {\n        header {\n            id(\"header\")\n            title(\"My Photos\")\n            description(\"My album description!\")\n        }\n\n        photos.forEach {\n            photoView {\n                id(it.id())\n                url(it.url())\n            }\n        }\n\n        if (loadingMore) loaderView { id(\"loader\") }\n    }\n}\n```\n\n### Integrating with RecyclerView\n\nGet the backing adapter off the EpoxyController to set up your RecyclerView:\n```java\nMyController controller = new MyController();\nrecyclerView.setAdapter(controller.getAdapter());\n\n// Request a model build whenever your data changes\ncontroller.requestModelBuild();\n\n// Or if you are using a TypedEpoxyController\ncontroller.setData(myData);\n```\n\nIf you are using the [EpoxyRecyclerView](https://github.com/airbnb/epoxy/wiki/EpoxyRecyclerView) integration is easier.\n\n```java\nepoxyRecyclerView.setControllerAndBuildModels(new MyController());\n\n// Request a model build on the recyclerview when data changes\nepoxyRecyclerView.requestModelBuild();\n```\n\n#### Kotlin\nOr use [Kotlin Extensions](https://github.com/airbnb/epoxy/wiki/EpoxyRecyclerView#kotlin-extensions) to simplify further and remove the need for a controller class.\n```kotlin\nepoxyRecyclerView.withModels {\n        header {\n            id(\"header\")\n            title(\"My Photos\")\n            description(\"My album description!\")\n        }\n\n        photos.forEach {\n            photoView {\n                id(it.id())\n                url(it.url())\n            }\n        }\n\n        if (loadingMore) loaderView { id(\"loader\") }\n    }\n}\n```\n\n\n### More Reading\nAnd that's it! The controller's declarative style makes it very easy to visualize what the RecyclerView will look like, even when many different view types or items are used. Epoxy handles everything else. If a view only partially changes, such as the description, only that new value is set on the view, so the system is very efficient\n\nEpoxy handles much more than these basics, and is highly configurable. See [the wiki](https://github.com/airbnb/epoxy/wiki) for in depth documentation.\n\n## Documentation\nSee examples and browse complete documentation at the [Epoxy Wiki](https://github.com/airbnb/epoxy/wiki)\n\nIf you still have questions, feel free to create a new issue.\n\n## Min SDK\nWe support a minimum SDK of 14. However, Epoxy is based on the v7 support libraries so it should work with lower versions if you care to override the min sdk level in the manifest.\n\n## Contributing\nPull requests are welcome! We'd love help improving this library. Feel free to browse through open issues to look for things that need work. If you have a feature request or bug, please open a new issue so we can track it.\n\n## License\n\n```\nCopyright 2016 Airbnb, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n"
  },
  {
    "path": "RELEASING.md",
    "content": "Releasing\n========\n\n1. Bump the VERSION_NAME property in `gradle.properties` based on Major.Minor.Patch naming scheme\n2. Update `CHANGELOG.md` for the impending release.\n3. `git commit -am \"Prepare for release X.Y.Z.\"` (where X.Y.Z is the version you set in step 1)\n4. Add your sonatype login information under gradle properties mavenCentralUsername and mavenCentralPassword in your local user gradle.properties file\n5. Make sure you have a gpg signing key configured (https://vanniktech.github.io/gradle-maven-publish-plugin/central/#secrets)\n5. Run `./gradlew publish` to build the artifacts and publish them to maven\n7. Open PR on Github, merge, and publish release through Github UI.\n\nPublishing a release to an internal repository\n========\n\nTo publish an internal release to an Artifactory repository:\n\n1. Set credential values for ARTIFACTORY_USERNAME and ARTIFACTORY_PASSWORD in your local gradle.properties\n2. Set values for ARTIFACTORY_RELEASE_URL (and optionally ARTIFACTORY_SNAPSHOT_URL if you are publishing a snapshot)\n3. ./gradlew publishAllPublicationsToAirbnbArtifactoryRepository -PdoNotSignRelease=true --no-configuration-cache\n4. \"-PdoNotSignRelease=true\" is optional, but we don't need to sign artifactory releases and this allows everyone to publish without setting up a gpg key\n\nIf you need to publish to a different repository, look at the configuration in 'publishing.gradle'\nto see how to configure additional repositories.\n\nMaven Local Installation\n=======================\n\nIf testing changes locally, you can install to mavenLocal via `./gradlew publishToMavenLocal`"
  },
  {
    "path": "UpdateProcessorTestResources.kt",
    "content": "#!/usr/bin/env kscript\n@file:DependsOn(\"org.jsoup:jsoup:1.13.1\")\n\nimport org.jsoup.Jsoup\nimport org.jsoup.nodes.Document\nimport java.io.File\n\n\nfun main() {\n    val testResultHtmlRegex = Regex(\"/build/reports/tests/.*/classes/.*\\\\.html\")\n    File(\".\")\n        .walk()\n        .filter { it.isFile }\n        .filter { it.path.contains(testResultHtmlRegex) }\n        .forEach { updateTestClass(it) }\n}\n\nfun updateTestClass(testReport: File) {\n    val doc: Document = Jsoup.parse(testReport, \"UTF-8\")\n\n    // Failing processor tests have their output in a <pre></pre> block\n    doc.getElementsByTag(\"pre\")\n        .filter { element ->\n            // A failing block contains the text \"Source declared the same top-level types of an expected source, but\n            // didn't match exactly.\"\n            element.text().contains(\"Source declared the same top-level types of an expected source\")\n        }.map { it.text() }\n        .forEach { failingTestText ->\n            updateIndividualTest(failingTestText)\n        }\n}\n\nprivate fun updateIndividualTest(failingTestText: String) {\n    val expectedFile = expectedFileRegex\n        .find(failingTestText)\n        ?.groupValues\n        ?.getOrNull(1)\n\n        ?.let { filePath ->\n            // The test copies the source file to the build folder. We need to modify the original file to update its expected source\n            File(\n                filePath.replace(\n                    \"/build/intermediates/sourceFolderJavaResources/debug/\",\n                    \"/src/test/resources/\"\n                )\n            )\n        }\n        ?.takeIf { it.isFile }\n        ?: error(\"Count not find expected file in $failingTestText\")\n\n    // The error message includes the source code that was generated.\n    // Actual Source:\n    //=================\n    // [code here]\n    //\n    // javaSources was: [com.google.testing.compile.JavaFileObjects$ResourceSourceJavaFileObject[file:/Users/elihart/repos/epoxy/epoxy-modelfactorytest/build/intermediates/sourceFolderJavaResources/debug/GroupPropMultipleSupportedAttributeDifferentNameModelView.java]]\n    // at com.airbnb.epoxy.ProcessorTestUtils.assertGeneration(ProcessorTestUtils.kt:33)\n    // ...\n\n    val actualSource = failingTestText.substringAfter(\n        \"\"\"\n            Actual Source:\n            =================\n\n        \"\"\".trimIndent()\n    ).substringBefore(\"javaSources was:\")\n        .substringBefore(\"object was:\")\n\n    expectedFile.writeText(actualSource)\n\n    println(\"Updated test source ${expectedFile.path.substringAfter(\"/epoxy/\")}\")\n}\n\n// We expect to see a line like:\n// Expected file: </Users/elihart/repos/epoxy/epoxy-modelfactorytest/build/intermediates/sourceFolderJavaResources/debug/AllTypesModelViewModel_.java>\n// Which tells us where the original processor test file lives\nval expectedFileRegex = Regex(\"Expected file: <(.*)>\")\n"
  },
  {
    "path": "blessedDeps.gradle",
    "content": "/**\n * \"Blessed\" dependencies give us the ability to force a dependency(s) version to be consistent\n *  for packaging a library. In turn, this also allows the ability to retract the forced update\n *  based off build type/flavor which reduces regressions caused by conflicts.\n *\n *  As an added bonus, we don't bloat our project build file by abstracting dependencies into its own\n *  gradle file, then applying it back in as necessary.\n */\n\nrootProject.ext.TARGET_SDK_VERSION = 30\nrootProject.ext.COMPILE_SDK_VERSION = 33\nrootProject.ext.MIN_SDK_VERSION = 14\nrootProject.ext.COMPOSE_MIN_SDK_VERSION = 21\nrootProject.ext.PARIS_MIN_SDK_VERSION = 21\n\nrootProject.ext.ANDROIDX_ANNOTATION = \"1.5.0\"\nrootProject.ext.ANDROIDX_APPCOMPAT = \"1.5.1\"\nrootProject.ext.ANDROIDX_CARDVIEW = \"1.0.0\"\nrootProject.ext.ANDROIDX_CORE_KTX = \"1.3.2\"\nrootProject.ext.ANDROIDX_DATABINDING_ADAPTERS = \"3.2.1\"\nrootProject.ext.ANDROIDX_DATABINDING_COMPILER = \"3.2.1\"\nrootProject.ext.ANDROIDX_DATABINDING_LIBRARY = \"3.2.1\"\nrootProject.ext.ANDROIDX_ESPRESSO_CORE = \"3.5.1\"\nrootProject.ext.ANDROIDX_FRAGMENT_TESTING = \"1.3.3\"\nrootProject.ext.ANDROIDX_LEGACY = \"1.0.0\"\nrootProject.ext.ANDROIDX_MATERIAL = \"1.3.0\"\nrootProject.ext.ANDROIDX_PAGING = \"2.0.0\"\nrootProject.ext.ANDROIDX_PAGING3 = \"3.1.1\"\nrootProject.ext.ANDROIDX_RECYCLERVIEW = \"1.3.0-rc01\"\nrootProject.ext.ANDROIDX_ROOM = \"2.5.0-beta01\"\nrootProject.ext.ANDROIDX_RUNTIME = \"2.3.1\"\nrootProject.ext.ANDROIDX_VERSIONED_PARCELABLE = \"1.1.1\"\nrootProject.ext.ANDROID_ARCH_TESTING = \"2.1.0\"\nrootProject.ext.ANDROID_DATA_BINDING = \"1.3.1\"\nrootProject.ext.ANDROID_RUNTIME_VERSION = \"4.1.1.4\"\nrootProject.ext.ANDROID_TEST_RUNNER = \"1.5.2\"\nrootProject.ext.ANDROID_TEST_RULES = \"1.5.0\"\nrootProject.ext.ASSERTJ_VERSION = \"1.7.1\"\nrootProject.ext.AUTO_VALUE_VERSION = \"1.7.4\"\nrootProject.ext.GLIDE_VERSION = \"4.12.0\"\nrootProject.ext.GOOGLE_TESTING_COMPILE_VERSION = \"0.23.0\"\nrootProject.ext.INCAP_VERSION = \"0.3\"\nrootProject.ext.JUNIT_VERSION = \"4.13.2\"\nrootProject.ext.KOTLIN_COROUTINES_VERSION = \"1.6.4\"\nrootProject.ext.LOTTIE_VERSION = \"2.8.0\"\nrootProject.ext.MOCKITO_VERSION = \"5.20.0\"\nrootProject.ext.PARIS_VERSION = \"2.2.1\"\nrootProject.ext.ROBOLECTRIC_VERSION = \"4.9.2\"\nrootProject.ext.SQUARE_JAVAPOET_VERSION = \"1.13.0\"\nrootProject.ext.SQUARE_KOTLINPOET_VERSION = \"1.12.0\"\nrootProject.ext.COMPOSE_VERSION = \"1.4.2\"\nrootProject.ext.COMPOSE_ACTIVITY_VERSION = \"1.6.0\"\nrootProject.ext.KOTLINX_LIFECYCLE_RUNTIME_VERSION = \"2.5.1\"\nrootProject.ext.XPROCESSING_VERSION = \"2.8.4\"\nrootProject.ext.KOTLIN_TESTING_COMPILE_VERSION = '0.11.0'\nrootProject.ext.LIFECYCLE_VIEWMODEL = '2.6.1'\n\nrootProject.ext.deps = [\n    activityCompose                     : \"androidx.activity:activity-compose:$COMPOSE_ACTIVITY_VERSION\",\n    androidAnnotations                  : \"androidx.annotation:annotation:$ANDROIDX_ANNOTATION\",\n    androidAppcompat                    : \"androidx.appcompat:appcompat:$ANDROIDX_APPCOMPAT\",\n    androidArchCoreTesting              : \"androidx.arch.core:core-testing:$ANDROID_ARCH_TESTING\",\n    androidCardView                     : \"androidx.cardview:cardview:$ANDROIDX_CARDVIEW\",\n    androidCoreKtx                      : \"androidx.core:core-ktx:$ANDROIDX_CORE_KTX\",\n    androidDesignLibrary                : \"com.google.android.material:material:$ANDROIDX_MATERIAL\",\n    androidEspressoCore                 : \"androidx.test.espresso:espresso-core:$ANDROIDX_ESPRESSO_CORE\",\n    androidFragmentTesting              : \"androidx.fragment:fragment-testing:$ANDROIDX_FRAGMENT_TESTING\",\n    androidLifecycleRuntimeKtx          : \"androidx.lifecycle:lifecycle-runtime-ktx:$KOTLINX_LIFECYCLE_RUNTIME_VERSION\",\n    androidPaging3Component             : \"androidx.paging:paging-runtime:$ANDROIDX_PAGING3\",\n    androidPagingComponent              : \"androidx.paging:paging-runtime:$ANDROIDX_PAGING\",\n    androidRecyclerView                 : \"androidx.recyclerview:recyclerview:$ANDROIDX_RECYCLERVIEW\",\n    androidRuntime                      : \"com.google.android:android:$ANDROID_RUNTIME_VERSION\",\n    androidTestCore                     : \"androidx.test:core:1.3.0\",\n    androidTestExtJunitKtx              : \"androidx.test.ext:junit-ktx:1.1.2\",\n    androidTestRules                    : \"androidx.test:rules:$ANDROID_TEST_RULES\",\n    androidTestRunner                   : \"androidx.test:runner:$ANDROID_TEST_RUNNER\",\n    assertj                             : \"org.assertj:assertj-core:$ASSERTJ_VERSION\",\n    autoValue                           : \"com.google.auto.value:auto-value:$AUTO_VALUE_VERSION\",\n    composeMaterial                     : \"androidx.compose.material:material:$COMPOSE_VERSION\",\n    composeUi                           : \"androidx.compose.ui:ui:$COMPOSE_VERSION\",\n    composeUiTooling                    : \"androidx.compose.ui:ui-tooling:$COMPOSE_VERSION\",\n    dataBindingAdapters                 : \"androidx.databinding:databinding-adapters:$ANDROIDX_DATABINDING_ADAPTERS\",\n    dataBindingLibrary                  : \"androidx.databinding:databinding-library:$ANDROIDX_DATABINDING_LIBRARY\",\n    glide                               : \"com.github.bumptech.glide:glide:$GLIDE_VERSION\",\n    googleTestingCompile                : \"com.google.testing.compile:compile-testing:$GOOGLE_TESTING_COMPILE_VERSION\",\n    incapProcessor                      : \"net.ltgt.gradle.incap:incap-processor:$INCAP_VERSION\",\n    incapRuntime                        : \"net.ltgt.gradle.incap:incap:$INCAP_VERSION\",\n    junit                               : \"junit:junit:$JUNIT_VERSION\",\n    kotlinCoroutines                    : \"org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLIN_COROUTINES_VERSION\",\n    kotlinCoroutinesTest                : \"org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLIN_COROUTINES_VERSION\",\n    kotlinxMetadata                     : \"org.jetbrains.kotlin:kotlin-metadata-jvm:$KOTLIN_VERSION\",\n    lottie                              : \"com.airbnb.android:lottie:$LOTTIE_VERSION\",\n    mockito                             : \"org.mockito:mockito-core:$MOCKITO_VERSION\",\n    paris                               : \"com.airbnb.android:paris:$PARIS_VERSION\",\n    parisProcessor                      : \"com.airbnb.android:paris-processor:$PARIS_VERSION\",\n    robolectric                         : \"org.robolectric:robolectric:$ROBOLECTRIC_VERSION\",\n    squareJavaPoet                      : \"com.squareup:javapoet:$SQUARE_JAVAPOET_VERSION\",\n    squareKotlinPoet                    : \"com.squareup:kotlinpoet:$SQUARE_KOTLINPOET_VERSION\",\n    kotlinPoetJavaInterop               : \"com.squareup:kotlinpoet-javapoet:$SQUARE_KOTLINPOET_VERSION\",\n    kotlinPoetKspInterop                : \"com.squareup:kotlinpoet-ksp:$SQUARE_KOTLINPOET_VERSION\",\n    versionedParcelable                 : \"androidx.versionedparcelable:versionedparcelable:$ANDROIDX_VERSIONED_PARCELABLE\",\n    ksp                                 : \"com.google.devtools.ksp:symbol-processing-api:$KSP_VERSION\",\n    kspAaEmbeddable                     : \"com.google.devtools.ksp:symbol-processing-aa-embeddable:$KSP_VERSION\",\n    kspImpl                             : \"com.google.devtools.ksp:symbol-processing:$KSP_VERSION\",\n    xProcessing                         : \"androidx.room:room-compiler-processing:$XPROCESSING_VERSION\",\n    xProcessingTesting                  : \"androidx.room:room-compiler-processing-testing:$XPROCESSING_VERSION\",\n    kotlinCompileTesting                : \"dev.zacsweers.kctfork:ksp:$KOTLIN_TESTING_COMPILE_VERSION\",\n    kotlinAnnotationProcessingEmbeddable: \"org.jetbrains.kotlin:kotlin-annotation-processing-embeddable:$KOTLIN_VERSION\",\n    lifecycleViewmodel                  : \"androidx.lifecycle:lifecycle-viewmodel:$LIFECYCLE_VIEWMODEL\",\n    lifecycleViewmodelKtx               : \"androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VIEWMODEL\",\n]\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n\n  ext.KOTLIN_VERSION = \"2.2.21\"\n  ext.ANDROID_PLUGIN_VERSION = '8.13.0'\n  ext.KSP_VERSION = '2.3.3'\n\n  repositories {\n    google()\n    mavenCentral()\n    gradlePluginPortal()\n  }\n  dependencies {\n    classpath \"com.android.tools.build:gradle:$ANDROID_PLUGIN_VERSION\"\n    classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION\"\n    classpath \"org.jetbrains.kotlin:compose-compiler-gradle-plugin:$KOTLIN_VERSION\"\n    // Upload with: (see RELEASING.md)\n    // ./gradlew publishAllPublicationsToMavenCentral --no-configuration-cache\n    classpath 'com.vanniktech:gradle-maven-publish-plugin:0.35.0'\n    // Dokka is needed on classpath for vanniktech publish plugin\n    classpath \"org.jetbrains.dokka:dokka-gradle-plugin:1.6.10\"\n  }\n}\n\nplugins {\n  // Run ./gradlew dependencyUpdates to see available version updates\n  id 'com.github.ben-manes.versions' version '0.42.0'\n  id \"com.google.devtools.ksp\" version \"$KSP_VERSION\"\n}\n\nallprojects {\n\n  repositories {\n    google()\n    mavenCentral()\n  }\n\n  // Prevent javadoc task complaining about errors with kotlin files\n  tasks.withType(Javadoc) {\n    excludes = ['**/*.kt']\n  }\n}\n\nsubprojects { project ->\n  apply from: \"$rootDir/blessedDeps.gradle\"\n  apply plugin: 'com.github.ben-manes.versions'\n  apply from: \"${project.rootDir}/ktlint.gradle\"\n\n  afterEvaluate {\n    if (project.tasks.findByName('check')) {\n      check.dependsOn('ktlint')\n    }\n\n    if (project.extensions.findByType(com.android.build.gradle.LibraryExtension.class) != null) {\n      project.android.libraryVariants.all { variant ->\n        def outputFolder = new File(\"build/generated/ksp/${variant.name}/kotlin\")\n        variant.addJavaSourceFoldersToModel(outputFolder)\n        android.sourceSets.getAt(variant.name).java {\n          srcDir(outputFolder)\n        }\n      }\n    } else if (project.extensions.findByType(com.android.build.gradle.AbstractAppExtension.class) != null) {\n      project.android.applicationVariants.all { variant ->\n        def outputFolder = new File(\"build/generated/ksp/${variant.name}/kotlin\")\n        variant.addJavaSourceFoldersToModel(outputFolder)\n        android.sourceSets.getAt(variant.name).java {\n          srcDir(outputFolder)\n        }\n      }\n    }\n  }\n}\n\ndef isNonStable = { String version ->\n  def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.uppercase().contains(it) }\n  def regex = /^[0-9,.v-]+(-r)?$/\n  return !stableKeyword && !(version ==~ regex)\n}\n\ntasks.named(\"dependencyUpdates\").configure {\n  // disallow release candidates as upgradable versions from stable versions\n  rejectVersionIf {\n    isNonStable(it.candidate.version) && !isNonStable(it.currentVersion)\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-adapter/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply plugin: 'kotlin-parcelize'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.viewmodeladapter'\n\n  defaultConfig {\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    consumerProguardFiles 'proguard-rules.pro'\n  }\n\n  testOptions.unitTests.includeAndroidResources = true\n\n  buildTypes.all { buildType ->\n    buildType.javaCompileOptions.annotationProcessorOptions.arguments =\n        [\n            logEpoxyTimings: \"true\"\n        ]\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\nconfigurations.all { strategy ->\n  strategy.resolutionStrategy.force rootProject.deps.androidAnnotations, rootProject.deps.androidRecyclerView,\n      rootProject.deps.androidDesignLibrary, rootProject.deps.androidAppcompat, rootProject.deps.junit,\n      rootProject.deps.robolectric, rootProject.deps.mockito\n}\n\ndependencies {\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidAnnotations\n  implementation rootProject.deps.androidRecyclerView\n  implementation rootProject.deps.androidDesignLibrary\n  api project(':epoxy-annotations')\n\n  kapt project(':epoxy-processor')\n  kaptTest project(':epoxy-processor')\n\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.robolectric\n  testImplementation rootProject.deps.mockito\n  testImplementation rootProject.deps.androidTestCore\n}\n"
  },
  {
    "path": "epoxy-adapter/gradle.properties",
    "content": "POM_NAME=Epoxy\nPOM_ARTIFACT_ID=epoxy\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-adapter/lint.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<lint>\n  <issue id=\"InvalidPackage\" severity=\"warning\" />\n  <!-- https://code.google.com/p/android/issues/detail?id=175532 -->\n  <issue id=\"WrongConstant\" severity=\"warning\" />\n  <issue id=\"PluralsCandidate\" severity=\"ignore\" />\n  <issue id=\"Typos\" severity=\"ignore\" />\n  <issue id=\"InvalidPackage\" severity=\"ignore\" />\n</lint>\n"
  },
  {
    "path": "epoxy-adapter/proguard-rules.pro",
    "content": "# The generated ControllerHelper classes are needed when using AutoModel annotations.\n# Each ControllerHelper is looked up reflectively, so we need to make sure it is\n# kept and its name not obfuscated so the reflective lookup works.\n-keep class * extends com.airbnb.epoxy.EpoxyController { *; }\n-keep class * extends com.airbnb.epoxy.ControllerHelper { *; }\n-keepclasseswithmembernames class * { @com.airbnb.epoxy.AutoModel <fields>; }"
  },
  {
    "path": "epoxy-adapter/src/main/AndroidManifest.xml",
    "content": "<manifest>\n\n    <application />\n\n</manifest>"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ActivityRecyclerPool.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.os.Build\nimport androidx.core.view.ViewCompat\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.OnLifecycleEvent\nimport androidx.recyclerview.widget.RecyclerView\nimport java.lang.ref.WeakReference\nimport java.util.ArrayList\n\ninternal class ActivityRecyclerPool {\n\n    /**\n     * Store one unique pool per activity. They are cleared out when activities are destroyed, so this\n     * only needs to hold pools for active activities.\n     */\n    private val pools = ArrayList<PoolReference>(5)\n\n    @JvmOverloads\n    fun getPool(\n        context: Context,\n        poolFactory: () -> RecyclerView.RecycledViewPool\n    ): PoolReference {\n\n        val iterator = pools.iterator()\n        var poolToUse: PoolReference? = null\n\n        while (iterator.hasNext()) {\n            val poolReference = iterator.next()\n            when {\n                poolReference.context === context -> {\n                    if (poolToUse != null) {\n                        throw IllegalStateException(\"A pool was already found\")\n                    }\n                    poolToUse = poolReference\n                    // finish iterating to remove any old contexts\n                }\n                poolReference.context.isActivityDestroyed() -> {\n                    // A pool from a different activity that was destroyed.\n                    // Clear the pool references to allow the activity to be GC'd\n                    poolReference.viewPool.clear()\n                    iterator.remove()\n                }\n            }\n        }\n\n        if (poolToUse == null) {\n            poolToUse = PoolReference(context, poolFactory(), this)\n            context.lifecycle()?.addObserver(poolToUse)\n            pools.add(poolToUse)\n        }\n\n        return poolToUse\n    }\n\n    fun clearIfDestroyed(pool: PoolReference) {\n        if (pool.context.isActivityDestroyed()) {\n            pool.viewPool.clear()\n            pools.remove(pool)\n        }\n    }\n\n    private fun Context.lifecycle(): Lifecycle? {\n        if (this is LifecycleOwner) {\n            return lifecycle\n        }\n\n        if (this is ContextWrapper) {\n            return baseContext.lifecycle()\n        }\n\n        return null\n    }\n}\n\ninternal class PoolReference(\n    context: Context,\n    val viewPool: RecyclerView.RecycledViewPool,\n    private val parent: ActivityRecyclerPool\n) : LifecycleObserver {\n    private val contextReference: WeakReference<Context> = WeakReference(context)\n\n    val context: Context? get() = contextReference.get()\n\n    fun clearIfDestroyed() {\n        parent.clearIfDestroyed(this)\n    }\n\n    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)\n    fun onContextDestroyed() {\n        clearIfDestroyed()\n    }\n}\n\ninternal fun Context?.isActivityDestroyed(): Boolean {\n    if (this == null) {\n        return true\n    }\n\n    if (this !is Activity) {\n        return (this as? ContextWrapper)?.baseContext?.isActivityDestroyed() ?: false\n    }\n\n    if (isFinishing) {\n        return true\n    }\n\n    return if (Build.VERSION.SDK_INT >= 17) {\n        isDestroyed\n    } else {\n        // Use this as a proxy for being destroyed on older devices\n        !ViewCompat.isAttachedToWindow(window.decorView)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/AsyncEpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\n\nimport static com.airbnb.epoxy.EpoxyAsyncUtil.MAIN_THREAD_HANDLER;\nimport static com.airbnb.epoxy.EpoxyAsyncUtil.getAsyncBackgroundHandler;\n\n/**\n * A subclass of {@link EpoxyController} that makes it easy to do model building and diffing in\n * the background.\n * <p>\n * See https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#asynchronous-support\n */\npublic abstract class AsyncEpoxyController extends EpoxyController {\n\n  /**\n   * A new instance that does model building and diffing asynchronously.\n   */\n  public AsyncEpoxyController() {\n    this(true);\n  }\n\n  /**\n   * @param enableAsync True to do model building and diffing asynchronously, false to do them\n   *                    both on the main thread.\n   */\n  public AsyncEpoxyController(boolean enableAsync) {\n    this(enableAsync, enableAsync);\n  }\n\n  /**\n   * Individually control whether model building and diffing are done async or on the main thread.\n   */\n  public AsyncEpoxyController(boolean enableAsyncModelBuilding, boolean enableAsyncDiffing) {\n    super(getHandler(enableAsyncModelBuilding), getHandler(enableAsyncDiffing));\n  }\n\n  private static Handler getHandler(boolean enableAsync) {\n    return enableAsync ? getAsyncBackgroundHandler() : MAIN_THREAD_HANDLER;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/AsyncEpoxyDiffer.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.Executor;\n\nimport androidx.annotation.AnyThread;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.DiffUtil;\nimport androidx.recyclerview.widget.DiffUtil.ItemCallback;\n\n/**\n * An adaptation of Google's {@link androidx.recyclerview.widget.AsyncListDiffer}\n * that adds support for payloads in changes.\n * <p>\n * Also adds support for canceling an in progress diff, and makes everything thread safe.\n */\nclass AsyncEpoxyDiffer {\n\n  interface ResultCallback {\n    void onResult(@NonNull DiffResult result);\n  }\n\n  private final Executor executor;\n  private final ResultCallback resultCallback;\n  private final ItemCallback<EpoxyModel<?>> diffCallback;\n  private final GenerationTracker generationTracker = new GenerationTracker();\n\n  AsyncEpoxyDiffer(\n      @NonNull Handler handler,\n      @NonNull ResultCallback resultCallback,\n      @NonNull ItemCallback<EpoxyModel<?>> diffCallback\n  ) {\n    this.executor = new HandlerExecutor(handler);\n    this.resultCallback = resultCallback;\n    this.diffCallback = diffCallback;\n  }\n\n  @Nullable\n  private volatile List<? extends EpoxyModel<?>> list;\n\n  /**\n   * Non-null, unmodifiable version of list.\n   * <p>\n   * Collections.emptyList when list is null, wrapped by Collections.unmodifiableList otherwise\n   */\n  @NonNull\n  private volatile List<? extends EpoxyModel<?>> readOnlyList = Collections.emptyList();\n\n  /**\n   * Get the current List - any diffing to present this list has already been computed and\n   * dispatched via the ListUpdateCallback.\n   * <p>\n   * If a <code>null</code> List, or no List has been submitted, an empty list will be returned.\n   * <p>\n   * The returned list may not be mutated - mutations to content must be done through\n   * {@link #submitList(List)}.\n   *\n   * @return current List.\n   */\n  @AnyThread\n  @NonNull\n  public List<? extends EpoxyModel<?>> getCurrentList() {\n    return readOnlyList;\n  }\n\n  /**\n   * Prevents any ongoing diff from dispatching results. Returns true if there was an ongoing\n   * diff to cancel, false otherwise.\n   */\n  @SuppressWarnings(\"WeakerAccess\")\n  @AnyThread\n  public boolean cancelDiff() {\n    return generationTracker.finishMaxGeneration();\n  }\n\n  /**\n   * @return True if a diff operation is in progress.\n   */\n  @SuppressWarnings(\"WeakerAccess\")\n  @AnyThread\n  public boolean isDiffInProgress() {\n    return generationTracker.hasUnfinishedGeneration();\n  }\n\n  /**\n   * Set the current list without performing any diffing. Cancels any diff in progress.\n   * <p>\n   * This can be used if you notified a change to the adapter manually and need this list to be\n   * synced.\n   */\n  @AnyThread\n  public synchronized boolean forceListOverride(@Nullable List<EpoxyModel<?>> newList) {\n    // We need to make sure that generation changes and list updates are synchronized\n    final boolean interruptedDiff = cancelDiff();\n    int generation = generationTracker.incrementAndGetNextScheduled();\n    tryLatchList(newList, generation);\n    return interruptedDiff;\n  }\n\n  /**\n   * Set a new List representing your latest data.\n   * <p>\n   * A diff will be computed between this list and the last list set. If this has not previously\n   * been called then an empty list is used as the previous list.\n   * <p>\n   * The diff computation will be done on the thread given by the handler in the constructor.\n   * When the diff is done it will be applied (dispatched to the result callback),\n   * and the new List will be swapped in.\n   */\n  @AnyThread\n  @SuppressWarnings(\"WeakerAccess\")\n  public void submitList(@Nullable final List<? extends EpoxyModel<?>> newList) {\n    final int runGeneration;\n    @Nullable final List<? extends EpoxyModel<?>> previousList;\n\n    synchronized (this) {\n      // Incrementing generation means any currently-running diffs are discarded when they finish\n      // We synchronize to guarantee list object and generation number are in sync\n      runGeneration = generationTracker.incrementAndGetNextScheduled();\n      previousList = list;\n    }\n\n    if (newList == previousList) {\n      // nothing to do\n      onRunCompleted(runGeneration, newList, DiffResult.noOp(previousList));\n      return;\n    }\n\n    if (newList == null || newList.isEmpty()) {\n      // fast simple clear all\n      DiffResult result = null;\n      if (previousList != null && !previousList.isEmpty()) {\n        result = DiffResult.clear(previousList);\n      }\n      onRunCompleted(runGeneration, null, result);\n      return;\n    }\n\n    if (previousList == null || previousList.isEmpty()) {\n      // fast simple first insert\n      onRunCompleted(runGeneration, newList, DiffResult.inserted(newList));\n      return;\n    }\n\n    final DiffCallback wrappedCallback = new DiffCallback(previousList, newList, diffCallback);\n\n    executor.execute(new Runnable() {\n      @Override\n      public void run() {\n        DiffUtil.DiffResult result = DiffUtil.calculateDiff(wrappedCallback);\n        onRunCompleted(runGeneration, newList, DiffResult.diff(previousList, newList, result));\n      }\n    });\n  }\n\n  private void onRunCompleted(\n      final int runGeneration,\n      @Nullable final List<? extends EpoxyModel<?>> newList,\n      @Nullable final DiffResult result\n  ) {\n\n    // We use an asynchronous handler so that the Runnable can be posted directly back to the main\n    // thread without waiting on view invalidation synchronization.\n    MainThreadExecutor.ASYNC_INSTANCE.execute(new Runnable() {\n      @Override\n      public void run() {\n        final boolean dispatchResult = tryLatchList(newList, runGeneration);\n        if (result != null && dispatchResult) {\n          resultCallback.onResult(result);\n        }\n      }\n    });\n  }\n\n  /**\n   * Marks the generation as done, and updates the list if the generation is the most recent.\n   *\n   * @return True if the given generation is the most recent, in which case the given list was\n   * set. False if the generation is old and the list was ignored.\n   */\n  @AnyThread\n  private synchronized boolean tryLatchList(@Nullable List<? extends EpoxyModel<?>> newList,\n      int runGeneration) {\n    if (generationTracker.finishGeneration(runGeneration)) {\n      list = newList;\n\n      if (newList == null) {\n        readOnlyList = Collections.emptyList();\n      } else {\n        readOnlyList = Collections.unmodifiableList(newList);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * The concept of a \"generation\" is used to associate a diff result with a point in time when\n   * it was created. This allows us to handle list updates concurrently, and ignore outdated diffs.\n   * <p>\n   * We track the highest start generation, and the highest finished generation, and these must\n   * be kept in sync, so all access to this class is synchronized.\n   * <p>\n   * The general synchronization strategy for this class is that when a generation number\n   * is queried that action must be synchronized with accessing the current list, so that the\n   * generation number is synced with the list state at the time it was created.\n   */\n  private static class GenerationTracker {\n\n    // Max generation of currently scheduled runnable\n    private volatile int maxScheduledGeneration;\n    private volatile int maxFinishedGeneration;\n\n    synchronized int incrementAndGetNextScheduled() {\n      return ++maxScheduledGeneration;\n    }\n\n    synchronized boolean finishMaxGeneration() {\n      boolean isInterrupting = hasUnfinishedGeneration();\n      maxFinishedGeneration = maxScheduledGeneration;\n      return isInterrupting;\n    }\n\n    synchronized boolean hasUnfinishedGeneration() {\n      return maxScheduledGeneration > maxFinishedGeneration;\n    }\n\n    synchronized boolean finishGeneration(int runGeneration) {\n      boolean isLatestGeneration =\n          maxScheduledGeneration == runGeneration && runGeneration > maxFinishedGeneration;\n\n      if (isLatestGeneration) {\n        maxFinishedGeneration = runGeneration;\n      }\n\n      return isLatestGeneration;\n    }\n  }\n\n  private static class DiffCallback extends DiffUtil.Callback {\n\n    final List<? extends EpoxyModel<?>> oldList;\n    final List<? extends EpoxyModel<?>> newList;\n    private final ItemCallback<EpoxyModel<?>> diffCallback;\n\n    DiffCallback(List<? extends EpoxyModel<?>> oldList, List<? extends EpoxyModel<?>> newList,\n        ItemCallback<EpoxyModel<?>> diffCallback) {\n      this.oldList = oldList;\n      this.newList = newList;\n      this.diffCallback = diffCallback;\n    }\n\n    @Override\n    public int getOldListSize() {\n      return oldList.size();\n    }\n\n    @Override\n    public int getNewListSize() {\n      return newList.size();\n    }\n\n    @Override\n    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {\n      return diffCallback.areItemsTheSame(\n          oldList.get(oldItemPosition),\n          newList.get(newItemPosition)\n      );\n    }\n\n    @Override\n    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {\n      return diffCallback.areContentsTheSame(\n          oldList.get(oldItemPosition),\n          newList.get(newItemPosition)\n      );\n    }\n\n    @Nullable\n    @Override\n    public Object getChangePayload(int oldItemPosition, int newItemPosition) {\n      return diffCallback.getChangePayload(\n          oldList.get(oldItemPosition),\n          newList.get(newItemPosition)\n      );\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/BaseEpoxyAdapter.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Bundle;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.annotation.CallSuper;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic abstract class BaseEpoxyAdapter\n    extends RecyclerView.Adapter<EpoxyViewHolder>\n    implements StickyHeaderCallbacks {\n\n  private static final String SAVED_STATE_ARG_VIEW_HOLDERS = \"saved_state_view_holders\";\n\n  private int spanCount = 1;\n\n  private final ViewTypeManager viewTypeManager = new ViewTypeManager();\n  /**\n   * Keeps track of view holders that are currently bound so we can save their state in {@link\n   * #onSaveInstanceState(Bundle)}.\n   */\n  private final BoundViewHolders boundViewHolders = new BoundViewHolders();\n  private ViewHolderState viewHolderState = new ViewHolderState();\n\n  private final SpanSizeLookup spanSizeLookup = new SpanSizeLookup() {\n\n    @Override\n    public int getSpanSize(int position) {\n      try {\n        return getModelForPosition(position)\n            .spanSize(spanCount, position, getItemCount());\n      } catch (IndexOutOfBoundsException e) {\n        // There seems to be a GridLayoutManager bug where when the user is in accessibility mode\n        // it incorrectly uses an outdated view position\n        // when calling this method. This crashes when a view is animating out, when it is\n        // removed from the adapter but technically still added\n        // to the layout. We've posted a bug report and hopefully can update when the support\n        // library fixes this\n        // TODO: (eli_hart 8/23/16) Figure out if this has been fixed in new support library\n        onExceptionSwallowed(e);\n        return 1;\n      }\n    }\n  };\n\n  public BaseEpoxyAdapter() {\n    // Defaults to stable ids since view models generate unique ids. Set this to false in the\n    // subclass if you don't want to support it\n    setHasStableIds(true);\n    spanSizeLookup.setSpanIndexCacheEnabled(true);\n  }\n\n  /**\n   * This is called when recoverable exceptions happen at runtime. They can be ignored and Epoxy\n   * will recover, but you can override this to be aware of when they happen.\n   */\n  protected void onExceptionSwallowed(RuntimeException exception) {\n\n  }\n\n  @Override\n  public int getItemCount() {\n    return getCurrentModels().size();\n  }\n\n  /** Return the models currently being used by the adapter to populate the recyclerview. */\n  abstract List<? extends EpoxyModel<?>> getCurrentModels();\n\n  public boolean isEmpty() {\n    return getCurrentModels().isEmpty();\n  }\n\n  @Override\n  public long getItemId(int position) {\n    // This does not call getModelForPosition so that we don't use the id of the empty model when\n    // hidden,\n    // so that the id stays constant when gone vs shown\n    return getCurrentModels().get(position).id();\n  }\n\n  @Override\n  public int getItemViewType(int position) {\n    return viewTypeManager.getViewTypeAndRememberModel(getModelForPosition(position));\n  }\n\n  @Override\n  public EpoxyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n    EpoxyModel<?> model = viewTypeManager.getModelForViewType(this, viewType);\n    View view = model.buildView(parent);\n    return new EpoxyViewHolder(parent, view, model.shouldSaveViewState());\n  }\n\n  @Override\n  public void onBindViewHolder(EpoxyViewHolder holder, int position) {\n    onBindViewHolder(holder, position, Collections.emptyList());\n  }\n\n  @Override\n  public void onBindViewHolder(EpoxyViewHolder holder, int position, List<Object> payloads) {\n    EpoxyModel<?> modelToShow = getModelForPosition(position);\n\n    EpoxyModel<?> previouslyBoundModel = null;\n    if (diffPayloadsEnabled()) {\n      previouslyBoundModel = DiffPayload.getModelFromPayload(payloads, getItemId(position));\n    }\n\n    holder.bind(modelToShow, previouslyBoundModel, payloads, position);\n\n    if (payloads.isEmpty()) {\n      // We only apply saved state to the view on initial bind, not on model updates.\n      // Since view state should be independent of model props, we should not need to apply state\n      // again in this case. This simplifies a rebind on update\n      viewHolderState.restore(holder);\n    }\n\n    boundViewHolders.put(holder);\n\n    if (diffPayloadsEnabled()) {\n      onModelBound(holder, modelToShow, position, previouslyBoundModel);\n    } else {\n      onModelBound(holder, modelToShow, position, payloads);\n    }\n  }\n\n  boolean diffPayloadsEnabled() {\n    return false;\n  }\n\n  /**\n   * Called immediately after a model is bound to a view holder. Subclasses can override this if\n   * they want alerts on when a model is bound.\n   */\n  protected void onModelBound(EpoxyViewHolder holder, EpoxyModel<?> model, int position,\n      @Nullable List<Object> payloads) {\n    onModelBound(holder, model, position);\n  }\n\n  void onModelBound(EpoxyViewHolder holder, EpoxyModel<?> model, int position,\n      @Nullable EpoxyModel<?> previouslyBoundModel) {\n    onModelBound(holder, model, position);\n  }\n\n  /**\n   * Called immediately after a model is bound to a view holder. Subclasses can override this if\n   * they want alerts on when a model is bound.\n   */\n  protected void onModelBound(EpoxyViewHolder holder, EpoxyModel<?> model, int position) {\n\n  }\n\n  /**\n   * Returns an object that manages the view holders currently bound to the RecyclerView. This\n   * object is mainly used by the base Epoxy adapter to save view states, but you may find it useful\n   * to help access views or models currently shown in the RecyclerView.\n   */\n  protected BoundViewHolders getBoundViewHolders() {\n    return boundViewHolders;\n  }\n\n  EpoxyModel<?> getModelForPosition(int position) {\n    return getCurrentModels().get(position);\n  }\n\n  @Override\n  public void onViewRecycled(EpoxyViewHolder holder) {\n    viewHolderState.save(holder);\n    boundViewHolders.remove(holder);\n\n    EpoxyModel<?> model = holder.getModel();\n    holder.unbind();\n    onModelUnbound(holder, model);\n  }\n\n  @CallSuper\n  @Override\n  public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {\n    // The last model is saved for optimization, but holding onto it can leak anything saved inside\n    // the model (like a click listener that references a Fragment). This is only needed during\n    // the viewholder creation phase, so it is safe to clear now.\n    viewTypeManager.lastModelForViewTypeLookup = null;\n  }\n\n  /**\n   * Called immediately after a model is unbound from a view holder. Subclasses can override this if\n   * they want alerts on when a model is unbound.\n   */\n  protected void onModelUnbound(EpoxyViewHolder holder, EpoxyModel<?> model) {\n\n  }\n\n  @CallSuper\n  @Override\n  public boolean onFailedToRecycleView(EpoxyViewHolder holder) {\n    //noinspection unchecked,rawtypes\n    return ((EpoxyModel) holder.getModel()).onFailedToRecycleView(holder.objectToBind());\n  }\n\n  @CallSuper\n  @Override\n  public void onViewAttachedToWindow(EpoxyViewHolder holder) {\n    //noinspection unchecked,rawtypes\n    ((EpoxyModel) holder.getModel()).onViewAttachedToWindow(holder.objectToBind());\n  }\n\n  @CallSuper\n  @Override\n  public void onViewDetachedFromWindow(EpoxyViewHolder holder) {\n    //noinspection unchecked,rawtypes\n    ((EpoxyModel) holder.getModel()).onViewDetachedFromWindow(holder.objectToBind());\n  }\n\n  public void onSaveInstanceState(Bundle outState) {\n    // Save the state of currently bound views first so they are included. Views that were\n    // scrolled off and unbound will already have had\n    // their state saved.\n    for (EpoxyViewHolder holder : boundViewHolders) {\n      viewHolderState.save(holder);\n    }\n\n    if (viewHolderState.size() > 0 && !hasStableIds()) {\n      throw new IllegalStateException(\"Must have stable ids when saving view holder state\");\n    }\n\n    outState.putParcelable(SAVED_STATE_ARG_VIEW_HOLDERS, viewHolderState);\n  }\n\n  public void onRestoreInstanceState(@Nullable Bundle inState) {\n    // To simplify things we enforce that state is restored before views are bound, otherwise it\n    // is more difficult to update view state once they are bound\n    if (boundViewHolders.size() > 0) {\n      throw new IllegalStateException(\n          \"State cannot be restored once views have been bound. It should be done before adding \"\n              + \"the adapter to the recycler view.\");\n    }\n\n    if (inState != null) {\n      viewHolderState = inState.getParcelable(SAVED_STATE_ARG_VIEW_HOLDERS);\n      if (viewHolderState == null) {\n        throw new IllegalStateException(\n            \"Tried to restore instance state, but onSaveInstanceState was never called.\");\n      }\n    }\n  }\n\n  /**\n   * Finds the position of the given model in the list. Doesn't use indexOf to avoid unnecessary\n   * equals() calls since we're looking for the same object instance.\n   *\n   * @return The position of the given model in the current models list, or -1 if the model can't be\n   * found.\n   */\n  protected int getModelPosition(EpoxyModel<?> model) {\n    int size = getCurrentModels().size();\n    for (int i = 0; i < size; i++) {\n      if (model == getCurrentModels().get(i)) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  /**\n   * For use with a grid layout manager - use this to get the {@link SpanSizeLookup} for models in\n   * this adapter. This will delegate span look up calls to each model's {@link\n   * EpoxyModel#getSpanSize(int, int, int)}. Make sure to also call {@link #setSpanCount(int)} so\n   * the span count is correct.\n   */\n  public SpanSizeLookup getSpanSizeLookup() {\n    return spanSizeLookup;\n  }\n\n  /**\n   * If you are using a grid layout manager you must call this to set the span count of the grid.\n   * This span count will be passed on to the models so models can choose what span count to be.\n   *\n   * @see #getSpanSizeLookup()\n   * @see EpoxyModel#getSpanSize(int, int, int)\n   */\n  public void setSpanCount(int spanCount) {\n    this.spanCount = spanCount;\n  }\n\n  public int getSpanCount() {\n    return spanCount;\n  }\n\n  public boolean isMultiSpan() {\n    return spanCount > 1;\n  }\n\n  //region Sticky header\n\n  /**\n   * Optional callback to setup the sticky view,\n   * by default it doesn't do anything.\n   * <p>\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public void setupStickyHeaderView(@NotNull View stickyHeader) {\n    // no-op\n  }\n\n  /**\n   * Optional callback to perform tear down operation on the\n   * sticky view, by default it doesn't do anything.\n   * <p>\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public void teardownStickyHeaderView(@NotNull View stickyHeader) {\n    // no-op\n  }\n\n  /**\n   * Called to check if the item at the position is a sticky item,\n   * by default returns false.\n   * <p>\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public boolean isStickyHeader(int position) {\n    return false;\n  }\n\n  //endregion\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/BaseEpoxyTouchCallback.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\ninterface BaseEpoxyTouchCallback<T extends EpoxyModel> {\n\n  /**\n   * Should return a composite flag which defines the enabled move directions in each state\n   * (idle, swiping, dragging) for the given model.\n   * <p>\n   * Return 0 to disable movement for the model.\n   *\n   * @param model           The model being targeted for movement.\n   * @param adapterPosition The current adapter position of the targeted model\n   * @see androidx.recyclerview.widget.ItemTouchHelper.Callback#getMovementFlags\n   */\n  int getMovementFlagsForModel(T model, int adapterPosition);\n\n  /**\n   * Called when the user interaction with a view is over and the view has\n   * completed its animation. This is a good place to clear all changes on the view that were done\n   * in other previous touch callbacks (such as on touch start, change, release, etc).\n   * <p>\n   * This is the last callback in the lifecycle of a touch event.\n   *\n   * @param model    The model whose view is being cleared.\n   * @param itemView The view being cleared.\n   */\n  void clearView(T model, View itemView);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/BoundViewHolders.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\n\nimport androidx.annotation.Nullable;\nimport androidx.collection.LongSparseArray;\n\n/** Helper class for keeping track of {@link EpoxyViewHolder}s that are currently bound. */\n@SuppressWarnings(\"WeakerAccess\")\npublic class BoundViewHolders implements Iterable<EpoxyViewHolder> {\n  private final LongSparseArray<EpoxyViewHolder> holders = new LongSparseArray<>();\n\n  @Nullable\n  public EpoxyViewHolder get(EpoxyViewHolder holder) {\n    return holders.get(holder.getItemId());\n  }\n\n  public void put(EpoxyViewHolder holder) {\n    holders.put(holder.getItemId(), holder);\n  }\n\n  public void remove(EpoxyViewHolder holder) {\n    holders.remove(holder.getItemId());\n  }\n\n  public int size() {\n    return holders.size();\n  }\n\n  @Override\n  public Iterator<EpoxyViewHolder> iterator() {\n    return new HolderIterator();\n  }\n\n  @Nullable\n  public EpoxyViewHolder getHolderForModel(EpoxyModel<?> model) {\n    return holders.get(model.id());\n  }\n\n  private class HolderIterator implements Iterator<EpoxyViewHolder> {\n    private int position = 0;\n\n    @Override\n    public boolean hasNext() {\n      return position < holders.size();\n    }\n\n    @Override\n    public EpoxyViewHolder next() {\n      if (!hasNext()) {\n        throw new NoSuchElementException();\n      }\n      return holders.valueAt(position++);\n    }\n\n    @Override\n    public void remove() {\n      throw new UnsupportedOperationException();\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/Carousel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.util.DisplayMetrics;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.airbnb.epoxy.ModelView.Size;\nimport com.airbnb.viewmodeladapter.R;\n\nimport java.util.List;\n\nimport androidx.annotation.DimenRes;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.Px;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.LinearSnapHelper;\nimport androidx.recyclerview.widget.SnapHelper;\n\n/**\n * <i>This feature is in Beta - please report bugs, feature requests, or other feedback at\n * https://github.com/airbnb/epoxy by creating a new issue. Thanks!</i>\n *\n * <p>This is intended as a plug and play \"Carousel\" view - a Recyclerview with horizontal\n * scrolling. It comes with common defaults and performance optimizations and can be either used as\n * a top level RecyclerView, or nested within a vertical recyclerview.\n *\n * <p>This class provides:\n *\n * <p>1. Automatic integration with Epoxy. A {@link CarouselModel_} is generated from this class,\n * which you can use in your EpoxyController. Just call {@link #setModels(List)} to provide the list\n * of models to show in the carousel.\n *\n * <p>2. Default padding for carousel peeking, and an easy way to change this padding - {@link\n * #setPaddingDp(int)}\n *\n * <p>3. Easily control how many items are shown on screen in the carousel at a time - {@link\n * #setNumViewsToShowOnScreen(float)}\n *\n * <p>4. Easy snap support. By default a {@link LinearSnapHelper} is used, but you can set a global\n * default for all Carousels with {@link #setDefaultGlobalSnapHelperFactory(SnapHelperFactory)}\n *\n * <p>5. All of the benefits of {@link EpoxyRecyclerView}\n *\n * <p>If you need further flexibility you can subclass this view to change its width, height,\n * scrolling direction, etc. You can annotate a subclass with {@link ModelView} to generate a new\n * EpoxyModel.\n */\n@ModelView(saveViewState = true, autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\npublic class Carousel extends EpoxyRecyclerView {\n  public static final int NO_VALUE_SET = -1;\n\n  private static SnapHelperFactory defaultGlobalSnapHelperFactory =\n      new SnapHelperFactory() {\n\n        @Override\n        @NonNull\n        public SnapHelper buildSnapHelper(Context context) {\n          return new LinearSnapHelper();\n        }\n      };\n\n  @Dimension(unit = Dimension.DP)\n  private static int defaultSpacingBetweenItemsDp = 8;\n\n  private float numViewsToShowOnScreen;\n\n  public Carousel(Context context) {\n    super(context);\n  }\n\n  public Carousel(Context context, @Nullable AttributeSet attrs) {\n    super(context, attrs);\n  }\n\n  public Carousel(Context context, @Nullable AttributeSet attrs, int defStyle) {\n    super(context, attrs, defStyle);\n  }\n\n  @Override\n  protected void init() {\n    super.init();\n    // When used as a model the padding can't be set via xml so we set it programmatically\n    int defaultSpacingDp = getDefaultSpacingBetweenItemsDp();\n\n    if (defaultSpacingDp >= 0) {\n      setItemSpacingDp(defaultSpacingDp);\n\n      if (getPaddingLeft() == 0\n          && getPaddingRight() == 0\n          && getPaddingTop() == 0\n          && getPaddingBottom() == 0) {\n        // Use the item spacing as the default padding if no other padding has been set\n        setPaddingDp(defaultSpacingDp);\n      }\n    }\n\n    SnapHelperFactory snapHelperFactory = getSnapHelperFactory();\n    if (snapHelperFactory != null) {\n      snapHelperFactory.buildSnapHelper(getContext()).attachToRecyclerView(this);\n    }\n\n    // Carousels will be detached when their parent recyclerview is\n    setRemoveAdapterWhenDetachedFromWindow(false);\n  }\n\n  /**\n   * Return a {@link SnapHelperFactory} instance to use with this Carousel. The {@link SnapHelper}\n   * created by the factory will be attached to this Carousel on view creation. Return null for no\n   * snap helper to be attached automatically.\n   */\n  @Nullable\n  protected SnapHelperFactory getSnapHelperFactory() {\n    return defaultGlobalSnapHelperFactory;\n  }\n\n  /**\n   * Set a {@link SnapHelperFactory} instance to use with all Carousels by default. The {@link\n   * SnapHelper} created by the factory will be attached to each Carousel on view creation. Set null\n   * for no snap helper to be attached automatically.\n   *\n   * <p>A Carousel subclass can implement {@link #getSnapHelperFactory()} to override the global\n   * default.\n   */\n  public static void setDefaultGlobalSnapHelperFactory(@Nullable SnapHelperFactory factory) {\n    defaultGlobalSnapHelperFactory = factory;\n  }\n\n  @ModelProp\n  @Override\n  public void setHasFixedSize(boolean hasFixedSize) {\n    super.setHasFixedSize(hasFixedSize);\n  }\n\n  /**\n   * Set the number of views to show on screen in this carousel at a time, partial numbers are\n   * allowed.\n   *\n   * <p>This is useful where you want to easily control for the number of items on screen,\n   * regardless of screen size. For example, you could set this to 1.2f so that one view is shown in\n   * full and 20% of the next view \"peeks\" from the edge to indicate that there is more content to\n   * scroll to.\n   *\n   * <p>Another pattern is setting a different view count depending on whether the device is phone\n   * or tablet.\n   *\n   * <p>Additionally, if a LinearLayoutManager is used this value will be forwarded to {@link\n   * LinearLayoutManager#setInitialPrefetchItemCount(int)} as a performance optimization.\n   *\n   * <p>If you want to only change the prefetch count without changing the view size you can simply\n   * use {@link #setInitialPrefetchItemCount(int)}\n   */\n  @ModelProp(group = \"prefetch\")\n  public void setNumViewsToShowOnScreen(float viewCount) {\n    numViewsToShowOnScreen = viewCount;\n    setInitialPrefetchItemCount((int) Math.ceil(viewCount));\n  }\n\n  /**\n   * @return The number of views to show on screen in this carousel at a time.\n   */\n  public float getNumViewsToShowOnScreen() {\n      return numViewsToShowOnScreen;\n  }\n\n  /**\n   * If you are using a Linear or Grid layout manager you can use this to set the item prefetch\n   * count. Only use this if you are not using {@link #setNumViewsToShowOnScreen(float)}\n   *\n   * @see #setNumViewsToShowOnScreen(float)\n   * @see LinearLayoutManager#setInitialPrefetchItemCount(int)\n   */\n  @ModelProp(group = \"prefetch\")\n  public void setInitialPrefetchItemCount(int numItemsToPrefetch) {\n    if (numItemsToPrefetch < 0) {\n      throw new IllegalStateException(\"numItemsToPrefetch must be greater than 0\");\n    }\n\n    // Use the linearlayoutmanager default of 2 if the user did not specify one\n    int prefetchCount = numItemsToPrefetch == 0 ? 2 : numItemsToPrefetch;\n\n    LayoutManager layoutManager = getLayoutManager();\n    if (layoutManager instanceof LinearLayoutManager) {\n      ((LinearLayoutManager) layoutManager).setInitialPrefetchItemCount(prefetchCount);\n    }\n  }\n\n  @Override\n  public void onChildAttachedToWindow(View child) {\n    if (numViewsToShowOnScreen > 0) {\n      ViewGroup.LayoutParams childLayoutParams = child.getLayoutParams();\n      child.setTag(R.id.epoxy_recycler_view_child_initial_size_id, childLayoutParams.width);\n\n      int itemSpacingPx = getSpacingDecorator().getPxBetweenItems();\n      int spaceBetweenItems = 0;\n      if (itemSpacingPx > 0) {\n        // The item decoration space is not counted in the width of the view\n        spaceBetweenItems = (int) (itemSpacingPx * numViewsToShowOnScreen);\n      }\n\n      boolean isScrollingHorizontally = getLayoutManager().canScrollHorizontally();\n      int itemSizeInScrollingDirection =\n          (int)\n              ((getSpaceForChildren(isScrollingHorizontally) - spaceBetweenItems)\n                  / numViewsToShowOnScreen);\n\n      if (isScrollingHorizontally) {\n        childLayoutParams.width = itemSizeInScrollingDirection;\n      } else {\n        childLayoutParams.height = itemSizeInScrollingDirection;\n      }\n\n      // We don't need to request layout because the layout manager will do that for us next\n    }\n  }\n\n  private int getSpaceForChildren(boolean horizontal) {\n    if (horizontal) {\n      return getTotalWidthPx(this)\n          - getPaddingLeft()\n          - (getClipToPadding() ? getPaddingRight() : 0);\n      // If child views will be showing through padding than we include just one side of padding\n      // since when the list is at position 0 only the child towards the end of the list will show\n      // through the padding.\n    } else {\n      return getTotalHeightPx(this)\n          - getPaddingTop()\n          - (getClipToPadding() ? getPaddingBottom() : 0);\n    }\n  }\n\n  @Px\n  private static int getTotalWidthPx(View view) {\n    if (view.getWidth() > 0) {\n      // Can only get a width if we are laid out\n      return view.getWidth();\n    }\n\n    if (view.getMeasuredWidth() > 0) {\n      return view.getMeasuredWidth();\n    }\n\n    // Fall back to assuming we want the full screen width\n    DisplayMetrics metrics = view.getContext().getResources().getDisplayMetrics();\n    return metrics.widthPixels;\n  }\n\n  @Px\n  private static int getTotalHeightPx(View view) {\n    if (view.getHeight() > 0) {\n      return view.getHeight();\n    }\n\n    if (view.getMeasuredHeight() > 0) {\n      return view.getMeasuredHeight();\n    }\n\n    // Fall back to assuming we want the full screen width\n    DisplayMetrics metrics = view.getContext().getResources().getDisplayMetrics();\n    return metrics.heightPixels;\n  }\n\n  @Override\n  public void onChildDetachedFromWindow(View child) {\n    // Restore the view width that existed before we modified it\n    Object initialWidth = child.getTag(R.id.epoxy_recycler_view_child_initial_size_id);\n\n    if (initialWidth instanceof Integer) {\n      ViewGroup.LayoutParams params = child.getLayoutParams();\n      params.width = (int) initialWidth;\n      child.setTag(R.id.epoxy_recycler_view_child_initial_size_id, null);\n      // No need to request layout since the view is unbound and not attached to window\n    }\n  }\n\n  /**\n   * Set a global default to use as the item spacing for all Carousels. Set to 0 for no item\n   * spacing.\n   */\n  public static void setDefaultItemSpacingDp(@Dimension(unit = Dimension.DP) int dp) {\n    defaultSpacingBetweenItemsDp = dp;\n  }\n\n  /**\n   * Return the item spacing to use in this carousel, or 0 for no spacing.\n   *\n   * <p>By default this uses the global default set in {@link #setDefaultItemSpacingDp(int)}, but\n   * subclasses can override this to specify their own value.\n   */\n  @Dimension(unit = Dimension.DP)\n  protected int getDefaultSpacingBetweenItemsDp() {\n    return defaultSpacingBetweenItemsDp;\n  }\n\n  /**\n   * Set a dimension resource to specify the padding value to use on each side of the carousel and\n   * in between carousel items.\n   */\n  @ModelProp(group = \"padding\")\n  public void setPaddingRes(@DimenRes int paddingRes) {\n    int px = resToPx(paddingRes);\n    setPadding(px, px, px, px);\n    setItemSpacingPx(px);\n  }\n\n  /**\n   * Set a DP value to use as the padding on each side of the carousel and in between carousel\n   * items.\n   *\n   * <p>The default as the value returned by {@link #getDefaultSpacingBetweenItemsDp()}\n   */\n  @ModelProp(defaultValue = \"NO_VALUE_SET\", group = \"padding\")\n  public void setPaddingDp(@Dimension(unit = Dimension.DP) int paddingDp) {\n    int px = dpToPx(paddingDp != NO_VALUE_SET ? paddingDp : getDefaultSpacingBetweenItemsDp());\n    setPadding(px, px, px, px);\n    setItemSpacingPx(px);\n  }\n\n  /**\n   * Use the {@link Padding} class to specify individual padding values for each side of the\n   * carousel, as well as item spacing.\n   *\n   * <p>A value of null will set all padding and item spacing to 0.\n   */\n  @ModelProp(group = \"padding\")\n  public void setPadding(@Nullable Padding padding) {\n    if (padding == null) {\n      setPaddingDp(0);\n    } else if (padding.paddingType == Padding.PaddingType.PX) {\n      setPadding(padding.left, padding.top, padding.right, padding.bottom);\n      setItemSpacingPx(padding.itemSpacing);\n    } else if (padding.paddingType == Padding.PaddingType.DP) {\n      setPadding(\n          dpToPx(padding.left), dpToPx(padding.top), dpToPx(padding.right), dpToPx(padding.bottom));\n      setItemSpacingPx(dpToPx(padding.itemSpacing));\n    } else if (padding.paddingType == Padding.PaddingType.RESOURCE) {\n      setPadding(\n          resToPx(padding.left),\n          resToPx(padding.top),\n          resToPx(padding.right),\n          resToPx(padding.bottom));\n      setItemSpacingPx(resToPx(padding.itemSpacing));\n    }\n  }\n\n  /**\n   * Used to specify individual padding values programmatically.\n   *\n   * @see #setPadding(Padding)\n   */\n  public static class Padding {\n    public final int left;\n    public final int top;\n    public final int right;\n    public final int bottom;\n    public final int itemSpacing;\n    public final PaddingType paddingType;\n\n    enum PaddingType {\n      PX,\n      DP,\n      RESOURCE\n    }\n\n    /**\n     * @param paddingRes Padding as dimension resource.\n     * @param itemSpacingRes Space as dimension resource to add between each carousel item. Will be\n     *     implemented via an item decoration.\n     */\n    public static Padding resource(@DimenRes int paddingRes, @DimenRes int itemSpacingRes) {\n      return new Padding(\n          paddingRes, paddingRes, paddingRes, paddingRes, itemSpacingRes, PaddingType.RESOURCE);\n    }\n\n    /**\n     * @param leftRes Left padding as dimension resource.\n     * @param topRes Top padding as dimension resource.\n     * @param rightRes Right padding as dimension resource.\n     * @param bottomRes Bottom padding as dimension resource.\n     * @param itemSpacingRes Space as dimension resource to add between each carousel item. Will be\n     *     implemented via an item decoration.\n     */\n    public static Padding resource(\n        @DimenRes int leftRes,\n        @DimenRes int topRes,\n        @DimenRes int rightRes,\n        @DimenRes int bottomRes,\n        @DimenRes int itemSpacingRes) {\n      return new Padding(\n          leftRes, topRes, rightRes, bottomRes, itemSpacingRes, PaddingType.RESOURCE);\n    }\n\n    /**\n     * @param paddingDp Padding in dp.\n     * @param itemSpacingDp Space in dp to add between each carousel item. Will be implemented via\n     *     an item decoration.\n     */\n    public static Padding dp(\n        @Dimension(unit = Dimension.DP) int paddingDp,\n        @Dimension(unit = Dimension.DP) int itemSpacingDp) {\n      return new Padding(paddingDp, paddingDp, paddingDp, paddingDp, itemSpacingDp, PaddingType.DP);\n    }\n\n    /**\n     * @param leftDp Left padding in dp.\n     * @param topDp Top padding in dp.\n     * @param rightDp Right padding in dp.\n     * @param bottomDp Bottom padding in dp.\n     * @param itemSpacingDp Space in dp to add between each carousel item. Will be implemented via\n     *     an item decoration.\n     */\n    public static Padding dp(\n        @Dimension(unit = Dimension.DP) int leftDp,\n        @Dimension(unit = Dimension.DP) int topDp,\n        @Dimension(unit = Dimension.DP) int rightDp,\n        @Dimension(unit = Dimension.DP) int bottomDp,\n        @Dimension(unit = Dimension.DP) int itemSpacingDp) {\n      return new Padding(leftDp, topDp, rightDp, bottomDp, itemSpacingDp, PaddingType.DP);\n    }\n\n    /**\n     * @param paddingPx Padding in pixels to add on all sides of the carousel\n     * @param itemSpacingPx Space in pixels to add between each carousel item. Will be implemented\n     *     via an item decoration.\n     */\n    public Padding(@Px int paddingPx, @Px int itemSpacingPx) {\n      this(paddingPx, paddingPx, paddingPx, paddingPx, itemSpacingPx, PaddingType.PX);\n    }\n\n    /**\n     * @param leftPx Left padding in pixels.\n     * @param topPx Top padding in pixels.\n     * @param rightPx Right padding in pixels.\n     * @param bottomPx Bottom padding in pixels.\n     * @param itemSpacingPx Space in pixels to add between each carousel item. Will be implemented\n     *     via an item decoration.\n     */\n    public Padding(\n        @Px int leftPx, @Px int topPx, @Px int rightPx, @Px int bottomPx, @Px int itemSpacingPx) {\n      this(leftPx, topPx, rightPx, bottomPx, itemSpacingPx, PaddingType.PX);\n    }\n\n    /**\n     * @param left Left padding.\n     * @param top Top padding.\n     * @param right Right padding.\n     * @param bottom Bottom padding.\n     * @param itemSpacing Space to add between each carousel item. Will be implemented via an item\n     *     decoration.\n     * @param paddingType Unit / Type of the given paddings/ itemspacing.\n     */\n    private Padding(\n        int left, int top, int right, int bottom, int itemSpacing, PaddingType paddingType) {\n\n      this.left = left;\n      this.top = top;\n      this.right = right;\n      this.bottom = bottom;\n      this.itemSpacing = itemSpacing;\n      this.paddingType = paddingType;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      if (this == o) {\n        return true;\n      }\n      if (o == null || getClass() != o.getClass()) {\n        return false;\n      }\n\n      Padding padding = (Padding) o;\n\n      if (left != padding.left) {\n        return false;\n      }\n      if (top != padding.top) {\n        return false;\n      }\n      if (right != padding.right) {\n        return false;\n      }\n      if (bottom != padding.bottom) {\n        return false;\n      }\n      return itemSpacing == padding.itemSpacing;\n    }\n\n    @Override\n    public int hashCode() {\n      int result = left;\n      result = 31 * result + top;\n      result = 31 * result + right;\n      result = 31 * result + bottom;\n      result = 31 * result + itemSpacing;\n      return result;\n    }\n  }\n\n  @ModelProp\n  public void setModels(@NonNull List<? extends EpoxyModel<?>> models) {\n    super.setModels(models);\n  }\n\n  @OnViewRecycled\n  public void clear() {\n    super.clear();\n  }\n\n  /** Provide a SnapHelper implementation you want to use with a Carousel. */\n  public abstract static class SnapHelperFactory {\n    /**\n     * Create and return a new instance of a {@link androidx.recyclerview.widget.SnapHelper} for use\n     * with a Carousel.\n     */\n    @NonNull\n    public abstract SnapHelper buildSnapHelper(Context context);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ControllerHelper.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\n/**\n * A helper class for {@link EpoxyController} to handle {@link\n * com.airbnb.epoxy.AutoModel} models. This is only implemented by the generated classes created the\n * annotation processor.\n */\npublic abstract class ControllerHelper<T extends EpoxyController> {\n  public abstract void resetAutoModels();\n\n  protected void validateModelHashCodesHaveNotChanged(T controller) {\n    List<EpoxyModel<?>> currentModels = controller.getAdapter().getCopyOfModels();\n\n    for (int i = 0; i < currentModels.size(); i++) {\n      EpoxyModel model = currentModels.get(i);\n      model.validateStateHasNotChangedSinceAdded(\n          \"Model has changed since it was added to the controller.\", i);\n    }\n  }\n\n  protected void setControllerToStageTo(EpoxyModel<?> model, T controller) {\n    model.controllerToStageTo = controller;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ControllerHelperLookup.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport androidx.annotation.Nullable;\n\n/**\n * Looks up a generated {@link ControllerHelper} implementation for a given adapter.\n * If the adapter has no {@link com.airbnb.epoxy.AutoModel} models then a No-Op implementation will\n * be returned.\n */\nclass ControllerHelperLookup {\n  private static final String GENERATED_HELPER_CLASS_SUFFIX = \"_EpoxyHelper\";\n  private static final Map<Class<?>, Constructor<?>> BINDINGS = new LinkedHashMap<>();\n  private static final NoOpControllerHelper NO_OP_CONTROLLER_HELPER = new NoOpControllerHelper();\n\n  static ControllerHelper getHelperForController(EpoxyController controller) {\n    Constructor<?> constructor = findConstructorForClass(controller.getClass());\n    if (constructor == null) {\n      return NO_OP_CONTROLLER_HELPER;\n    }\n\n    try {\n      return (ControllerHelper) constructor.newInstance(controller);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InstantiationException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InvocationTargetException e) {\n      Throwable cause = e.getCause();\n      if (cause instanceof RuntimeException) {\n        throw (RuntimeException) cause;\n      }\n      if (cause instanceof Error) {\n        throw (Error) cause;\n      }\n      throw new RuntimeException(\"Unable to get Epoxy helper class.\", cause);\n    }\n  }\n\n  @Nullable\n  private static Constructor<?> findConstructorForClass(Class<?> controllerClass) {\n    Constructor<?> helperCtor = BINDINGS.get(controllerClass);\n    if (helperCtor != null || BINDINGS.containsKey(controllerClass)) {\n      return helperCtor;\n    }\n\n    String clsName = controllerClass.getName();\n    if (clsName.startsWith(\"android.\") || clsName.startsWith(\"java.\")) {\n      return null;\n    }\n\n    try {\n      Class<?> bindingClass = Class.forName(clsName + GENERATED_HELPER_CLASS_SUFFIX);\n      //noinspection unchecked\n      helperCtor = bindingClass.getConstructor(controllerClass);\n    } catch (ClassNotFoundException e) {\n      helperCtor = findConstructorForClass(controllerClass.getSuperclass());\n    } catch (NoSuchMethodException e) {\n      throw new RuntimeException(\"Unable to find Epoxy Helper constructor for \" + clsName, e);\n    }\n    BINDINGS.put(controllerClass, helperCtor);\n    return helperCtor;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ControllerModelList.java",
    "content": "package com.airbnb.epoxy;\n\n/**\n * This ArrayList subclass enforces that no changes are made to the list after {@link #freeze()} is\n * called. This prevents model interceptors from storing the list and trying to change it later. We\n * could copy the list before diffing, but that would waste memory to make the copy for every\n * buildModels cycle, plus the interceptors could still try to modify the list and be confused about\n * why it doesn't do anything.\n */\nclass ControllerModelList extends ModelList {\n\n  private static final ModelListObserver OBSERVER = new ModelListObserver() {\n    @Override\n    public void onItemRangeInserted(int positionStart, int itemCount) {\n      throw new IllegalStateException(\n          \"Models cannot be changed once they are added to the controller\");\n    }\n\n    @Override\n    public void onItemRangeRemoved(int positionStart, int itemCount) {\n      throw new IllegalStateException(\n          \"Models cannot be changed once they are added to the controller\");\n    }\n  };\n\n  ControllerModelList(int expectedModelCount) {\n    super(expectedModelCount);\n    pauseNotifications();\n  }\n\n  void freeze() {\n    setObserver(OBSERVER);\n    resumeNotifications();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/DebugTimer.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.util.Log;\n\nclass DebugTimer implements Timer {\n\n  private final String tag;\n  private long startTime;\n  private String sectionName;\n\n  DebugTimer(String tag) {\n    this.tag = tag;\n    reset();\n  }\n\n  private void reset() {\n    startTime = -1;\n    sectionName = null;\n  }\n\n  @Override\n  public void start(String sectionName) {\n    if (startTime != -1) {\n      throw new IllegalStateException(\"Timer was already started\");\n    }\n\n    startTime = System.nanoTime();\n    this.sectionName = sectionName;\n  }\n\n  @Override\n  public void stop() {\n    if (startTime == -1) {\n      throw new IllegalStateException(\"Timer was not started\");\n    }\n\n    float durationMs = (System.nanoTime() - startTime) / 1000000f;\n    Log.d(tag, String.format(sectionName + \": %.3fms\", durationMs));\n    reset();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/DiffHelper.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\n\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * Helper to track changes in the models list.\n */\nclass DiffHelper {\n  private ArrayList<ModelState> oldStateList = new ArrayList<>();\n  // Using a HashMap instead of a LongSparseArray to\n  // have faster look up times at the expense of memory\n  private Map<Long, ModelState> oldStateMap = new HashMap<>();\n  private ArrayList<ModelState> currentStateList = new ArrayList<>();\n  private Map<Long, ModelState> currentStateMap = new HashMap<>();\n  private final BaseEpoxyAdapter adapter;\n  private final boolean immutableModels;\n\n\n  DiffHelper(BaseEpoxyAdapter adapter, boolean immutableModels) {\n    this.adapter = adapter;\n    this.immutableModels = immutableModels;\n    adapter.registerAdapterDataObserver(observer);\n  }\n\n  private final RecyclerView.AdapterDataObserver observer = new RecyclerView.AdapterDataObserver() {\n    @Override\n    public void onChanged() {\n      throw new UnsupportedOperationException(\n          \"Diffing is enabled. You should use notifyModelsChanged instead of notifyDataSetChanged\");\n    }\n\n    @Override\n    public void onItemRangeChanged(int positionStart, int itemCount) {\n      for (int i = positionStart; i < positionStart + itemCount; i++) {\n        currentStateList.get(i).hashCode = adapter.getCurrentModels().get(i).hashCode();\n      }\n    }\n\n    @Override\n    public void onItemRangeInserted(int positionStart, int itemCount) {\n      if (itemCount == 0) {\n        // no-op\n        return;\n      }\n\n      if (itemCount == 1 || positionStart == currentStateList.size()) {\n        for (int i = positionStart; i < positionStart + itemCount; i++) {\n          currentStateList.add(i, createStateForPosition(i));\n        }\n      } else {\n        // Add in a batch since multiple insertions to the middle of the list are slow\n        List<ModelState> newModels = new ArrayList<>(itemCount);\n        for (int i = positionStart; i < positionStart + itemCount; i++) {\n          newModels.add(createStateForPosition(i));\n        }\n\n        currentStateList.addAll(positionStart, newModels);\n      }\n\n      // Update positions of affected items\n      int size = currentStateList.size();\n      for (int i = positionStart + itemCount; i < size; i++) {\n        currentStateList.get(i).position += itemCount;\n      }\n    }\n\n    @Override\n    public void onItemRangeRemoved(int positionStart, int itemCount) {\n      if (itemCount == 0) {\n        // no-op\n        return;\n      }\n\n      List<ModelState> modelsToRemove =\n          currentStateList.subList(positionStart, positionStart + itemCount);\n      for (ModelState model : modelsToRemove) {\n        currentStateMap.remove(model.id);\n      }\n      modelsToRemove.clear();\n\n      // Update positions of affected items\n      int size = currentStateList.size();\n      for (int i = positionStart; i < size; i++) {\n        currentStateList.get(i).position -= itemCount;\n      }\n    }\n\n    @Override\n    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\n      if (fromPosition == toPosition) {\n        // no-op\n        return;\n      }\n\n      if (itemCount != 1) {\n        throw new IllegalArgumentException(\"Moving more than 1 item at a time is not \"\n            + \"supported. Number of items moved: \" + itemCount);\n      }\n\n      ModelState model = currentStateList.remove(fromPosition);\n      model.position = toPosition;\n      currentStateList.add(toPosition, model);\n\n      if (fromPosition < toPosition) {\n        // shift the affected items left\n        for (int i = fromPosition; i < toPosition; i++) {\n          currentStateList.get(i).position--;\n        }\n      } else {\n        // shift the affected items right\n        for (int i = toPosition + 1; i <= fromPosition; i++) {\n          currentStateList.get(i).position++;\n        }\n      }\n    }\n  };\n\n  /**\n   * Set the current list of models. The diff callbacks will be notified of the changes between the\n   * current list and the last list that was set.\n   */\n  void notifyModelChanges() {\n    UpdateOpHelper updateOpHelper = new UpdateOpHelper();\n\n    buildDiff(updateOpHelper);\n\n    // Send out the proper notify calls for the diff. We remove our\n    // observer first so that we don't react to our own notify calls\n    adapter.unregisterAdapterDataObserver(observer);\n    notifyChanges(updateOpHelper);\n    adapter.registerAdapterDataObserver(observer);\n  }\n\n  private void notifyChanges(UpdateOpHelper opHelper) {\n    for (UpdateOp op : opHelper.opList) {\n      switch (op.type) {\n        case UpdateOp.ADD:\n          adapter.notifyItemRangeInserted(op.positionStart, op.itemCount);\n          break;\n        case UpdateOp.MOVE:\n          adapter.notifyItemMoved(op.positionStart, op.itemCount);\n          break;\n        case UpdateOp.REMOVE:\n          adapter.notifyItemRangeRemoved(op.positionStart, op.itemCount);\n          break;\n        case UpdateOp.UPDATE:\n          if (immutableModels && op.payloads != null) {\n            adapter.notifyItemRangeChanged(op.positionStart, op.itemCount,\n                new DiffPayload(op.payloads));\n          } else {\n            adapter.notifyItemRangeChanged(op.positionStart, op.itemCount);\n          }\n          break;\n        default:\n          throw new IllegalArgumentException(\"Unknown type: \" + op.type);\n      }\n    }\n  }\n\n  /**\n   * Create a list of operations that define the difference between {@link #oldStateList} and {@link\n   * #currentStateList}.\n   */\n  private UpdateOpHelper buildDiff(UpdateOpHelper updateOpHelper) {\n    prepareStateForDiff();\n\n    // The general approach is to first search for removals, then additions, and lastly changes.\n    // Focusing on one type of operation at a time makes it easy to coalesce batch changes.\n    // When we identify an operation and add it to the\n    // result list we update the positions of items in the oldStateList to reflect\n    // the change, this way subsequent operations will use the correct, updated positions.\n    collectRemovals(updateOpHelper);\n\n    // Only need to check for insertions if new list is bigger\n    boolean hasInsertions =\n        oldStateList.size() - updateOpHelper.getNumRemovals() != currentStateList.size();\n    if (hasInsertions) {\n      collectInsertions(updateOpHelper);\n    }\n\n    collectMoves(updateOpHelper);\n    collectChanges(updateOpHelper);\n\n    resetOldState();\n\n    return updateOpHelper;\n  }\n\n  private void resetOldState() {\n    oldStateList.clear();\n    oldStateMap.clear();\n  }\n\n  private void prepareStateForDiff() {\n    // We use a list of the models as well as a map by their id,\n    // so we can easily find them by both position and id\n\n    oldStateList.clear();\n    oldStateMap.clear();\n\n    // Swap the two lists so that we have a copy of the current state to calculate the next diff\n    ArrayList<ModelState> tempList = oldStateList;\n    oldStateList = currentStateList;\n    currentStateList = tempList;\n\n    Map<Long, ModelState> tempMap = oldStateMap;\n    oldStateMap = currentStateMap;\n    currentStateMap = tempMap;\n\n    // Remove all pairings in the old states so we can tell which of them were removed. The items\n    // that still exist in the new list will be paired when we build the current list state below\n    for (ModelState modelState : oldStateList) {\n      modelState.pair = null;\n    }\n\n    int modelCount = adapter.getCurrentModels().size();\n    currentStateList.ensureCapacity(modelCount);\n\n    for (int i = 0; i < modelCount; i++) {\n      currentStateList.add(createStateForPosition(i));\n    }\n  }\n\n  private ModelState createStateForPosition(int position) {\n    EpoxyModel<?> model = adapter.getCurrentModels().get(position);\n    model.addedToAdapter = true;\n    ModelState state = ModelState.build(model, position, immutableModels);\n\n    ModelState previousValue = currentStateMap.put(state.id, state);\n    if (previousValue != null) {\n      int previousPosition = previousValue.position;\n      EpoxyModel<?> previousModel = adapter.getCurrentModels().get(previousPosition);\n      throw new IllegalStateException(\"Two models have the same ID. ID's must be unique!\"\n          + \" Model at position \" + position + \": \" + model\n          + \" Model at position \" + previousPosition + \": \" + previousModel);\n    }\n\n    return state;\n  }\n\n  /**\n   * Find all removal operations and add them to the result list. The general strategy here is to\n   * walk through the {@link #oldStateList} and check for items that don't exist in the new list.\n   * Walking through it in order makes it easy to batch adjacent removals.\n   */\n  private void collectRemovals(UpdateOpHelper helper) {\n    for (ModelState state : oldStateList) {\n      // Update the position of the item to take into account previous removals,\n      // so that future operations will reference the correct position\n      state.position -= helper.getNumRemovals();\n\n      // This is our first time going through the list, so we\n      // look up the item with the matching id in the new\n      // list and hold a reference to it so that we can access it quickly in the future\n      state.pair = currentStateMap.get(state.id);\n      if (state.pair != null) {\n        state.pair.pair = state;\n        continue;\n      }\n\n      helper.remove(state.position);\n    }\n  }\n\n  /**\n   * Find all insertion operations and add them to the result list. The general strategy here is to\n   * walk through the {@link #currentStateList} and check for items that don't exist in the old\n   * list. Walking through it in order makes it easy to batch adjacent insertions.\n   */\n  private void collectInsertions(UpdateOpHelper helper) {\n    Iterator<ModelState> oldItemIterator = oldStateList.iterator();\n\n    for (ModelState itemToInsert : currentStateList) {\n      if (itemToInsert.pair != null) {\n        // Update the position of the next item in the old list to take any insertions into account\n        ModelState nextOldItem = getNextItemWithPair(oldItemIterator);\n        if (nextOldItem != null) {\n          nextOldItem.position += helper.getNumInsertions();\n        }\n        continue;\n      }\n\n      helper.add(itemToInsert.position);\n    }\n  }\n\n  /**\n   * Check if any items have had their values changed, batching if possible.\n   */\n  private void collectChanges(UpdateOpHelper helper) {\n    for (ModelState newItem : currentStateList) {\n      ModelState previousItem = newItem.pair;\n      if (previousItem == null) {\n        continue;\n      }\n\n      // We use equals when we know the models are immutable and available, otherwise we have to\n      // rely on the stored hashCode\n      boolean modelChanged;\n      if (immutableModels) {\n        // Make sure that the old model hasn't changed, otherwise comparing it with the new one\n        // won't be accurate.\n        if (previousItem.model.isDebugValidationEnabled()) {\n          previousItem.model\n              .validateStateHasNotChangedSinceAdded(\"Model was changed before it could be diffed.\",\n                  previousItem.position);\n        }\n\n        modelChanged = !previousItem.model.equals(newItem.model);\n      } else {\n        modelChanged = previousItem.hashCode != newItem.hashCode;\n      }\n\n      if (modelChanged) {\n        helper.update(newItem.position, previousItem.model);\n      }\n    }\n  }\n\n  /**\n   * Check which items have had a position changed. Recyclerview does not support batching these.\n   */\n  private void collectMoves(UpdateOpHelper helper) {\n    // This walks through both the new and old list simultaneous and checks for position changes.\n    Iterator<ModelState> oldItemIterator = oldStateList.iterator();\n    ModelState nextOldItem = null;\n\n    for (ModelState newItem : currentStateList) {\n      if (newItem.pair == null) {\n        // This item was inserted. However, insertions are done at the item's final position, and\n        // aren't smart about inserting at a different position to take future moves into account.\n        // As the old state list is updated to reflect moves, it needs to also consider insertions\n        // affected by those moves in order for the final change set to be correct\n        if (helper.moves.isEmpty()) {\n          // There have been no moves, so the item is still at it's correct position\n          continue;\n        } else {\n          // There have been moves, so the old list needs to take this inserted item\n          // into account. The old list doesn't have this item inserted into it\n          // (for optimization purposes), but we can create a pair for this item to\n          // track its position in the old list and move it back to its final position if necessary\n          newItem.pairWithSelf();\n        }\n      }\n\n      // We could iterate through only the new list and move each\n      // item that is out of place, however in cases such as moving the first item\n      // to the end, that strategy would do many moves to move all\n      // items up one instead of doing one move to move the first item to the end.\n      // To avoid this we compare the old item to the new item at\n      // each index and move the one that is farthest from its correct position.\n      // We only move on from a new item once its pair is placed in\n      // the correct spot. Since we move from start to end, all new items we've\n      // already iterated through are guaranteed to have their pair\n      // be already in the right spot, which won't be affected by future MOVEs.\n      if (nextOldItem == null) {\n        nextOldItem = getNextItemWithPair(oldItemIterator);\n\n        // We've already iterated through all old items and moved each\n        // item once. However, subsequent moves may have shifted an item out of\n        // its correct space once it was already moved. We finish\n        // iterating through all the new items to ensure everything is still correct\n        if (nextOldItem == null) {\n          nextOldItem = newItem.pair;\n        }\n      }\n\n      while (nextOldItem != null) {\n        // Make sure the positions are updated to the latest\n        // move operations before we calculate the next move\n        updateItemPosition(newItem.pair, helper.moves);\n        updateItemPosition(nextOldItem, helper.moves);\n\n        // The item is the same and its already in the correct place\n        if (newItem.id == nextOldItem.id && newItem.position == nextOldItem.position) {\n          nextOldItem = null;\n          break;\n        }\n\n        int newItemDistance = newItem.pair.position - newItem.position;\n        int oldItemDistance = nextOldItem.pair.position - nextOldItem.position;\n\n        // Both items are already in the correct position\n        if (newItemDistance == 0 && oldItemDistance == 0) {\n          nextOldItem = null;\n          break;\n        }\n\n        if (oldItemDistance > newItemDistance) {\n          helper.move(nextOldItem.position, nextOldItem.pair.position);\n\n          nextOldItem.position = nextOldItem.pair.position;\n          nextOldItem.lastMoveOp = helper.getNumMoves();\n\n          nextOldItem = getNextItemWithPair(oldItemIterator);\n        } else {\n          helper.move(newItem.pair.position, newItem.position);\n\n          newItem.pair.position = newItem.position;\n          newItem.pair.lastMoveOp = helper.getNumMoves();\n          break;\n        }\n      }\n    }\n  }\n\n  /**\n   * Apply the movement operations to the given item to update its position. Only applies the\n   * operations that have not been applied yet, and stores how many operations have been applied so\n   * we know which ones to apply next time.\n   */\n  private void updateItemPosition(ModelState item, List<UpdateOp> moveOps) {\n    int size = moveOps.size();\n\n    for (int i = item.lastMoveOp; i < size; i++) {\n      UpdateOp moveOp = moveOps.get(i);\n      int fromPosition = moveOp.positionStart;\n      int toPosition = moveOp.itemCount;\n\n      if (item.position > fromPosition && item.position <= toPosition) {\n        item.position--;\n      } else if (item.position < fromPosition && item.position >= toPosition) {\n        item.position++;\n      }\n    }\n\n    item.lastMoveOp = size;\n  }\n\n  /**\n   * Gets the next item in the list that has a pair, meaning it wasn't inserted or removed.\n   */\n  @Nullable\n  private ModelState getNextItemWithPair(Iterator<ModelState> iterator) {\n    ModelState nextItem = null;\n    while (nextItem == null && iterator.hasNext()) {\n      nextItem = iterator.next();\n\n      if (nextItem.pair == null) {\n        // Skip this one and go on to the next\n        nextItem = null;\n      }\n    }\n\n    return nextItem;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/DiffPayload.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\nimport androidx.collection.LongSparseArray;\n\n/**\n * A helper class for tracking changed models found by the {@link com.airbnb.epoxy.DiffHelper} to\n * be included as a payload in the\n * {@link androidx.recyclerview.widget.RecyclerView.Adapter#notifyItemChanged(int, Object)}\n * call.\n */\npublic class DiffPayload {\n  private final EpoxyModel<?> singleModel;\n  private final LongSparseArray<EpoxyModel<?>> modelsById;\n\n  DiffPayload(List<? extends EpoxyModel<?>> models) {\n    if (models.isEmpty()) {\n      throw new IllegalStateException(\"Models must not be empty\");\n    }\n\n    int modelCount = models.size();\n\n    if (modelCount == 1) {\n      // Optimize for the common case of only one model changed.\n      singleModel = models.get(0);\n      modelsById = null;\n    } else {\n      singleModel = null;\n      modelsById = new LongSparseArray<>(modelCount);\n      for (EpoxyModel<?> model : models) {\n        modelsById.put(model.id(), model);\n      }\n    }\n  }\n\n  public DiffPayload(EpoxyModel<?> changedItem) {\n    this(Collections.singletonList(changedItem));\n  }\n\n  /**\n   * Looks through the payloads list and returns the first model found with the given model id. This\n   * assumes that the payloads list will only contain objects of type {@link DiffPayload}, and will\n   * throw if an unexpected type is found.\n   */\n  @Nullable\n  public static EpoxyModel<?> getModelFromPayload(List<Object> payloads, long modelId) {\n    if (payloads.isEmpty()) {\n      return null;\n    }\n\n    for (Object payload : payloads) {\n      DiffPayload diffPayload = (DiffPayload) payload;\n\n      if (diffPayload.singleModel != null) {\n        if (diffPayload.singleModel.id() == modelId) {\n          return diffPayload.singleModel;\n        }\n      } else {\n        EpoxyModel<?> modelForId = diffPayload.modelsById.get(modelId);\n        if (modelForId != null) {\n          return modelForId;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  @VisibleForTesting\n  boolean equalsForTesting(DiffPayload that) {\n    if (singleModel != null) {\n      return that.singleModel == singleModel;\n    }\n\n    int thisSize = modelsById.size();\n    int thatSize = that.modelsById.size();\n\n    if (thisSize != thatSize) {\n      return false;\n    }\n\n    for (int i = 0; i < thisSize; i++) {\n      long thisKey = modelsById.keyAt(i);\n      long thatKey = that.modelsById.keyAt(i);\n\n      if (thisKey != thatKey) {\n        return false;\n      }\n\n      EpoxyModel<?> thisModel = modelsById.valueAt(i);\n      EpoxyModel<?> thatModel = that.modelsById.valueAt(i);\n      if (thisModel != thatModel) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/DiffResult.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.AdapterListUpdateCallback;\nimport androidx.recyclerview.widget.DiffUtil;\nimport androidx.recyclerview.widget.ListUpdateCallback;\nimport androidx.recyclerview.widget.RecyclerView.Adapter;\n\n/**\n * Wraps the result of {@link AsyncEpoxyDiffer#submitList(List)}.\n */\npublic class DiffResult {\n  @NonNull final List<? extends EpoxyModel<?>> previousModels;\n  @NonNull final List<? extends EpoxyModel<?>> newModels;\n\n  /**\n   * If this is non null it means the full differ ran and the result is contained\n   * in this object. If it is null, it means that either the old list or the new list was empty, so\n   * we can simply add all or clear all items and skipped running the full diffing.\n   */\n  @Nullable final DiffUtil.DiffResult differResult;\n\n  /** No changes were made to the models. */\n  static DiffResult noOp(@Nullable List<? extends EpoxyModel<?>> models) {\n    if (models == null) {\n      models = Collections.emptyList();\n    }\n    return new DiffResult(models, models, null);\n  }\n\n  /** The previous list was empty and the given non empty list was inserted. */\n  static DiffResult inserted(@NonNull List<? extends EpoxyModel<?>> newModels) {\n    //noinspection unchecked\n    return new DiffResult(Collections.EMPTY_LIST, newModels, null);\n  }\n\n  /** The previous list was non empty and the new list is empty. */\n  static DiffResult clear(@NonNull List<? extends EpoxyModel<?>> previousModels) {\n    //noinspection unchecked\n    return new DiffResult(previousModels, Collections.EMPTY_LIST, null);\n  }\n\n  /**\n   * The previous and new models are both non empty and a full differ pass was run on them.\n   * There may be no changes, however.\n   */\n  static DiffResult diff(\n      @NonNull List<? extends EpoxyModel<?>> previousModels,\n      @NonNull List<? extends EpoxyModel<?>> newModels,\n      @NonNull DiffUtil.DiffResult differResult\n  ) {\n    return new DiffResult(previousModels, newModels, differResult);\n  }\n\n  private DiffResult(\n      @NonNull List<? extends EpoxyModel<?>> previousModels,\n      @NonNull List<? extends EpoxyModel<?>> newModels,\n      @Nullable DiffUtil.DiffResult differResult\n  ) {\n    this.previousModels = previousModels;\n    this.newModels = newModels;\n    this.differResult = differResult;\n  }\n\n  public void dispatchTo(Adapter adapter) {\n    dispatchTo(new AdapterListUpdateCallback(adapter));\n  }\n\n  public void dispatchTo(ListUpdateCallback callback) {\n    if (differResult != null) {\n      differResult.dispatchUpdatesTo(callback);\n    } else if (newModels.isEmpty() && !previousModels.isEmpty()) {\n      callback.onRemoved(0, previousModels.size());\n    } else if (!newModels.isEmpty() && previousModels.isEmpty()) {\n      callback.onInserted(0, newModels.size());\n    }\n\n    // Else nothing changed!\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAdapter.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.annotation.Nullable;\n\n/**\n * Allows you to easily combine different view types in the same adapter, and handles view holder\n * creation, binding, and ids for you. Subclasses just need to add their desired {@link EpoxyModel}\n * objects and the rest is done automatically.\n * <p/>\n * {@link androidx.recyclerview.widget.RecyclerView.Adapter#setHasStableIds(boolean)} is set to true\n * by default, since {@link EpoxyModel} makes it easy to support unique ids. If you don't want to\n * support this then disable it in your base class (not recommended).\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic abstract class EpoxyAdapter extends BaseEpoxyAdapter {\n  private final HiddenEpoxyModel hiddenModel = new HiddenEpoxyModel();\n\n  /**\n   * Subclasses should modify this list as necessary with the models they want to show. Subclasses\n   * are responsible for notifying data changes whenever this list is changed.\n   */\n  protected final List<EpoxyModel<?>> models = new ModelList();\n  private DiffHelper diffHelper;\n\n  @Override\n  List<EpoxyModel<?>> getCurrentModels() {\n    return models;\n  }\n\n  /**\n   * Enables support for automatically notifying model changes via {@link #notifyModelsChanged()}.\n   * If used, this should be called in the constructor, before any models are changed.\n   *\n   * @see #notifyModelsChanged()\n   */\n  protected void enableDiffing() {\n    if (diffHelper != null) {\n      throw new IllegalStateException(\"Diffing was already enabled\");\n    }\n\n    if (!models.isEmpty()) {\n      throw new IllegalStateException(\"You must enable diffing before modifying models\");\n    }\n\n    if (!hasStableIds()) {\n      throw new IllegalStateException(\"You must have stable ids to use diffing\");\n    }\n\n    diffHelper = new DiffHelper(this, false);\n  }\n\n  @Override\n  EpoxyModel<?> getModelForPosition(int position) {\n    EpoxyModel<?> model = models.get(position);\n    return model.isShown() ? model : hiddenModel;\n  }\n\n  /**\n   * Intelligently notify item changes by comparing the current {@link #models} list against the\n   * previous so you don't have to micromanage notification calls yourself. This may be\n   * prohibitively slow for large model lists (in the hundreds), in which case consider doing\n   * notification calls yourself. If you use this, all your view models must implement {@link\n   * EpoxyModel#hashCode()} and {@link EpoxyModel#equals(Object)} to completely identify their\n   * state, so that changes to a model's content can be detected. Before using this you must enable\n   * it with {@link #enableDiffing()}, since keeping track of the model state adds extra computation\n   * time to all other data change notifications.\n   *\n   * @see #enableDiffing()\n   */\n\n  protected void notifyModelsChanged() {\n    if (diffHelper == null) {\n      throw new IllegalStateException(\"You must enable diffing before notifying models changed\");\n    }\n\n    diffHelper.notifyModelChanges();\n  }\n\n  /**\n   * Notify that the given model has had its data changed. It should only be called if the model\n   * retained the same position.\n   */\n  protected void notifyModelChanged(EpoxyModel<?> model) {\n    notifyModelChanged(model, null);\n  }\n\n  /**\n   * Notify that the given model has had its data changed. It should only be called if the model\n   * retained the same position.\n   */\n  protected void notifyModelChanged(EpoxyModel<?> model, @Nullable Object payload) {\n    int index = getModelPosition(model);\n    if (index != -1) {\n      notifyItemChanged(index, payload);\n    }\n  }\n\n  /**\n   * Adds the model to the end of the {@link #models} list and notifies that the item was inserted.\n   */\n  protected void addModel(EpoxyModel<?> modelToAdd) {\n    int initialSize = models.size();\n\n    pauseModelListNotifications();\n    models.add(modelToAdd);\n    resumeModelListNotifications();\n\n    notifyItemRangeInserted(initialSize, 1);\n  }\n\n  /**\n   * Adds the models to the end of the {@link #models} list and notifies that the items were\n   * inserted.\n   */\n  protected void addModels(EpoxyModel<?>... modelsToAdd) {\n    int initialSize = models.size();\n    int numModelsToAdd = modelsToAdd.length;\n\n    ((ModelList) models).ensureCapacity(initialSize + numModelsToAdd);\n\n    pauseModelListNotifications();\n    Collections.addAll(models, modelsToAdd);\n    resumeModelListNotifications();\n\n    notifyItemRangeInserted(initialSize, numModelsToAdd);\n  }\n\n  /**\n   * Adds the models to the end of the {@link #models} list and notifies that the items were\n   * inserted.\n   */\n  protected void addModels(Collection<? extends EpoxyModel<?>> modelsToAdd) {\n    int initialSize = models.size();\n\n    pauseModelListNotifications();\n    models.addAll(modelsToAdd);\n    resumeModelListNotifications();\n\n    notifyItemRangeInserted(initialSize, modelsToAdd.size());\n  }\n\n  /**\n   * Inserts the given model before the other in the {@link #models} list, and notifies that the\n   * item was inserted.\n   */\n  protected void insertModelBefore(EpoxyModel<?> modelToInsert, EpoxyModel<?> modelToInsertBefore) {\n    int targetIndex = getModelPosition(modelToInsertBefore);\n    if (targetIndex == -1) {\n      throw new IllegalStateException(\"Model is not added: \" + modelToInsertBefore);\n    }\n\n    pauseModelListNotifications();\n    models.add(targetIndex, modelToInsert);\n    resumeModelListNotifications();\n\n    notifyItemInserted(targetIndex);\n  }\n\n  /**\n   * Inserts the given model after the other in the {@link #models} list, and notifies that the item\n   * was inserted.\n   */\n  protected void insertModelAfter(EpoxyModel<?> modelToInsert, EpoxyModel<?> modelToInsertAfter) {\n    int modelIndex = getModelPosition(modelToInsertAfter);\n    if (modelIndex == -1) {\n      throw new IllegalStateException(\"Model is not added: \" + modelToInsertAfter);\n    }\n\n    int targetIndex = modelIndex + 1;\n    pauseModelListNotifications();\n    models.add(targetIndex, modelToInsert);\n    resumeModelListNotifications();\n\n    notifyItemInserted(targetIndex);\n  }\n\n  /**\n   * If the given model exists it is removed and an item removal is notified. Otherwise this does\n   * nothing.\n   */\n  protected void removeModel(EpoxyModel<?> model) {\n    int index = getModelPosition(model);\n    if (index != -1) {\n      pauseModelListNotifications();\n      models.remove(index);\n      resumeModelListNotifications();\n\n      notifyItemRemoved(index);\n    }\n  }\n\n  /**\n   * Removes all models\n   */\n  protected void removeAllModels() {\n    int numModelsRemoved = models.size();\n\n    pauseModelListNotifications();\n    models.clear();\n    resumeModelListNotifications();\n\n    notifyItemRangeRemoved(0, numModelsRemoved);\n  }\n\n  /**\n   * Removes all models after the given model, which must have already been added. An example use\n   * case is you want to keep a header but clear everything else, like in the case of refreshing\n   * data.\n   */\n  protected void removeAllAfterModel(EpoxyModel<?> model) {\n    List<EpoxyModel<?>> modelsToRemove = getAllModelsAfter(model);\n    int numModelsRemoved = modelsToRemove.size();\n    int initialModelCount = models.size();\n\n    // This is a sublist, so clearing it will clear the models in the original list\n    pauseModelListNotifications();\n    modelsToRemove.clear();\n    resumeModelListNotifications();\n\n    notifyItemRangeRemoved(initialModelCount - numModelsRemoved, numModelsRemoved);\n  }\n\n  /**\n   * Sets the visibility of the given model, and notifies that the item changed if the new\n   * visibility is different from the previous.\n   *\n   * @param model The model to show. It should already be added to the {@link #models} list.\n   * @param show  True to show the model, false to hide it.\n   */\n  protected void showModel(EpoxyModel<?> model, boolean show) {\n    if (model.isShown() == show) {\n      return;\n    }\n\n    model.show(show);\n    notifyModelChanged(model);\n  }\n\n  /**\n   * Shows the given model, and notifies that the item changed if the item wasn't already shown.\n   *\n   * @param model The model to show. It should already be added to the {@link #models} list.\n   */\n  protected void showModel(EpoxyModel<?> model) {\n    showModel(model, true);\n  }\n\n  /**\n   * Shows the given models, and notifies that each item changed if the item wasn't already shown.\n   *\n   * @param models The models to show. They should already be added to the {@link #models} list.\n   */\n  protected void showModels(EpoxyModel<?>... models) {\n    showModels(Arrays.asList(models));\n  }\n\n  /**\n   * Sets the visibility of the given models, and notifies that the items changed if the new\n   * visibility is different from the previous.\n   *\n   * @param models The models to show. They should already be added to the {@link #models} list.\n   * @param show   True to show the models, false to hide them.\n   */\n  protected void showModels(boolean show, EpoxyModel<?>... models) {\n    showModels(Arrays.asList(models), show);\n  }\n\n  /**\n   * Shows the given models, and notifies that each item changed if the item wasn't already shown.\n   *\n   * @param models The models to show. They should already be added to the {@link #models} list.\n   */\n  protected void showModels(Iterable<EpoxyModel<?>> models) {\n    showModels(models, true);\n  }\n\n  /**\n   * Sets the visibility of the given models, and notifies that the items changed if the new\n   * visibility is different from the previous.\n   *\n   * @param models The models to show. They should already be added to the {@link #models} list.\n   * @param show   True to show the models, false to hide them.\n   */\n  protected void showModels(Iterable<EpoxyModel<?>> models, boolean show) {\n    for (EpoxyModel<?> model : models) {\n      showModel(model, show);\n    }\n  }\n\n  /**\n   * Hides the given model, and notifies that the item changed if the item wasn't already hidden.\n   *\n   * @param model The model to hide. This should already be added to the {@link #models} list.\n   */\n  protected void hideModel(EpoxyModel<?> model) {\n    showModel(model, false);\n  }\n\n  /**\n   * Hides the given models, and notifies that each item changed if the item wasn't already hidden.\n   *\n   * @param models The models to hide. They should already be added to the {@link #models} list.\n   */\n  protected void hideModels(Iterable<EpoxyModel<?>> models) {\n    showModels(models, false);\n  }\n\n  /**\n   * Hides the given models, and notifies that each item changed if the item wasn't already hidden.\n   *\n   * @param models The models to hide. They should already be added to the {@link #models} list.\n   */\n  protected void hideModels(EpoxyModel<?>... models) {\n    hideModels(Arrays.asList(models));\n  }\n\n  /**\n   * Hides all models currently located after the given model in the {@link #models} list.\n   *\n   * @param model The model after which to hide. It must exist in the {@link #models} list.\n   */\n  protected void hideAllAfterModel(EpoxyModel<?> model) {\n    hideModels(getAllModelsAfter(model));\n  }\n\n  /**\n   * Returns a sub list of all items in {@link #models} that occur after the given model. This list\n   * is backed by the original models list, any changes to the returned list will be reflected in\n   * the original {@link #models} list.\n   *\n   * @param model Must exist in {@link #models}.\n   */\n  protected List<EpoxyModel<?>> getAllModelsAfter(EpoxyModel<?> model) {\n    int index = getModelPosition(model);\n    if (index == -1) {\n      throw new IllegalStateException(\"Model is not added: \" + model);\n    }\n    return models.subList(index + 1, models.size());\n  }\n\n  /**\n   * We pause the list's notifications when we modify models internally, since we already do the\n   * proper adapter notifications for those modifications. By pausing these list notifications we\n   * prevent the differ having to do work to track them.\n   */\n  private void pauseModelListNotifications() {\n    ((ModelList) models).pauseNotifications();\n  }\n\n  private void resumeModelListNotifications() {\n    ((ModelList) models).resumeNotifications();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAsyncUtil.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Build;\nimport android.os.Handler;\nimport android.os.Handler.Callback;\nimport android.os.HandlerThread;\nimport android.os.Looper;\nimport android.os.Message;\n\nimport androidx.annotation.MainThread;\n\n/**\n * Various helpers for running Epoxy operations off the main thread.\n */\npublic final class EpoxyAsyncUtil {\n  private EpoxyAsyncUtil() {\n  }\n\n  /**\n   * A Handler class that uses the main thread's Looper.\n   */\n  public static final Handler MAIN_THREAD_HANDLER =\n      createHandler(Looper.getMainLooper(), false);\n\n  /**\n   * A Handler class that uses the main thread's Looper. Additionally, this handler calls\n   * {@link Message#setAsynchronous(boolean)} for\n   * each {@link Message} that is sent to it or {@link Runnable} that is posted to it\n   */\n  public static final Handler AYSNC_MAIN_THREAD_HANDLER =\n      createHandler(Looper.getMainLooper(), true);\n\n  private static Handler asyncBackgroundHandler;\n\n  /**\n   * A Handler class that uses a separate background thread dedicated to Epoxy. Additionally,\n   * this handler calls {@link Message#setAsynchronous(boolean)} for\n   * each {@link Message} that is sent to it or {@link Runnable} that is posted to it\n   */\n  @MainThread\n  public static Handler getAsyncBackgroundHandler() {\n    // This is initialized lazily so we don't create the thread unless it will be used.\n    // It isn't synchronized so it should only be accessed on the main thread.\n    if (asyncBackgroundHandler == null) {\n      asyncBackgroundHandler = createHandler(buildBackgroundLooper(\"epoxy\"), true);\n    }\n\n    return asyncBackgroundHandler;\n  }\n\n  /**\n   * Create a Handler with the given Looper\n   *\n   * @param async If true the Handler will calls {@link Message#setAsynchronous(boolean)} for\n   *              each {@link Message} that is sent to it or {@link Runnable} that is posted to it.\n   */\n  public static Handler createHandler(Looper looper, boolean async) {\n    if (!async) {\n      return new Handler(looper);\n    }\n\n    // Standard way of exposing async handler on older api's from the support library\n    // https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/core\n    // /src/main/java/androidx/core/os/HandlerCompat.java#51\n    if (Build.VERSION.SDK_INT >= 28) {\n      return Handler.createAsync(looper);\n    }\n    if (Build.VERSION.SDK_INT >= 16) {\n      try {\n        //noinspection JavaReflectionMemberAccess\n        return Handler.class.getDeclaredConstructor(Looper.class, Callback.class, boolean.class)\n            .newInstance(looper, null, true);\n      } catch (Throwable ignored) {\n      }\n    }\n\n    return new Handler(looper);\n  }\n\n  /**\n   * Create a new looper that runs on a new background thread.\n   */\n  public static Looper buildBackgroundLooper(String threadName) {\n    HandlerThread handlerThread = new HandlerThread(threadName);\n    handlerThread.start();\n    return handlerThread.getLooper();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.view.View;\n\nimport com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.Set;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\nimport androidx.annotation.IntDef;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;\n\nimport static com.airbnb.epoxy.ControllerHelperLookup.getHelperForController;\n\n/**\n * A controller for easily combining {@link EpoxyModel} instances in a {@link RecyclerView.Adapter}.\n * Simply implement {@link #buildModels()} to declare which models should be used, and in which\n * order. Call {@link #requestModelBuild()} whenever your data changes, and the controller will call\n * {@link #buildModels()}, update the adapter with the new models, and notify any changes between\n * the new and old models.\n * <p>\n * The controller maintains a {@link androidx.recyclerview.widget.RecyclerView.Adapter} with the\n * latest models, which you can get via {@link #getAdapter()} to set on your RecyclerView.\n * <p>\n * All data change notifications are applied automatically via Epoxy's diffing algorithm. All of\n * your models must have a unique id set on them for diffing to work. You may choose to use {@link\n * AutoModel} annotations to have the controller create models with unique ids for you\n * automatically.\n * <p>\n * Once a model is created and added to the controller in {@link #buildModels()} it should be\n * treated as immutable and never modified again. This is necessary for adapter updates to be\n * accurate.\n */\npublic abstract class EpoxyController implements ModelCollector, StickyHeaderCallbacks {\n\n  /**\n   * We check that the adapter is not connected to multiple recyclerviews, but when a fragment has\n   * its view quickly destroyed and recreated it may temporarily attach the same adapter to the\n   * previous view and the new view (eg because of fragment transitions) if the controller is reused\n   * across views. We want to allow this case since it is a brief transient state. This should be\n   * enough time for screen transitions to happen.\n   */\n  private static final int DELAY_TO_CHECK_ADAPTER_COUNT_MS = 3000;\n  private static final Timer NO_OP_TIMER = new NoOpTimer();\n\n  public static Handler defaultModelBuildingHandler = MainThreadExecutor.INSTANCE.handler;\n  public static Handler defaultDiffingHandler = MainThreadExecutor.INSTANCE.handler;\n  private static boolean filterDuplicatesDefault = false;\n  private static boolean globalDebugLoggingEnabled = false;\n\n  private final EpoxyControllerAdapter adapter;\n  private EpoxyDiffLogger debugObserver;\n  private int recyclerViewAttachCount = 0;\n  private final Handler modelBuildHandler;\n\n  /**\n   * This is iterated over in the build models thread, but items can be inserted or removed from\n   * other threads at any time.\n   */\n  private final List<Interceptor> interceptors = new CopyOnWriteArrayList<>();\n\n  // Volatile because -> write only on main thread, read from builder thread\n  private volatile boolean filterDuplicates = filterDuplicatesDefault;\n  /**\n   * This is used to track whether we are currently building models. If it is non null it means\n   * a thread is in the building models method. We store the thread so we can know which one\n   * is building models.\n   * <p>\n   * Volatile because -> write only on handler, read from any thread\n   */\n  private volatile Thread threadBuildingModels = null;\n  /**\n   * Used to know that we should build models synchronously the first time.\n   * <p>\n   * Volatile because -> written from the build models thread, read from the main thread.\n   */\n  private volatile boolean hasBuiltModelsEver;\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n\n  /*\n   * These fields are expected to only be used on the model building thread so they are not\n   * synchronized.\n   */\n\n  /** Used to time operations and log their duration when in debug mode. */\n  private Timer timer = NO_OP_TIMER;\n  private final ControllerHelper helper = getHelperForController(this);\n  private ControllerModelList modelsBeingBuilt;\n  private List<ModelInterceptorCallback> modelInterceptorCallbacks;\n  private EpoxyModel<?> stagedModel;\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n\n  public EpoxyController() {\n    this(defaultModelBuildingHandler, defaultDiffingHandler);\n  }\n\n  public EpoxyController(Handler modelBuildingHandler, Handler diffingHandler) {\n    adapter = new EpoxyControllerAdapter(this, diffingHandler);\n    modelBuildHandler = modelBuildingHandler;\n    setDebugLoggingEnabled(globalDebugLoggingEnabled);\n  }\n\n  /**\n   * Posting and canceling runnables is a bit expensive - it is synchronizes and iterates the\n   * list of runnables. We want clients to be able to request model builds as often as they want and\n   * have it act as a no-op if one is already requested, without being a performance hit. To do that\n   * we track whether we have a call to build models posted already so we can avoid canceling a\n   * current call and posting it again.\n   */\n  @RequestedModelBuildType private volatile int requestedModelBuildType =\n      RequestedModelBuildType.NONE;\n\n  @Retention(RetentionPolicy.SOURCE)\n  @IntDef({RequestedModelBuildType.NONE,\n      RequestedModelBuildType.NEXT_FRAME,\n      RequestedModelBuildType.DELAYED})\n  private @interface RequestedModelBuildType {\n    int NONE = 0;\n    /** A request has been made to build models immediately. It is posted. */\n    int NEXT_FRAME = 1;\n    /** A request has been made to build models after a delay. It is post delayed. */\n    int DELAYED = 2;\n  }\n\n  /**\n   * Call this to request a model update. The controller will schedule a call to {@link\n   * #buildModels()} so that models can be rebuilt for the current data. Once a build is requested\n   * all subsequent requests are ignored until the model build runs. Therefore, the calling code\n   * need not worry about calling this multiple times in a row.\n   * <p>\n   * The exception is that the first time this is called on a new instance of {@link\n   * EpoxyController} it is run synchronously. This allows state to be restored and the initial view\n   * to be draw quicker.\n   * <p>\n   * If you would like to be alerted when models have finished building use\n   * {@link #addModelBuildListener(OnModelBuildFinishedListener)}\n   */\n  public void requestModelBuild() {\n    if (isBuildingModels()) {\n      throw new IllegalEpoxyUsage(\"Cannot call `requestModelBuild` from inside `buildModels`\");\n    }\n\n    // If it is the first time building models then we do it right away, otherwise we post the call.\n    // We want to do it right away the first time so that scroll position can be restored correctly,\n    // shared element transitions aren't delayed, and content is shown asap. We post later calls\n    // so that they are debounced, and so any updates to data can be completely finished before\n    // the models are built.\n    if (hasBuiltModelsEver) {\n      requestDelayedModelBuild(0);\n    } else {\n      buildModelsRunnable.run();\n    }\n  }\n\n  /**\n   * Whether an update to models is currently pending. This can either be because\n   * {@link #requestModelBuild()} was called, or because models are currently being built or diff\n   * on a background thread.\n   */\n  public boolean hasPendingModelBuild() {\n    return requestedModelBuildType != RequestedModelBuildType.NONE // model build is posted\n        || threadBuildingModels != null // model build is in progress\n        || adapter.isDiffInProgress(); // Diff in progress\n  }\n\n  /**\n   * Add a listener that will be called every time {@link #buildModels()} has finished running\n   * and changes have been dispatched to the RecyclerView.\n   * <p>\n   * Since buildModels can be called once for many calls to {@link #requestModelBuild()}, this is\n   * called just once for each buildModels execution, not for every request.\n   * <p>\n   * Use this to react to changes in your models that need to happen after the RecyclerView has\n   * been notified, such as scrolling.\n   */\n  public void addModelBuildListener(OnModelBuildFinishedListener listener) {\n    adapter.addModelBuildListener(listener);\n  }\n\n  /**\n   * Remove a listener added with {@link #addModelBuildListener(OnModelBuildFinishedListener)}.\n   * This is safe to call from inside the callback\n   * {@link OnModelBuildFinishedListener#onModelBuildFinished(DiffResult)}\n   */\n  public void removeModelBuildListener(OnModelBuildFinishedListener listener) {\n    adapter.removeModelBuildListener(listener);\n  }\n\n  /**\n   * Call this to request a delayed model update. The controller will schedule a call to {@link\n   * #buildModels()} so that models can be rebuilt for the current data.\n   * <p>\n   * Using this to delay a model update may be helpful in cases where user input is causing many\n   * rapid changes in the models, such as typing. In that case, the view is already updated on\n   * screen and constantly rebuilding models is potentially slow and unnecessary. The downside to\n   * delaying the model build too long is that models will not be in sync with the data or view, and\n   * scrolling the view offscreen and back onscreen will cause the model to bind old data.\n   * <p>\n   * If a previous request is still pending it will be removed in favor of this new delay\n   * <p>\n   * Any call to {@link #requestModelBuild()} will override a delayed request.\n   * <p>\n   * In most cases you should use {@link #requestModelBuild()} instead of this.\n   *\n   * @param delayMs The time in milliseconds to delay the model build by. Should be greater than or\n   *                equal to 0. A value of 0 is equivalent to calling {@link #requestModelBuild()}\n   */\n  public synchronized void requestDelayedModelBuild(int delayMs) {\n    if (isBuildingModels()) {\n      throw new IllegalEpoxyUsage(\n          \"Cannot call `requestDelayedModelBuild` from inside `buildModels`\");\n    }\n\n    if (requestedModelBuildType == RequestedModelBuildType.DELAYED) {\n      cancelPendingModelBuild();\n    } else if (requestedModelBuildType == RequestedModelBuildType.NEXT_FRAME) {\n      return;\n    }\n\n    requestedModelBuildType =\n        delayMs == 0 ? RequestedModelBuildType.NEXT_FRAME : RequestedModelBuildType.DELAYED;\n\n    modelBuildHandler.postDelayed(buildModelsRunnable, delayMs);\n  }\n\n  /**\n   * Cancels a pending call to {@link #buildModels()} if one has been queued by {@link\n   * #requestModelBuild()}.\n   */\n  public synchronized void cancelPendingModelBuild() {\n    // Access to requestedModelBuildType is synchronized because the model building thread clears\n    // it when model building starts, and the main thread needs to set it to indicate a build\n    // request.\n    // Additionally, it is crucial to guarantee that the state of requestedModelBuildType is in sync\n    // with the modelBuildHandler, otherwise we could end up in a state where we think a model build\n    // is queued, but it isn't, and model building never happens - stuck forever.\n    if (requestedModelBuildType != RequestedModelBuildType.NONE) {\n      requestedModelBuildType = RequestedModelBuildType.NONE;\n      modelBuildHandler.removeCallbacks(buildModelsRunnable);\n    }\n  }\n\n  private final Runnable buildModelsRunnable = new Runnable() {\n    @Override\n    public void run() {\n      // Do this first to mark the controller as being in the model building process.\n      threadBuildingModels = Thread.currentThread();\n\n      // This is needed to reset the requestedModelBuildType back to NONE.\n      // As soon as we do this another model build can be posted.\n      cancelPendingModelBuild();\n\n      helper.resetAutoModels();\n\n      modelsBeingBuilt = new ControllerModelList(getExpectedModelCount());\n\n      timer.start(\"Models built\");\n\n      // The user's implementation of buildModels is wrapped in a try/catch so that if it fails\n      // we can reset the state of this controller. This is useful when model building is done\n      // on a dedicated thread, which may have its own error handler, and a failure may not\n      // crash the app - in which case this controller would be in an invalid state and crash later\n      // with confusing errors because \"threadBuildingModels\" and other properties are not\n      // correctly set. This can happen particularly with Espresso testing.\n      try {\n        buildModels();\n      } catch (Throwable throwable) {\n        timer.stop();\n        modelsBeingBuilt = null;\n        hasBuiltModelsEver = true;\n        threadBuildingModels = null;\n        stagedModel = null;\n        throw throwable;\n      }\n\n      addCurrentlyStagedModelIfExists();\n      timer.stop();\n\n      runInterceptors();\n      filterDuplicatesIfNeeded(modelsBeingBuilt);\n      modelsBeingBuilt.freeze();\n\n      timer.start(\"Models diffed\");\n      adapter.setModels(modelsBeingBuilt);\n      // This timing is only right if diffing and model building are on the same thread\n      timer.stop();\n\n      modelsBeingBuilt = null;\n      hasBuiltModelsEver = true;\n      threadBuildingModels = null;\n    }\n  };\n\n  /** An estimate for how many models will be built in the next {@link #buildModels()} phase. */\n  private int getExpectedModelCount() {\n    int currentModelCount = adapter.getItemCount();\n    return currentModelCount != 0 ? currentModelCount : 25;\n  }\n\n  /**\n   * Subclasses should implement this to describe what models should be shown for the current state.\n   * Implementations should call either {@link #add(EpoxyModel)}, {@link\n   * EpoxyModel#addTo(EpoxyController)}, or {@link EpoxyModel#addIf(boolean, EpoxyController)} with\n   * the models that should be shown, in the order that is desired.\n   * <p>\n   * Once a model is added to the controller it should be treated as immutable and never modified\n   * again. This is necessary for adapter updates to be accurate. If \"validateEpoxyModelUsage\" is\n   * enabled then runtime validations will be done to make sure models are not changed.\n   * <p>\n   * You CANNOT call this method directly. Instead, call {@link #requestModelBuild()} to have the\n   * controller schedule an update.\n   */\n  protected abstract void buildModels();\n\n  int getFirstIndexOfModelInBuildingList(EpoxyModel<?> model) {\n    assertIsBuildingModels();\n\n    int size = modelsBeingBuilt.size();\n    for (int i = 0; i < size; i++) {\n      if (modelsBeingBuilt.get(i) == model) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  boolean isModelAddedMultipleTimes(EpoxyModel<?> model) {\n    assertIsBuildingModels();\n\n    int modelCount = 0;\n    int size = modelsBeingBuilt.size();\n    for (int i = 0; i < size; i++) {\n      if (modelsBeingBuilt.get(i) == model) {\n        modelCount++;\n      }\n    }\n\n    return modelCount > 1;\n  }\n\n  void addAfterInterceptorCallback(ModelInterceptorCallback callback) {\n    assertIsBuildingModels();\n\n    if (modelInterceptorCallbacks == null) {\n      modelInterceptorCallbacks = new ArrayList<>();\n    }\n\n    modelInterceptorCallbacks.add(callback);\n  }\n\n  /**\n   * Callbacks to each model for when interceptors are started and stopped, so the models know when\n   * to allow changes.\n   */\n  interface ModelInterceptorCallback {\n    void onInterceptorsStarted(EpoxyController controller);\n    void onInterceptorsFinished(EpoxyController controller);\n  }\n\n  private void runInterceptors() {\n    if (!interceptors.isEmpty()) {\n      if (modelInterceptorCallbacks != null) {\n        for (ModelInterceptorCallback callback : modelInterceptorCallbacks) {\n          callback.onInterceptorsStarted(this);\n        }\n      }\n\n      timer.start(\"Interceptors executed\");\n\n      for (Interceptor interceptor : interceptors) {\n        interceptor.intercept(modelsBeingBuilt);\n      }\n\n      timer.stop();\n\n      if (modelInterceptorCallbacks != null) {\n        for (ModelInterceptorCallback callback : modelInterceptorCallbacks) {\n          callback.onInterceptorsFinished(this);\n        }\n      }\n    }\n\n    // Interceptors are cleared so that future model builds don't notify past models.\n    // We need to make sure they are cleared even if there are no interceptors so that\n    // we don't leak the models.\n    modelInterceptorCallbacks = null;\n  }\n\n  /** A callback that is run after {@link #buildModels()} completes and before diffing is run. */\n  public interface Interceptor {\n    /**\n     * This is called immediately after {@link #buildModels()} and before diffing is run and the\n     * models are set on the adapter. This is a final chance to make any changes to the the models\n     * added in {@link #buildModels()}. This may be useful for actions that act on all models in\n     * aggregate, such as toggling divider settings, or for cases such as rearranging models for an\n     * experiment.\n     * <p>\n     * The models list must not be changed after this method returns. Doing so will throw an\n     * exception.\n     */\n    void intercept(@NonNull List<EpoxyModel<?>> models);\n  }\n\n  /**\n   * Add an interceptor callback to be run after models are built, to make any last changes before\n   * they are set on the adapter. Interceptors are run in the order they are added.\n   * <p>\n   * Interceptors are run on the same thread that models are built on.\n   *\n   * @see Interceptor#intercept(List)\n   */\n  public void addInterceptor(@NonNull Interceptor interceptor) {\n    interceptors.add(interceptor);\n  }\n\n  /** Remove an interceptor that was added with {@link #addInterceptor(Interceptor)}. */\n  public void removeInterceptor(@NonNull Interceptor interceptor) {\n    interceptors.remove(interceptor);\n  }\n\n  /**\n   * Get the number of models added so far during the {@link #buildModels()} phase. It is only valid\n   * to call this from within that method.\n   * <p>\n   * This is different from the number of models currently on the adapter, since models on the\n   * adapter are not updated until after models are finished being built. To access current adapter\n   * count call {@link #getAdapter()} and {@link EpoxyControllerAdapter#getItemCount()}\n   */\n  protected int getModelCountBuiltSoFar() {\n    assertIsBuildingModels();\n    return modelsBeingBuilt.size();\n  }\n\n  private void assertIsBuildingModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalEpoxyUsage(\"Can only call this when inside the `buildModels` method\");\n    }\n  }\n\n  private void assertNotBuildingModels() {\n    if (isBuildingModels()) {\n      throw new IllegalEpoxyUsage(\"Cannot call this from inside `buildModels`\");\n    }\n  }\n\n  /**\n   * Add the model to this controller. Can only be called from inside {@link\n   * EpoxyController#buildModels()}.\n   */\n  public void add(@NonNull EpoxyModel<?> model) {\n    model.addTo(this);\n  }\n\n  /**\n   * Add the models to this controller. Can only be called from inside {@link\n   * EpoxyController#buildModels()}.\n   */\n  protected void add(@NonNull EpoxyModel<?>... modelsToAdd) {\n    modelsBeingBuilt.ensureCapacity(modelsBeingBuilt.size() + modelsToAdd.length);\n\n    for (EpoxyModel<?> model : modelsToAdd) {\n      add(model);\n    }\n  }\n\n  /**\n   * Add the models to this controller. Can only be called from inside {@link\n   * EpoxyController#buildModels()}.\n   */\n  protected void add(@NonNull List<? extends EpoxyModel<?>> modelsToAdd) {\n    modelsBeingBuilt.ensureCapacity(modelsBeingBuilt.size() + modelsToAdd.size());\n\n    for (EpoxyModel<?> model : modelsToAdd) {\n      add(model);\n    }\n  }\n\n  /**\n   * Method to actually add the model to the list being built. Should be called after all\n   * validations are done.\n   */\n  void addInternal(EpoxyModel<?> modelToAdd) {\n    assertIsBuildingModels();\n\n    if (modelToAdd.hasDefaultId()) {\n      throw new IllegalEpoxyUsage(\n          \"You must set an id on a model before adding it. Use the @AutoModel annotation if you \"\n              + \"want an id to be automatically generated for you.\");\n    }\n\n    if (!modelToAdd.isShown()) {\n      throw new IllegalEpoxyUsage(\n          \"You cannot hide a model in an EpoxyController. Use `addIf` to conditionally add a \"\n              + \"model instead.\");\n    }\n\n    // The model being added may not have been staged if it wasn't mutated before it was added.\n    // In that case we may have a previously staged model that still needs to be added.\n    clearModelFromStaging(modelToAdd);\n    modelToAdd.controllerToStageTo = null;\n    modelsBeingBuilt.add(modelToAdd);\n  }\n\n  /**\n   * Staging models allows them to be implicitly added after the user finishes modifying them. This\n   * means that if a user has modified a model, and then moves on to modifying a different model,\n   * the first model is automatically added as soon as the second model is modified.\n   * <p>\n   * There are some edge cases for handling models that are added without modification, or models\n   * that are modified but then fail an `addIf` check.\n   * <p>\n   * This only works for AutoModels, and only if implicitly adding is enabled in configuration.\n   */\n  void setStagedModel(EpoxyModel<?> model) {\n    if (model != stagedModel) {\n      addCurrentlyStagedModelIfExists();\n    }\n\n    stagedModel = model;\n  }\n\n  void addCurrentlyStagedModelIfExists() {\n    if (stagedModel != null) {\n      stagedModel.addTo(this);\n    }\n    stagedModel = null;\n  }\n\n  void clearModelFromStaging(EpoxyModel<?> model) {\n    if (stagedModel != model) {\n      addCurrentlyStagedModelIfExists();\n    }\n    stagedModel = null;\n  }\n\n  /** True if the current callstack originated from the buildModels call, on the same thread. */\n  protected boolean isBuildingModels() {\n    return threadBuildingModels == Thread.currentThread();\n  }\n\n  private void filterDuplicatesIfNeeded(List<EpoxyModel<?>> models) {\n    if (!filterDuplicates) {\n      return;\n    }\n\n    timer.start(\"Duplicates filtered\");\n    Set<Long> modelIds = new HashSet<>(models.size());\n\n    ListIterator<EpoxyModel<?>> modelIterator = models.listIterator();\n    while (modelIterator.hasNext()) {\n      EpoxyModel<?> model = modelIterator.next();\n      if (!modelIds.add(model.id())) {\n        int indexOfDuplicate = modelIterator.previousIndex();\n        modelIterator.remove();\n\n        int indexOfOriginal = findPositionOfDuplicate(models, model);\n        EpoxyModel<?> originalModel = models.get(indexOfOriginal);\n        if (indexOfDuplicate <= indexOfOriginal) {\n          // Adjust for the original positions of the models before the duplicate was removed\n          indexOfOriginal++;\n        }\n\n        onExceptionSwallowed(\n            new IllegalEpoxyUsage(\"Two models have the same ID. ID's must be unique!\"\n                + \"\\nOriginal has position \" + indexOfOriginal + \":\\n\" + originalModel\n                + \"\\nDuplicate has position \" + indexOfDuplicate + \":\\n\" + model)\n        );\n      }\n    }\n\n    timer.stop();\n  }\n\n  private int findPositionOfDuplicate(List<EpoxyModel<?>> models, EpoxyModel<?> duplicateModel) {\n    int size = models.size();\n    for (int i = 0; i < size; i++) {\n      EpoxyModel<?> model = models.get(i);\n      if (model.id() == duplicateModel.id()) {\n        return i;\n      }\n    }\n\n    throw new IllegalArgumentException(\"No duplicates in list\");\n  }\n\n  /**\n   * If set to true, Epoxy will search for models with duplicate ids added during {@link\n   * #buildModels()} and remove any duplicates found. If models with the same id are found, the\n   * first one is left in the adapter and any subsequent models are removed. {@link\n   * #onExceptionSwallowed(RuntimeException)} will be called for each duplicate removed.\n   * <p>\n   * This may be useful if your models are created via server supplied data, in which case the\n   * server may erroneously send duplicate items. Duplicate items are otherwise left in and can\n   * result in undefined behavior.\n   */\n  public void setFilterDuplicates(boolean filterDuplicates) {\n    this.filterDuplicates = filterDuplicates;\n  }\n\n  public boolean isDuplicateFilteringEnabled() {\n    return filterDuplicates;\n  }\n\n  /**\n   * {@link #setFilterDuplicates(boolean)} is disabled in each EpoxyController by default. It can be\n   * toggled individually in each controller, or alternatively you can use this to change the\n   * default value for all EpoxyControllers.\n   */\n  public static void setGlobalDuplicateFilteringDefault(boolean filterDuplicatesByDefault) {\n    EpoxyController.filterDuplicatesDefault = filterDuplicatesByDefault;\n  }\n\n  /**\n   * If enabled, DEBUG logcat messages will be printed to show when models are rebuilt, the time\n   * taken to build them, the time taken to diff them, and the item change outcomes from the\n   * differ. The tag of the logcat message is the class name of your EpoxyController.\n   * <p>\n   * This is useful to verify that models are being diffed as expected, as well as to watch for\n   * slowdowns in model building or diffing to indicate when you should optimize model building or\n   * model hashCode/equals implementations (which can often slow down diffing).\n   * <p>\n   * This should only be used in debug builds to avoid a performance hit in prod.\n   */\n  public void setDebugLoggingEnabled(boolean enabled) {\n    assertNotBuildingModels();\n\n    if (enabled) {\n      timer = new DebugTimer(getClass().getSimpleName());\n      if (debugObserver == null) {\n        debugObserver = new EpoxyDiffLogger(getClass().getSimpleName());\n      }\n      adapter.registerAdapterDataObserver(debugObserver);\n    } else {\n      timer = NO_OP_TIMER;\n      if (debugObserver != null) {\n        adapter.unregisterAdapterDataObserver(debugObserver);\n      }\n    }\n  }\n\n  public boolean isDebugLoggingEnabled() {\n    return timer != NO_OP_TIMER;\n  }\n\n  /**\n   * Similar to {@link #setDebugLoggingEnabled(boolean)}, but this changes the global default for\n   * all EpoxyControllers.\n   * <p>\n   * The default is false.\n   */\n  public static void setGlobalDebugLoggingEnabled(boolean globalDebugLoggingEnabled) {\n    EpoxyController.globalDebugLoggingEnabled = globalDebugLoggingEnabled;\n  }\n\n  /**\n   * An optimized way to move a model from one position to another without rebuilding all models.\n   * This is intended to be used with {@link androidx.recyclerview.widget.ItemTouchHelper} to\n   * allow for efficient item dragging and rearranging. It cannot be\n   * <p>\n   * If you call this you MUST also update the data backing your models as necessary.\n   * <p>\n   * This will immediately change the model's position and notify the change to the RecyclerView.\n   * However, a delayed request to rebuild models will be scheduled for the future to guarantee that\n   * models are in sync with data.\n   *\n   * @param fromPosition Previous position of the item.\n   * @param toPosition   New position of the item.\n   */\n  public void moveModel(int fromPosition, int toPosition) {\n    assertNotBuildingModels();\n\n    adapter.moveModel(fromPosition, toPosition);\n\n    requestDelayedModelBuild(500);\n  }\n\n\n  /**\n   * An way to notify the adapter that a model has changed. This is intended to be used with\n   * {@link androidx.recyclerview.widget.ItemTouchHelper} to allow revert swiping a model.\n   * <p>\n   * This will immediately notify the change to the RecyclerView.\n   *\n   * @param position Position of the item.\n   */\n  public void notifyModelChanged(int position) {\n    assertNotBuildingModels();\n\n    adapter.notifyModelChanged(position);\n  }\n\n\n  /**\n   * Get the underlying adapter built by this controller. Use this to get the adapter to set on a\n   * RecyclerView, or to get information about models currently in use.\n   */\n  @NonNull\n  public EpoxyControllerAdapter getAdapter() {\n    return adapter;\n  }\n\n  public void onSaveInstanceState(@NonNull Bundle outState) {\n    adapter.onSaveInstanceState(outState);\n  }\n\n  public void onRestoreInstanceState(@Nullable Bundle inState) {\n    adapter.onRestoreInstanceState(inState);\n  }\n\n  /**\n   * For use with a grid layout manager - use this to get the {@link SpanSizeLookup} for models in\n   * this controller. This will delegate span look up calls to each model's {@link\n   * EpoxyModel#getSpanSize(int, int, int)}. Make sure to also call {@link #setSpanCount(int)} so\n   * the span count is correct.\n   */\n  @NonNull\n  public SpanSizeLookup getSpanSizeLookup() {\n    return adapter.getSpanSizeLookup();\n  }\n\n  /**\n   * If you are using a grid layout manager you must call this to set the span count of the grid.\n   * This span count will be passed on to the models so models can choose which span count to be.\n   *\n   * @see #getSpanSizeLookup()\n   * @see EpoxyModel#getSpanSize(int, int, int)\n   */\n  public void setSpanCount(int spanCount) {\n    adapter.setSpanCount(spanCount);\n  }\n\n  public int getSpanCount() {\n    return adapter.getSpanCount();\n  }\n\n  public boolean isMultiSpan() {\n    return adapter.isMultiSpan();\n  }\n\n  /**\n   * This is called when recoverable exceptions occur at runtime. By default they are ignored and\n   * Epoxy will recover, but you can override this to be aware of when they happen.\n   * <p>\n   * A common use for this is being aware of duplicates when {@link #setFilterDuplicates(boolean)}\n   * is enabled.\n   * <p>\n   * By default the global exception handler provided by\n   * {@link #setGlobalExceptionHandler(ExceptionHandler)}\n   * is called with the exception. Overriding this allows you to provide your own handling for a\n   * controller.\n   */\n  protected void onExceptionSwallowed(@NonNull RuntimeException exception) {\n    globalExceptionHandler.onException(this, exception);\n  }\n\n  /**\n   * Default handler for exceptions in all EpoxyControllers. Set with {@link\n   * #setGlobalExceptionHandler(ExceptionHandler)}\n   */\n  private static ExceptionHandler globalExceptionHandler =\n      new ExceptionHandler() {\n\n        @Override\n        public void onException(@NonNull EpoxyController controller,\n            @NonNull RuntimeException exception) {\n          // Ignore exceptions as the default\n        }\n      };\n\n  /**\n   * Set a callback to be notified when a recoverable exception occurs at runtime.  By default these\n   * are ignored and Epoxy will recover, but you can override this to be aware of when they happen.\n   * <p>\n   * For example, you could choose to rethrow the exception in development builds, or log them in\n   * production.\n   * <p>\n   * A common use for this is being aware of duplicates when {@link #setFilterDuplicates(boolean)}\n   * is enabled.\n   * <p>\n   * This callback will be used in all EpoxyController classes. If you would like specific handling\n   * in a certain controller you can override {@link #onExceptionSwallowed(RuntimeException)} in\n   * that controller.\n   */\n  public static void setGlobalExceptionHandler(\n      @NonNull ExceptionHandler globalExceptionHandler) {\n    EpoxyController.globalExceptionHandler = globalExceptionHandler;\n  }\n\n  public interface ExceptionHandler {\n    /**\n     * This is called when recoverable exceptions happen at runtime. They can be ignored and Epoxy\n     * will recover, but you can override this to be aware of when they happen.\n     * <p>\n     * For example, you could choose to rethrow the exception in development builds, or log them in\n     * production.\n     *\n     * @param controller The EpoxyController that the error occurred in.\n     */\n    void onException(@NonNull EpoxyController controller, @NonNull RuntimeException exception);\n  }\n\n  void onAttachedToRecyclerViewInternal(RecyclerView recyclerView) {\n    recyclerViewAttachCount++;\n\n    if (recyclerViewAttachCount > 1) {\n      MainThreadExecutor.INSTANCE.handler.postDelayed(new Runnable() {\n        @Override\n        public void run() {\n          // Only warn if there are still multiple adapters attached after a delay, to allow for\n          // a grace period\n          if (recyclerViewAttachCount > 1) {\n            onExceptionSwallowed(new IllegalStateException(\n                \"This EpoxyController had its adapter added to more than one ReyclerView. Epoxy \"\n                    + \"does not support attaching an adapter to multiple RecyclerViews because \"\n                    + \"saved state will not work properly. If you did not intend to attach your \"\n                    + \"adapter \"\n                    + \"to multiple RecyclerViews you may be leaking a \"\n                    + \"reference to a previous RecyclerView. Make sure to remove the adapter from \"\n                    + \"any \"\n                    + \"previous RecyclerViews (eg if the adapter is reused in a Fragment across \"\n                    + \"multiple onCreateView/onDestroyView cycles). See https://github\"\n                    + \".com/airbnb/epoxy/wiki/Avoiding-Memory-Leaks for more information.\"));\n          }\n        }\n      }, DELAY_TO_CHECK_ADAPTER_COUNT_MS);\n    }\n\n    onAttachedToRecyclerView(recyclerView);\n  }\n\n  void onDetachedFromRecyclerViewInternal(RecyclerView recyclerView) {\n    recyclerViewAttachCount--;\n    onDetachedFromRecyclerView(recyclerView);\n  }\n\n  /** Called when the controller's adapter is attach to a recyclerview. */\n  protected void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {\n\n  }\n\n  /** Called when the controller's adapter is detached from a recyclerview. */\n  protected void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {\n\n  }\n\n  /**\n   * Called immediately after a model is bound to a view holder. Subclasses can override this if\n   * they want alerts on when a model is bound. Alternatively you may attach a listener directly to\n   * a generated model with model.onBind(...)\n   *\n   * @param previouslyBoundModel If non null, this is a model with the same id as the newly bound\n   *                             model, and was previously bound to a view. This means that {@link\n   *                             #buildModels()} returned a model that is different from the\n   *                             previouslyBoundModel and the view is being rebound to incorporate\n   *                             the change. You can compare this previous model with the new one to\n   *                             see exactly what changed.\n   *                             <p>\n   *                             The newly bound model and the previously bound model are guaranteed\n   *                             to have the same id, but will not necessarily be of the same type\n   *                             depending on your implementation of {@link #buildModels()}. With\n   *                             common usage patterns of Epoxy they should be the same type, and\n   *                             will only differ if you are using different model classes with the\n   *                             same id.\n   *                             <p>\n   *                             Comparing the newly bound model with the previous model allows you\n   *                             to be more intelligent when updating your view. This may help you\n   *                             optimize, or make it easier to work with animations.\n   *                             <p>\n   *                             If the new model and the previous model have the same view type\n   *                             (given by {@link EpoxyModel#getViewType()}), and if you are using\n   *                             the default ReyclerView item animator, the same view will be kept.\n   *                             If you are using a custom item animator then the view will be the\n   *                             same if the animator returns true in canReuseUpdatedViewHolder.\n   *                             <p>\n   *                             This previously bound model is taken as a payload from the diffing\n   *                             process, and follows the same general conditions for all\n   *                             recyclerview change payloads.\n   */\n  protected void onModelBound(@NonNull EpoxyViewHolder holder, @NonNull EpoxyModel<?> boundModel,\n      int position,\n      @Nullable EpoxyModel<?> previouslyBoundModel) {\n  }\n\n  /**\n   * Called immediately after a model is unbound from a view holder. Subclasses can override this if\n   * they want alerts on when a model is unbound. Alternatively you may attach a listener directly\n   * to a generated model with model.onUnbind(...)\n   */\n  protected void onModelUnbound(@NonNull EpoxyViewHolder holder, @NonNull EpoxyModel<?> model) {\n\n  }\n\n  /**\n   * Called when the given viewholder is attached to the window, along with the model it is bound\n   * to.\n   *\n   * @see BaseEpoxyAdapter#onViewAttachedToWindow(EpoxyViewHolder)\n   */\n  protected void onViewAttachedToWindow(@NonNull EpoxyViewHolder holder,\n      @NonNull EpoxyModel<?> model) {\n\n  }\n\n  /**\n   * Called when the given viewholder is detechaed from the window, along with the model it is bound\n   * to.\n   *\n   * @see BaseEpoxyAdapter#onViewDetachedFromWindow(EpoxyViewHolder)\n   */\n  protected void onViewDetachedFromWindow(@NonNull EpoxyViewHolder holder,\n      @NonNull EpoxyModel<?> model) {\n\n  }\n\n  //region Sticky header\n\n  /**\n   * Optional callback to setup the sticky view,\n   * by default it doesn't do anything.\n   *\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public void setupStickyHeaderView(@NotNull View stickyHeader) {\n    // no-op\n  }\n\n  /**\n   * Optional callback to perform tear down operation on the\n   * sticky view, by default it doesn't do anything.\n   *\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public void teardownStickyHeaderView(@NotNull View stickyHeader) {\n    // no-op\n  }\n\n  /**\n   * Called to check if the item at the position is a sticky item,\n   * by default returns false.\n   *\n   * The sub-classes should override the function if they are\n   * using sticky header feature.\n   */\n  @Override\n  public boolean isStickyHeader(int position) {\n    return false;\n  }\n\n  //endregion\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyControllerAdapter.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AsyncEpoxyDiffer.ResultCallback;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.UiThread;\nimport androidx.recyclerview.widget.DiffUtil.ItemCallback;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic final class EpoxyControllerAdapter extends BaseEpoxyAdapter implements ResultCallback {\n  private final NotifyBlocker notifyBlocker = new NotifyBlocker();\n  private final AsyncEpoxyDiffer differ;\n  private final EpoxyController epoxyController;\n  private int itemCount;\n  private final List<OnModelBuildFinishedListener> modelBuildListeners = new ArrayList<>();\n\n  EpoxyControllerAdapter(@NonNull EpoxyController epoxyController, Handler diffingHandler) {\n    this.epoxyController = epoxyController;\n    differ = new AsyncEpoxyDiffer(\n        diffingHandler,\n        this,\n        ITEM_CALLBACK\n    );\n    registerAdapterDataObserver(notifyBlocker);\n  }\n\n  @Override\n  protected void onExceptionSwallowed(@NonNull RuntimeException exception) {\n    epoxyController.onExceptionSwallowed(exception);\n  }\n\n  @NonNull\n  @Override\n  List<? extends EpoxyModel<?>> getCurrentModels() {\n    return differ.getCurrentList();\n  }\n\n  @Override\n  public int getItemCount() {\n    // RecyclerView calls this A LOT. The base class implementation does\n    // getCurrentModels().size() which adds some overhead because of the method calls.\n    // We can easily memoize this, which seems to help when there are lots of models.\n    return itemCount;\n  }\n\n  /** This is set from whatever thread model building happened on, so must be thread safe. */\n  void setModels(@NonNull ControllerModelList models) {\n    // If debug model validations are on then we should help detect the error case where models\n    // were incorrectly mutated once they were added. That check is also done before and after\n    // bind, but there is no other check after that to see if a model is incorrectly\n    // mutated after being bound.\n    // If a data class inside a model is mutated, then when models are rebuilt the differ\n    // will still recognize the old and new models as equal, even though the old model was changed.\n    // To help catch that error case we check for mutations here, before running the differ.\n    //\n    // https://github.com/airbnb/epoxy/issues/805\n    List<? extends EpoxyModel<?>> currentModels = getCurrentModels();\n    if (!currentModels.isEmpty() && currentModels.get(0).isDebugValidationEnabled()) {\n      for (int i = 0; i < currentModels.size(); i++) {\n        EpoxyModel<?> model = currentModels.get(i);\n        model.validateStateHasNotChangedSinceAdded(\n            \"The model was changed between being bound and when models were rebuilt\",\n            i\n        );\n      }\n    }\n\n    differ.submitList(models);\n  }\n\n  /**\n   * @return True if a diff operation is in progress.\n   */\n  public boolean isDiffInProgress() {\n    return differ.isDiffInProgress();\n  }\n\n  // Called on diff results from the differ\n  @Override\n  public void onResult(@NonNull DiffResult result) {\n    itemCount = result.newModels.size();\n    notifyBlocker.allowChanges();\n    result.dispatchTo(this);\n    notifyBlocker.blockChanges();\n\n    for (int i = modelBuildListeners.size() - 1; i >= 0; i--) {\n      modelBuildListeners.get(i).onModelBuildFinished(result);\n    }\n  }\n\n  public void addModelBuildListener(OnModelBuildFinishedListener listener) {\n    modelBuildListeners.add(listener);\n  }\n\n  public void removeModelBuildListener(OnModelBuildFinishedListener listener) {\n    modelBuildListeners.remove(listener);\n  }\n\n  @Override\n  boolean diffPayloadsEnabled() {\n    return true;\n  }\n\n  @Override\n  public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {\n    super.onAttachedToRecyclerView(recyclerView);\n    epoxyController.onAttachedToRecyclerViewInternal(recyclerView);\n  }\n\n  @Override\n  public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {\n    super.onDetachedFromRecyclerView(recyclerView);\n    epoxyController.onDetachedFromRecyclerViewInternal(recyclerView);\n  }\n\n  @Override\n  public void onViewAttachedToWindow(@NonNull EpoxyViewHolder holder) {\n    super.onViewAttachedToWindow(holder);\n    epoxyController.onViewAttachedToWindow(holder, holder.getModel());\n  }\n\n  @Override\n  public void onViewDetachedFromWindow(@NonNull EpoxyViewHolder holder) {\n    super.onViewDetachedFromWindow(holder);\n    epoxyController.onViewDetachedFromWindow(holder, holder.getModel());\n  }\n\n  @Override\n  protected void onModelBound(@NonNull EpoxyViewHolder holder, @NonNull EpoxyModel<?> model,\n      int position, @Nullable EpoxyModel<?> previouslyBoundModel) {\n    epoxyController.onModelBound(holder, model, position, previouslyBoundModel);\n  }\n\n  @Override\n  protected void onModelUnbound(@NonNull EpoxyViewHolder holder, @NonNull EpoxyModel<?> model) {\n    epoxyController.onModelUnbound(holder, model);\n  }\n\n  /** Get an unmodifiable copy of the current models set on the adapter. */\n  @NonNull\n  public List<EpoxyModel<?>> getCopyOfModels() {\n    //noinspection unchecked\n    return (List<EpoxyModel<?>>) getCurrentModels();\n  }\n\n  /**\n   * @throws IndexOutOfBoundsException If the given position is out of range of the current model\n   *                                   list.\n   */\n  @NonNull\n  public EpoxyModel<?> getModelAtPosition(int position) {\n    return getCurrentModels().get(position);\n  }\n\n  /**\n   * Searches the current model list for the model with the given id. Returns the matching model if\n   * one is found, otherwise null is returned.\n   */\n  @Nullable\n  public EpoxyModel<?> getModelById(long id) {\n    for (EpoxyModel<?> model : getCurrentModels()) {\n      if (model.id() == id) {\n        return model;\n      }\n    }\n\n    return null;\n  }\n\n  @Override\n  public int getModelPosition(@NonNull EpoxyModel<?> targetModel) {\n    int size = getCurrentModels().size();\n    for (int i = 0; i < size; i++) {\n      EpoxyModel<?> model = getCurrentModels().get(i);\n      if (model.id() == targetModel.id()) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  @NonNull\n  @Override\n  public BoundViewHolders getBoundViewHolders() {\n    return super.getBoundViewHolders();\n  }\n\n  @UiThread\n  void moveModel(int fromPosition, int toPosition) {\n    ArrayList<EpoxyModel<?>> updatedList = new ArrayList<>(getCurrentModels());\n\n    updatedList.add(toPosition, updatedList.remove(fromPosition));\n    notifyBlocker.allowChanges();\n    notifyItemMoved(fromPosition, toPosition);\n    notifyBlocker.blockChanges();\n\n    boolean interruptedDiff = differ.forceListOverride(updatedList);\n\n    if (interruptedDiff) {\n      // The move interrupted a model rebuild/diff that was in progress,\n      // so models may be out of date and we should force them to rebuilt\n      epoxyController.requestModelBuild();\n    }\n  }\n\n  @UiThread\n  void notifyModelChanged(int position) {\n    ArrayList<EpoxyModel<?>> updatedList = new ArrayList<>(getCurrentModels());\n\n    notifyBlocker.allowChanges();\n    notifyItemChanged(position);\n    notifyBlocker.blockChanges();\n\n    boolean interruptedDiff = differ.forceListOverride(updatedList);\n\n    if (interruptedDiff) {\n      // The move interrupted a model rebuild/diff that was in progress,\n      // so models may be out of date and we should force them to rebuilt\n      epoxyController.requestModelBuild();\n    }\n  }\n\n  private static final ItemCallback<EpoxyModel<?>> ITEM_CALLBACK =\n      new ItemCallback<EpoxyModel<?>>() {\n        @Override\n        public boolean areItemsTheSame(EpoxyModel<?> oldItem, EpoxyModel<?> newItem) {\n          return oldItem.id() == newItem.id();\n        }\n\n        @Override\n        public boolean areContentsTheSame(EpoxyModel<?> oldItem, EpoxyModel<?> newItem) {\n          return oldItem.equals(newItem);\n        }\n\n        @Override\n        public Object getChangePayload(EpoxyModel<?> oldItem, EpoxyModel<?> newItem) {\n          return new DiffPayload(oldItem);\n        }\n      };\n\n  /**\n   * Delegates the callbacks received in the adapter\n   * to the controller.\n   */\n  @Override\n  public boolean isStickyHeader(int position) {\n    return epoxyController.isStickyHeader(position);\n  }\n\n  /**\n   * Delegates the callbacks received in the adapter\n   * to the controller.\n   */\n  @Override\n  public void setupStickyHeaderView(@NotNull View stickyHeader) {\n    epoxyController.setupStickyHeaderView(stickyHeader);\n  }\n\n  /**\n   * Delegates the callbacks received in the adapter\n   * to the controller.\n   */\n  @Override\n  public void teardownStickyHeaderView(@NotNull View stickyHeader) {\n    epoxyController.teardownStickyHeaderView(stickyHeader);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyDiffLogger.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.util.Log;\n\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\n/**\n * This data observer can be registered with an Epoxy adapter or controller to log all item change\n * events. This may be useful to use in debug builds in order to observe model updates and monitor\n * for issues.\n * <p>\n * You may want to look for unexpected item updates to catch improper hashCode/equals\n * implementations in your models.\n * <p>\n * Additionally, you may want to look for frequent or unnecessary updates as an opportunity for\n * optimization.\n */\npublic class EpoxyDiffLogger extends AdapterDataObserver {\n  private final String tag;\n\n  public EpoxyDiffLogger(String tag) {\n    this.tag = tag;\n  }\n\n  @Override\n  public void onItemRangeChanged(int positionStart, int itemCount) {\n    Log.d(tag, \"Item range changed. Start: \" + positionStart + \" Count: \" + itemCount);\n  }\n\n  @Override\n  public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {\n    if (payload == null) {\n      onItemRangeChanged(positionStart, itemCount);\n    } else {\n      Log.d(tag,\n          \"Item range changed with payloads. Start: \" + positionStart + \" Count: \" + itemCount);\n    }\n  }\n\n  @Override\n  public void onItemRangeInserted(int positionStart, int itemCount) {\n    Log.d(tag, \"Item range inserted. Start: \" + positionStart + \" Count: \" + itemCount);\n  }\n\n  @Override\n  public void onItemRangeRemoved(int positionStart, int itemCount) {\n    Log.d(tag, \"Item range removed. Start: \" + positionStart + \" Count: \" + itemCount);\n  }\n\n  @Override\n  public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\n    Log.d(tag, \"Item moved. From: \" + fromPosition + \" To: \" + toPosition);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyDragCallback.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\n/**\n * For use with {@link EpoxyModelTouchCallback}\n */\npublic interface EpoxyDragCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T> {\n\n  /**\n   * Called when the view switches from an idle state to a dragged state, as the user begins a drag\n   * interaction with it. You can use this callback to modify the view to indicate it is being\n   * dragged.\n   * <p>\n   * This is the first callback in the lifecycle of a drag event.\n   *\n   * @param model           The model representing the view that is being dragged\n   * @param itemView        The view that is being dragged\n   * @param adapterPosition The adapter position of the model\n   */\n  void onDragStarted(T model, View itemView, int adapterPosition);\n\n  /**\n   * Called after {@link #onDragStarted(EpoxyModel, View, int)} when the dragged view is dropped to\n   * a new position. The EpoxyController will be updated automatically for you to reposition the\n   * models and notify the RecyclerView of the change.\n   * <p>\n   * You MUST use this callback to modify your data backing the models to reflect the change.\n   * <p>\n   * The next callback in the drag lifecycle will be {@link #onDragStarted(EpoxyModel, View, int)}\n   *\n   * @param modelBeingMoved The model representing the view that was moved\n   * @param itemView        The view that was moved\n   * @param fromPosition    The adapter position that the model came from\n   * @param toPosition      The new adapter position of the model\n   */\n  void onModelMoved(int fromPosition, int toPosition, T modelBeingMoved, View itemView);\n\n  /**\n   * Called after {@link #onDragStarted(EpoxyModel, View, int)} when the view being dragged is\n   * released. If the view was dragged to a new, valid location then {@link #onModelMoved(int, int,\n   * EpoxyModel, View)} will be called before this and the view will settle to the new location.\n   * Otherwise the view will animate back to its original position.\n   * <p>\n   * You can use this callback to modify the view as it animates back into position.\n   * <p>\n   * {@link BaseEpoxyTouchCallback#clearView(EpoxyModel, View)} will be called after this, when the\n   * view has finished animating. Final cleanup of the view should be done there.\n   *\n   * @param model    The model representing the view that is being released\n   * @param itemView The view that was being dragged\n   */\n  void onDragReleased(T model, View itemView);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyHolder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Used in conjunction with {@link com.airbnb.epoxy.EpoxyModelWithHolder} to provide a view holder\n * pattern when binding to a model.\n */\npublic abstract class EpoxyHolder {\n\n  public EpoxyHolder(@NonNull ViewParent parent) {\n    this();\n  }\n\n  public EpoxyHolder() {\n  }\n\n  /**\n   * Called when this holder is created, with the view that it should hold. You can use this\n   * opportunity to find views by id, and do any other initialization you need. This is called only\n   * once for the lifetime of the class.\n   *\n   * @param itemView A view inflated from the layout provided by\n   * {@link EpoxyModelWithHolder#getLayout()}\n   */\n  protected abstract void bindView(@NonNull View itemView);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyItemSpacingDecorator.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.graphics.Rect;\nimport android.view.View;\n\nimport androidx.annotation.Px;\nimport androidx.core.view.ViewCompat;\nimport androidx.recyclerview.widget.GridLayoutManager;\nimport androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.RecyclerView.LayoutManager;\nimport androidx.recyclerview.widget.RecyclerView.State;\n\n/**\n * Modifies item spacing in a recycler view so that items are equally spaced no matter where they\n * are on the grid. Only designed to work with standard linear or grid layout managers.\n */\npublic class EpoxyItemSpacingDecorator extends RecyclerView.ItemDecoration {\n  private int pxBetweenItems;\n  private boolean verticallyScrolling;\n  private boolean horizontallyScrolling;\n  private boolean firstItem;\n  private boolean lastItem;\n  private boolean grid;\n\n  private boolean isFirstItemInRow;\n  private boolean fillsLastSpan;\n  private boolean isInFirstRow;\n  private boolean isInLastRow;\n\n  public EpoxyItemSpacingDecorator() {\n    this(0);\n  }\n\n  public EpoxyItemSpacingDecorator(@Px int pxBetweenItems) {\n    setPxBetweenItems(pxBetweenItems);\n  }\n\n  public void setPxBetweenItems(@Px int pxBetweenItems) {\n    this.pxBetweenItems = pxBetweenItems;\n  }\n\n  @Px\n  public int getPxBetweenItems() {\n    return pxBetweenItems;\n  }\n\n  @Override\n  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {\n    // Zero everything out for the common case\n    outRect.setEmpty();\n\n    int position = parent.getChildAdapterPosition(view);\n    if (position == RecyclerView.NO_POSITION) {\n      // View is not shown\n      return;\n    }\n\n    RecyclerView.LayoutManager layout = parent.getLayoutManager();\n    calculatePositionDetails(parent, position, layout);\n\n    boolean left = useLeftPadding();\n    boolean right = useRightPadding();\n    boolean top = useTopPadding();\n    boolean bottom = useBottomPadding();\n\n    if (shouldReverseLayout(layout, horizontallyScrolling)) {\n      if (horizontallyScrolling) {\n        boolean temp = left;\n        left = right;\n        right = temp;\n      } else {\n        boolean temp = top;\n        top = bottom;\n        bottom = temp;\n      }\n    }\n\n    // Divided by two because it is applied to the left side of one item and the right of another\n    // to add up to the total desired space\n    int padding = pxBetweenItems / 2;\n    outRect.right = right ? padding : 0;\n    outRect.left = left ? padding : 0;\n    outRect.top = top ? padding : 0;\n    outRect.bottom = bottom ? padding : 0;\n  }\n\n  private void calculatePositionDetails(RecyclerView parent, int position, LayoutManager layout) {\n    int itemCount = parent.getAdapter().getItemCount();\n    firstItem = position == 0;\n    lastItem = position == itemCount - 1;\n    horizontallyScrolling = layout.canScrollHorizontally();\n    verticallyScrolling = layout.canScrollVertically();\n    grid = layout instanceof GridLayoutManager;\n\n    if (grid) {\n      GridLayoutManager grid = (GridLayoutManager) layout;\n      final SpanSizeLookup spanSizeLookup = grid.getSpanSizeLookup();\n      int spanSize = spanSizeLookup.getSpanSize(position);\n      int spanCount = grid.getSpanCount();\n      int spanIndex = spanSizeLookup.getSpanIndex(position, spanCount);\n      isFirstItemInRow = spanIndex == 0;\n      fillsLastSpan = spanIndex + spanSize == spanCount;\n      isInFirstRow = isInFirstRow(position, spanSizeLookup, spanCount);\n      isInLastRow =\n          !isInFirstRow && isInLastRow(position, itemCount, spanSizeLookup, spanCount);\n    }\n  }\n\n  private static boolean shouldReverseLayout(LayoutManager layout, boolean horizontallyScrolling) {\n    boolean reverseLayout =\n        layout instanceof LinearLayoutManager && ((LinearLayoutManager) layout).getReverseLayout();\n    boolean rtl = layout.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;\n    if (horizontallyScrolling && rtl) {\n      // This is how linearlayout checks if it should reverse layout in #resolveShouldLayoutReverse\n      reverseLayout = !reverseLayout;\n    }\n\n    return reverseLayout;\n  }\n\n  private boolean useBottomPadding() {\n    if (grid) {\n      return (horizontallyScrolling && !fillsLastSpan)\n          || (verticallyScrolling && !isInLastRow);\n    }\n\n    return verticallyScrolling && !lastItem;\n  }\n\n  private boolean useTopPadding() {\n    if (grid) {\n      return (horizontallyScrolling && !isFirstItemInRow)\n          || (verticallyScrolling && !isInFirstRow);\n    }\n\n    return verticallyScrolling && !firstItem;\n  }\n\n  private boolean useRightPadding() {\n    if (grid) {\n      return (horizontallyScrolling && !isInLastRow)\n          || (verticallyScrolling && !fillsLastSpan);\n    }\n\n    return horizontallyScrolling && !lastItem;\n  }\n\n  private boolean useLeftPadding() {\n    if (grid) {\n      return (horizontallyScrolling && !isInFirstRow)\n          || (verticallyScrolling && !isFirstItemInRow);\n    }\n\n    return horizontallyScrolling && !firstItem;\n  }\n\n  private static boolean isInFirstRow(int position, SpanSizeLookup spanSizeLookup, int spanCount) {\n    int totalSpan = 0;\n    for (int i = 0; i <= position; i++) {\n      totalSpan += spanSizeLookup.getSpanSize(i);\n      if (totalSpan > spanCount) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  private static boolean isInLastRow(int position, int itemCount, SpanSizeLookup spanSizeLookup,\n      int spanCount) {\n    int totalSpan = 0;\n    for (int i = itemCount - 1; i >= position; i--) {\n      totalSpan += spanSizeLookup.getSpanSize(i);\n      if (totalSpan > spanCount) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.airbnb.epoxy.EpoxyController.ModelInterceptorCallback;\nimport com.airbnb.epoxy.VisibilityState.Visibility;\n\nimport java.util.List;\n\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.Px;\n\nimport static com.airbnb.epoxy.IdUtils.hashLong64Bit;\nimport static com.airbnb.epoxy.IdUtils.hashString64Bit;\n\n/**\n * Helper to bind data to a view using a builder style. The parameterized type should extend\n * Android's View or EpoxyHolder.\n *\n * @see EpoxyModelWithHolder\n * @see EpoxyModelWithView\n */\npublic abstract class EpoxyModel<T> {\n\n  /**\n   * Counts how many of these objects are created, so that each new object can have a unique id .\n   * Uses negative values so that these autogenerated ids don't clash with database ids that may be\n   * set with {@link #id(long)}\n   */\n  private static long idCounter = -1;\n\n  /**\n   * An id that can be used to uniquely identify this {@link EpoxyModel} for use in RecyclerView\n   * stable ids. It defaults to a unique id for this object instance, if you want to maintain the\n   * same id across instances use {@link #id(long)}\n   */\n  private long id;\n  @LayoutRes private int layout;\n  private boolean shown = true;\n  /**\n   * Set to true once this model is diffed in an adapter. Used to ensure that this model's id\n   * doesn't change after being diffed.\n   */\n  boolean addedToAdapter;\n  /**\n   * The first controller this model was added to. A reference is kept in debug mode in order to run\n   * validations. The model is allowed to be added to other controllers, but we only keep a\n   * reference to the first.\n   */\n  private EpoxyController firstControllerAddedTo;\n  /**\n   * Models are staged when they are changed. This allows them to be automatically added when they\n   * are done being changed (eg the next model is changed/added or buildModels finishes). It is only\n   * allowed for AutoModels, and only if implicit adding is enabled.\n   */\n  EpoxyController controllerToStageTo;\n  private boolean currentlyInInterceptors;\n  private int hashCodeWhenAdded;\n  private boolean hasDefaultId;\n  @Nullable private SpanSizeOverrideCallback spanSizeOverride;\n\n  protected EpoxyModel(long id) {\n    id(id);\n  }\n\n  public EpoxyModel() {\n    this(idCounter--);\n    hasDefaultId = true;\n  }\n\n  boolean hasDefaultId() {\n    return hasDefaultId;\n  }\n\n  /**\n   * Get the view type to associate with this model in the recyclerview. For models that use a\n   * layout resource, the view type is simply the layout resource value by default.\n   * <p>\n   * If this returns 0 Epoxy will assign a unique view type for this model at run time.\n   *\n   * @see androidx.recyclerview.widget.RecyclerView.Adapter#getItemViewType(int)\n   */\n  protected int getViewType() {\n    return getLayout();\n  }\n\n  /**\n   * Create and return a new instance of a view for this model. By default a view is created by\n   * inflating the layout resource.\n   */\n  public View buildView(@NonNull ViewGroup parent) {\n    return LayoutInflater.from(parent.getContext()).inflate(getLayout(), parent, false);\n  }\n\n  /**\n   * Hook that is called before {@link #bind(Object)}. This is similar to\n   * {@link GeneratedModel#handlePreBind(EpoxyViewHolder, Object, int)}, but is intended for\n   * subclasses of EpoxyModel to hook into rather than for generated code to hook into.\n   * Overriding preBind is useful to capture state before the view changes, e.g. for animations.\n   *\n   * @param previouslyBoundModel This is a model with the same id that was previously bound. You can\n   *                             compare this previous model with the current one to see exactly\n   *                             what changed.\n   *                             <p>\n   *                             This model and the previously bound model are guaranteed to have\n   *                             the same id, but will not necessarily be of the same type depending\n   *                             on your implementation of {@link EpoxyController#buildModels()}.\n   *                             With common usage patterns of Epoxy they should be the same type,\n   *                             and will only differ if you are using different model classes with\n   *                             the same id.\n   *                             <p>\n   *                             Comparing the newly bound model with the previous model allows you\n   *                             to be more intelligent when binding your view. This may help you\n   *                             optimize view binding, or make it easier to work with animations.\n   *                             <p>\n   *                             If the new model and the previous model have the same view type\n   *                             (given by {@link EpoxyModel#getViewType()}), and if you are using\n   *                             the default ReyclerView item animator, the same view will be\n   *                             reused. This means that you only need to update the view to reflect\n   *                             the data that changed. If you are using a custom item animator then\n   *                             the view will be the same if the animator returns true in\n   *                             canReuseUpdatedViewHolder.\n   *                             <p>\n   *                             This previously bound model is taken as a payload from the diffing\n   *                             process, and follows the same general conditions for all\n   *                             recyclerview change payloads.\n   */\n  public void preBind(@NonNull T view, @Nullable EpoxyModel<?> previouslyBoundModel) {\n\n  }\n\n  /**\n   * Binds the current data to the given view. You should bind all fields including unset/empty\n   * fields to ensure proper recycling.\n   */\n  public void bind(@NonNull T view) {\n\n  }\n\n  /**\n   * Similar to {@link #bind(Object)}, but provides a non null, non empty list of payloads\n   * describing what changed. This is the payloads list specified in the adapter's notifyItemChanged\n   * method. This is a useful optimization to allow you to only change part of a view instead of\n   * updating the whole thing, which may prevent unnecessary layout calls. If there are no payloads\n   * then {@link #bind(Object)} is called instead. This will only be used if the model is used with\n   * an {@link EpoxyAdapter}\n   */\n  public void bind(@NonNull T view, @NonNull List<Object> payloads) {\n    bind(view);\n  }\n\n  /**\n   * Similar to {@link #bind(Object)}, but provides a non null model which was previously bound to\n   * this view. This will only be called if the model is used with an {@link EpoxyController}.\n   *\n   * @param previouslyBoundModel This is a model with the same id that was previously bound. You can\n   *                             compare this previous model with the current one to see exactly\n   *                             what changed.\n   *                             <p>\n   *                             This model and the previously bound model are guaranteed to have\n   *                             the same id, but will not necessarily be of the same type depending\n   *                             on your implementation of {@link EpoxyController#buildModels()}.\n   *                             With common usage patterns of Epoxy they should be the same type,\n   *                             and will only differ if you are using different model classes with\n   *                             the same id.\n   *                             <p>\n   *                             Comparing the newly bound model with the previous model allows you\n   *                             to be more intelligent when binding your view. This may help you\n   *                             optimize view binding, or make it easier to work with animations.\n   *                             <p>\n   *                             If the new model and the previous model have the same view type\n   *                             (given by {@link EpoxyModel#getViewType()}), and if you are using\n   *                             the default ReyclerView item animator, the same view will be\n   *                             reused. This means that you only need to update the view to reflect\n   *                             the data that changed. If you are using a custom item animator then\n   *                             the view will be the same if the animator returns true in\n   *                             canReuseUpdatedViewHolder.\n   *                             <p>\n   *                             This previously bound model is taken as a payload from the diffing\n   *                             process, and follows the same general conditions for all\n   *                             recyclerview change payloads.\n   */\n  public void bind(@NonNull T view, @NonNull EpoxyModel<?> previouslyBoundModel) {\n    bind(view);\n  }\n\n  /**\n   * Called when the view bound to this model is recycled. Subclasses can override this if their\n   * view should release resources when it's recycled.\n   * <p>\n   * Note that {@link #bind(Object)} can be called multiple times without an unbind call in between\n   * if the view has remained on screen to be reused across item changes. This means that you should\n   * not rely on unbind to clear a view or model's state before bind is called again.\n   *\n   * @see EpoxyAdapter#onViewRecycled(EpoxyViewHolder)\n   */\n  public void unbind(@NonNull T view) {\n  }\n\n  /**\n   * TODO link to the wiki\n   *\n   * @see OnVisibilityStateChanged annotation\n   */\n  public void onVisibilityStateChanged(@Visibility int visibilityState, @NonNull T view) {\n  }\n\n  /**\n   * TODO link to the wiki\n   *\n   * @see OnVisibilityChanged annotation\n   */\n  public void onVisibilityChanged(\n      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleHeight,\n      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleWidth,\n      @Px int visibleHeight,\n      @Px int visibleWidth,\n      @NonNull T view\n  ) {\n  }\n\n  public long id() {\n    return id;\n  }\n\n  /**\n   * Override the default id in cases where the data subject naturally has an id, like an object\n   * from a database. This id can only be set before the model is added to the adapter, it is an\n   * error to change the id after that.\n   */\n  public EpoxyModel<T> id(long id) {\n    if ((addedToAdapter || firstControllerAddedTo != null) && id != this.id) {\n      throw new IllegalEpoxyUsage(\n          \"Cannot change a model's id after it has been added to the adapter.\");\n    }\n\n    hasDefaultId = false;\n    this.id = id;\n    return this;\n  }\n\n  /**\n   * Use multiple numbers as the id for this model. Useful when you don't have a single long that\n   * represents a unique id.\n   * <p>\n   * This hashes the numbers, so there is a tiny risk of collision with other ids.\n   */\n  public EpoxyModel<T> id(@Nullable Number... ids) {\n    long result = 0;\n    if (ids != null) {\n      for (@Nullable Number id : ids) {\n        result = 31 * result + hashLong64Bit(id == null ? 0 : id.hashCode());\n      }\n    }\n    return id(result);\n  }\n\n  /**\n   * Use two numbers as the id for this model. Useful when you don't have a single long that\n   * represents a unique id.\n   * <p>\n   * This hashes the two numbers, so there is a tiny risk of collision with other ids.\n   */\n  public EpoxyModel<T> id(long id1, long id2) {\n    long result = hashLong64Bit(id1);\n    result = 31 * result + hashLong64Bit(id2);\n    return id(result);\n  }\n\n  /**\n   * Use a string as the model id. Useful for models that don't clearly map to a numerical id. This\n   * is preferable to using {@link String#hashCode()} because that is a 32 bit hash and this is a 64\n   * bit hash, giving better spread and less chance of collision with other ids.\n   * <p>\n   * Since this uses a hashcode method to convert the String to a long there is a very small chance\n   * that you may have a collision with another id. Assuming an even spread of hashcodes, and\n   * several hundred models in the adapter, there would be roughly 1 in 100 trillion chance of a\n   * collision. (http://preshing.com/20110504/hash-collision-probabilities/)\n   *\n   * @see IdUtils#hashString64Bit(CharSequence)\n   */\n  public EpoxyModel<T> id(@Nullable CharSequence key) {\n    id(hashString64Bit(key));\n    return this;\n  }\n\n  /**\n   * Use several strings to define the id of the model.\n   * <p>\n   * Similar to {@link #id(CharSequence)}, but with additional strings.\n   */\n  public EpoxyModel<T> id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    long result = hashString64Bit(key);\n    if (otherKeys != null) {\n      for (CharSequence otherKey : otherKeys) {\n        result = 31 * result + hashString64Bit(otherKey);\n      }\n    }\n    return id(result);\n  }\n\n  /**\n   * Set an id that is namespaced with a string. This is useful when you need to show models of\n   * multiple types, side by side and don't want to risk id collisions.\n   * <p>\n   * Since this uses a hashcode method to convert the String to a long there is a very small chance\n   * that you may have a collision with another id. Assuming an even spread of hashcodes, and\n   * several hundred models in the adapter, there would be roughly 1 in 100 trillion chance of a\n   * collision. (http://preshing.com/20110504/hash-collision-probabilities/)\n   *\n   * @see IdUtils#hashString64Bit(CharSequence)\n   * @see IdUtils#hashLong64Bit(long)\n   */\n  public EpoxyModel<T> id(@Nullable CharSequence key, long id) {\n    long result = hashString64Bit(key);\n    result = 31 * result + hashLong64Bit(id);\n    id(result);\n    return this;\n  }\n\n  /**\n   * Return the default layout resource to be used when creating views for this model. The resource\n   * will be inflated to create a view for the model; additionally the layout int is used as the\n   * views type in the RecyclerView.\n   * <p>\n   * This can be left unimplemented if you use the {@link EpoxyModelClass} annotation to define a\n   * layout.\n   * <p>\n   * This default value can be overridden with {@link #layout(int)} at runtime to change the layout\n   * dynamically.\n   */\n  @LayoutRes\n  protected abstract int getDefaultLayout();\n\n  @NonNull\n  public EpoxyModel<T> layout(@LayoutRes int layoutRes) {\n    onMutation();\n    layout = layoutRes;\n    return this;\n  }\n\n  @LayoutRes\n  public final int getLayout() {\n    if (layout == 0) {\n      return getDefaultLayout();\n    }\n\n    return layout;\n  }\n\n  /**\n   * Sets fields of the model to default ones.\n   */\n  @NonNull\n  public EpoxyModel<T> reset() {\n    onMutation();\n\n    layout = 0;\n    shown = true;\n\n    return this;\n  }\n\n  /**\n   * Add this model to the given controller. Can only be called from inside {@link\n   * EpoxyController#buildModels()}.\n   */\n  public void addTo(@NonNull EpoxyController controller) {\n    controller.addInternal(this);\n  }\n\n  /**\n   * Add this model to the given controller if the condition is true. Can only be called from inside\n   * {@link EpoxyController#buildModels()}.\n   */\n  public void addIf(boolean condition, @NonNull EpoxyController controller) {\n    if (condition) {\n      addTo(controller);\n    } else if (controllerToStageTo != null) {\n      // Clear this model from staging since it failed the add condition. If this model wasn't\n      // staged (eg not changed before addIf was called, then we need to make sure to add the\n      // previously staged model.\n      controllerToStageTo.clearModelFromStaging(this);\n      controllerToStageTo = null;\n    }\n  }\n\n  /**\n   * Add this model to the given controller if the {@link AddPredicate} return true. Can only be\n   * called from inside {@link EpoxyController#buildModels()}.\n   */\n  public void addIf(@NonNull AddPredicate predicate, @NonNull EpoxyController controller) {\n    addIf(predicate.addIf(), controller);\n  }\n\n  /**\n   * @see #addIf(AddPredicate, EpoxyController)\n   */\n  public interface AddPredicate {\n    boolean addIf();\n  }\n\n  /**\n   * This is used internally by generated models to turn on validation checking when\n   * \"validateEpoxyModelUsage\" is enabled and the model is used with an {@link EpoxyController}.\n   */\n  protected final void addWithDebugValidation(@NonNull EpoxyController controller) {\n    if (controller == null) {\n      throw new IllegalArgumentException(\"Controller cannot be null\");\n    }\n\n    if (controller.isModelAddedMultipleTimes(this)) {\n      throw new IllegalEpoxyUsage(\n          \"This model was already added to the controller at position \"\n              + controller.getFirstIndexOfModelInBuildingList(this));\n    }\n\n    if (firstControllerAddedTo == null) {\n      firstControllerAddedTo = controller;\n\n      // We save the current hashCode so we can compare it to the hashCode at later points in time\n      // in order to validate that it doesn't change and enforce mutability.\n      hashCodeWhenAdded = hashCode();\n\n      // The one time it is valid to change the model is during an interceptor callback. To support\n      // that we need to update the hashCode after interceptors have been run.\n      // The model can be added to multiple controllers, but we only allow an interceptor change\n      // the first time, since after that it will have been added to an adapter.\n      controller.addAfterInterceptorCallback(new ModelInterceptorCallback() {\n        @Override\n        public void onInterceptorsStarted(EpoxyController controller) {\n          currentlyInInterceptors = true;\n        }\n\n        @Override\n        public void onInterceptorsFinished(EpoxyController controller) {\n          hashCodeWhenAdded = EpoxyModel.this.hashCode();\n          currentlyInInterceptors = false;\n        }\n      });\n    }\n  }\n\n  boolean isDebugValidationEnabled() {\n    return firstControllerAddedTo != null;\n  }\n\n  /**\n   * This is used internally by generated models to do validation checking when\n   * \"validateEpoxyModelUsage\" is enabled and the model is used with an {@link EpoxyController}.\n   * This method validates that it is ok to change this model. It is only valid if the model hasn't\n   * yet been added, or the change is being done from an {@link EpoxyController.Interceptor}\n   * callback.\n   * <p>\n   * This is also used to stage the model for implicitly adding it, if it is an AutoModel and\n   * implicit adding is enabled.\n   */\n  protected final void onMutation() {\n    // The model may be added to multiple controllers, in which case if it was already diffed\n    // and added to an adapter in one controller we don't want to even allow interceptors\n    // from changing the model in a different controller\n    if (isDebugValidationEnabled() && !currentlyInInterceptors) {\n      throw new ImmutableModelException(this,\n          getPosition(firstControllerAddedTo, this));\n    }\n\n    if (controllerToStageTo != null) {\n      controllerToStageTo.setStagedModel(this);\n    }\n  }\n\n  private static int getPosition(@NonNull EpoxyController controller,\n      @NonNull EpoxyModel<?> model) {\n    // If the model was added to multiple controllers, or was removed from the controller and then\n    // modified, this won't be correct. But those should be very rare cases that we don't need to\n    // worry about\n    if (controller.isBuildingModels()) {\n      return controller.getFirstIndexOfModelInBuildingList(model);\n    }\n\n    return controller.getAdapter().getModelPosition(model);\n  }\n\n  /**\n   * This is used internally by generated models to do validation checking when\n   * \"validateEpoxyModelUsage\" is enabled and the model is used with a {@link EpoxyController}. This\n   * method validates that the model's hashCode hasn't been changed since it was added to the\n   * controller. This is similar to {@link #onMutation()}, but that method is only used for\n   * specific model changes such as calling a setter. By checking the hashCode, this method allows\n   * us to catch more subtle changes, such as through setting a field directly or through changing\n   * an object that is set on the model.\n   */\n  protected final void validateStateHasNotChangedSinceAdded(String descriptionOfChange,\n      int modelPosition) {\n    if (isDebugValidationEnabled()\n        && !currentlyInInterceptors\n        && hashCodeWhenAdded != hashCode()) {\n      throw new ImmutableModelException(this, descriptionOfChange, modelPosition);\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof EpoxyModel)) {\n      return false;\n    }\n\n    EpoxyModel<?> that = (EpoxyModel<?>) o;\n\n    if (id != that.id) {\n      return false;\n    }\n    if (getViewType() != that.getViewType()) {\n      return false;\n    }\n    return shown == that.shown;\n  }\n\n  @Override\n  public int hashCode() {\n    int result = (int) (id ^ (id >>> 32));\n    result = 31 * result + getViewType();\n    result = 31 * result + (shown ? 1 : 0);\n    return result;\n  }\n\n  /**\n   * Subclasses can override this if they want their view to take up more than one span in a grid\n   * layout.\n   *\n   * @param totalSpanCount The number of spans in the grid\n   * @param position       The position of the model\n   * @param itemCount      The total number of items in the adapter\n   */\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return 1;\n  }\n\n  public EpoxyModel<T> spanSizeOverride(@Nullable SpanSizeOverrideCallback spanSizeCallback) {\n    this.spanSizeOverride = spanSizeCallback;\n    return this;\n  }\n\n  public interface SpanSizeOverrideCallback {\n    int getSpanSize(int totalSpanCount, int position, int itemCount);\n  }\n\n  /**\n   * Returns the actual span size of this model, using the {@link SpanSizeOverrideCallback} if one\n   * was set, otherwise using the value from {@link #getSpanSize(int, int, int)}\n   */\n  public final int spanSize(int totalSpanCount, int position, int itemCount) {\n    if (spanSizeOverride != null) {\n      return spanSizeOverride.getSpanSize(totalSpanCount, position, itemCount);\n    }\n\n    return getSpanSize(totalSpanCount, position, itemCount);\n  }\n\n  /**\n   * Change the visibility of the model so that it's view is shown. This only works if the model is\n   * used in {@link EpoxyAdapter} or a {@link EpoxyModelGroup}, but is not supported in {@link\n   * EpoxyController}\n   */\n  @NonNull\n  public EpoxyModel<T> show() {\n    return show(true);\n  }\n\n  /**\n   * Change the visibility of the model's view. This only works if the model is\n   * used in {@link EpoxyAdapter} or a {@link EpoxyModelGroup}, but is not supported in {@link\n   * EpoxyController}\n   */\n  @NonNull\n  public EpoxyModel<T> show(boolean show) {\n    onMutation();\n    shown = show;\n    return this;\n  }\n\n  /**\n   * Change the visibility of the model so that it's view is hidden. This only works if the model is\n   * used in {@link EpoxyAdapter} or a {@link EpoxyModelGroup}, but is not supported in {@link\n   * EpoxyController}\n   */\n  @NonNull\n  public EpoxyModel<T> hide() {\n    return show(false);\n  }\n\n  /**\n   * Whether the model's view should be shown on screen. If false it won't be inflated and drawn,\n   * and will be like it was never added to the recycler view.\n   */\n  public boolean isShown() {\n    return shown;\n  }\n\n  /**\n   * Whether the adapter should save the state of the view bound to this model.\n   */\n  public boolean shouldSaveViewState() {\n    return false;\n  }\n\n  /**\n   * Called if the RecyclerView failed to recycle this model's view. You can take this opportunity\n   * to clear the animation(s) that affect the View's transient state and return <code>true</code>\n   * so that the View can be recycled. Keep in mind that the View in question is already removed\n   * from the RecyclerView.\n   *\n   * @return True if the View should be recycled, false otherwise\n   * @see EpoxyAdapter#onFailedToRecycleView(androidx.recyclerview.widget.RecyclerView.ViewHolder)\n   */\n  public boolean onFailedToRecycleView(@NonNull T view) {\n    return false;\n  }\n\n  /**\n   * Called when this model's view is attached to the window.\n   *\n   * @see EpoxyAdapter#onViewAttachedToWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder)\n   */\n  public void onViewAttachedToWindow(@NonNull T view) {\n\n  }\n\n  /**\n   * Called when this model's view is detached from the the window.\n   *\n   * @see EpoxyAdapter#onViewDetachedFromWindow(androidx.recyclerview.widget.RecyclerView\n   * .ViewHolder)\n   */\n  public void onViewDetachedFromWindow(@NonNull T view) {\n\n  }\n\n  @Override\n  public String toString() {\n    return getClass().getSimpleName() + \"{\"\n        + \"id=\" + id\n        + \", viewType=\" + getViewType()\n        + \", shown=\" + shown\n        + \", addedToAdapter=\" + addedToAdapter\n        + '}';\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\nimport android.view.ViewStub;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.annotation.CallSuper;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * An {@link EpoxyModel} that contains other models, and allows you to combine those models in\n * whatever view configuration you want.\n * <p>\n * The constructors take a list of models and a layout resource. The layout must have a viewgroup as\n * its top level view; it determines how the view of each model is laid out. There are two ways to\n * specify this\n * <p>\n * 1. Leave the viewgroup empty. The view for each model will be inflated and added in order. This\n * works fine if you don't need to include any other views, your model views don't need their layout\n * params changed, and your views don't need ids (eg for saving state).\n * <p>\n * Alternatively you can have nested view groups, with the innermost viewgroup given the id\n * \"epoxy_model_group_child_container\" to mark it as the viewgroup that should have the model views\n * added to it. The viewgroup marked with this id should be empty. This allows you to nest\n * viewgroups, such as a LinearLayout inside of a CardView.\n * <p>\n * 2. Include a {@link ViewStub} for each of the models in the list. There should be at least as\n * many view stubs as models. Extra stubs will be ignored. Each model will have its view replace the\n * stub in order of the view stub's position in the view group. That is, the view group's children\n * will be iterated through in order. The first view stub found will be used for the first model in\n * the models list, the second view stub will be used for the second model, and so on. A depth first\n * recursive search through nested viewgroups is done to find these viewstubs.\n * <p>\n * The layout can be of any ViewGroup subclass, and can have arbitrary other child views besides the\n * view stubs. It can arrange the views and view stubs however is needed.\n * <p>\n * Any layout param options set on the view stubs will be transferred to the corresponding model\n * view by default. If you want a model to keep the layout params from it's own layout resource you\n * can override {@link #useViewStubLayoutParams(EpoxyModel, int)}\n * <p>\n * If you want to override the id used for a model's view you can set {@link\n * ViewStub#setInflatedId(int)} via xml. That id will be transferred over to the view taking that\n * stub's place. This is necessary if you want your model to save view state, since without this the\n * model's view won't have an id to associate the saved state with.\n * <p>\n * By default this model inherits the same id as the first model in the list. Call {@link #id(long)}\n * to override that if needed.\n * <p>\n * When a model group is recycled, its child views are automatically recycled to a pool that is\n * shared with all other model groups in the activity. This enables model groups to more efficiently\n * manage their children. The shared pool is cleaned up when the activity is destroyed.\n */\n@SuppressWarnings(\"rawtypes\")\npublic class EpoxyModelGroup extends EpoxyModelWithHolder<ModelGroupHolder> {\n\n  protected final List<EpoxyModel<?>> models;\n\n  private boolean shouldSaveViewStateDefault = false;\n\n  @Nullable\n  private Boolean shouldSaveViewState = null;\n\n  /**\n   * @param layoutRes The layout to use with these models.\n   * @param models    The models that will be used to bind the views in the given layout.\n   */\n  public EpoxyModelGroup(@LayoutRes int layoutRes, Collection<? extends EpoxyModel<?>> models) {\n    this(layoutRes, new ArrayList<>(models));\n  }\n\n  /**\n   * @param layoutRes The layout to use with these models.\n   * @param models    The models that will be used to bind the views in the given layout.\n   */\n  public EpoxyModelGroup(@LayoutRes int layoutRes, EpoxyModel<?>... models) {\n    this(layoutRes, new ArrayList<>(Arrays.asList(models)));\n  }\n\n  /**\n   * @param layoutRes The layout to use with these models.\n   * @param models    The models that will be used to bind the views in the given layout.\n   */\n  private EpoxyModelGroup(@LayoutRes int layoutRes, List<EpoxyModel<?>> models) {\n    if (models.isEmpty()) {\n      throw new IllegalArgumentException(\"Models cannot be empty\");\n    }\n\n    this.models = models;\n    layout(layoutRes);\n    id(models.get(0).id());\n\n    boolean saveState = false;\n    for (EpoxyModel<?> model : models) {\n      if (model.shouldSaveViewState()) {\n        saveState = true;\n        break;\n      }\n    }\n    // By default we save view state if any of the models need to save state.\n    shouldSaveViewStateDefault = saveState;\n  }\n\n  /**\n   * Constructor use for DSL\n   */\n  protected EpoxyModelGroup() {\n    models = new ArrayList<>();\n    shouldSaveViewStateDefault = false;\n  }\n\n  /**\n   * Constructor use for DSL\n   */\n  protected EpoxyModelGroup(@LayoutRes int layoutRes) {\n    this();\n    layout(layoutRes);\n  }\n\n  protected void addModel(@NonNull EpoxyModel<?> model) {\n    // By default we save view state if any of the models need to save state.\n    shouldSaveViewStateDefault |= model.shouldSaveViewState();\n    models.add(model);\n  }\n\n  @CallSuper\n  @Override\n  public void bind(@NonNull ModelGroupHolder holder) {\n    iterateModels(holder, new IterateModelsCallback() {\n      @Override\n      public void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex) {\n        setViewVisibility(model, viewHolder);\n        viewHolder.bind(model, null, Collections.emptyList(), modelIndex);\n      }\n    });\n  }\n\n  @CallSuper\n  @Override\n  public void bind(@NonNull ModelGroupHolder holder, @NonNull final List<Object> payloads) {\n    iterateModels(holder, new IterateModelsCallback() {\n      @Override\n      public void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex) {\n        setViewVisibility(model, viewHolder);\n        viewHolder.bind(model, null, Collections.emptyList(), modelIndex);\n      }\n    });\n  }\n\n  @Override\n  public void bind(@NonNull ModelGroupHolder holder, @NonNull EpoxyModel<?> previouslyBoundModel) {\n    if (!(previouslyBoundModel instanceof EpoxyModelGroup)) {\n      bind(holder);\n      return;\n    }\n\n    final EpoxyModelGroup previousGroup = (EpoxyModelGroup) previouslyBoundModel;\n\n    iterateModels(holder, new IterateModelsCallback() {\n      @Override\n      public void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex) {\n        setViewVisibility(model, viewHolder);\n\n        if (modelIndex < previousGroup.models.size()) {\n          EpoxyModel<?> previousModel = previousGroup.models.get(modelIndex);\n          if (previousModel.id() == model.id()) {\n            viewHolder.bind(model, previousModel, Collections.emptyList(), modelIndex);\n            return;\n          }\n        }\n\n        viewHolder.bind(model, null, Collections.emptyList(), modelIndex);\n      }\n    });\n  }\n\n  private static void setViewVisibility(EpoxyModel model, EpoxyViewHolder viewHolder) {\n    if (model.isShown()) {\n      viewHolder.itemView.setVisibility(View.VISIBLE);\n    } else {\n      viewHolder.itemView.setVisibility(View.GONE);\n    }\n  }\n\n  @CallSuper\n  @Override\n  public void unbind(@NonNull ModelGroupHolder holder) {\n    holder.unbindGroup();\n  }\n\n  @CallSuper\n  @Override\n  public void onViewAttachedToWindow(ModelGroupHolder holder) {\n    iterateModels(holder, new IterateModelsCallback() {\n      @Override\n      public void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex) {\n        //noinspection unchecked\n        model.onViewAttachedToWindow(viewHolder.objectToBind());\n      }\n    });\n  }\n\n  @CallSuper\n  @Override\n  public void onViewDetachedFromWindow(ModelGroupHolder holder) {\n    iterateModels(holder, new IterateModelsCallback() {\n      @Override\n      public void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex) {\n        //noinspection unchecked\n        model.onViewDetachedFromWindow(viewHolder.objectToBind());\n      }\n    });\n  }\n\n  private void iterateModels(ModelGroupHolder holder, IterateModelsCallback callback) {\n    holder.bindGroupIfNeeded(this);\n    int modelCount = models.size();\n\n    for (int i = 0; i < modelCount; i++) {\n      callback.onModel(models.get(i), holder.getViewHolders().get(i), i);\n    }\n  }\n\n  private interface IterateModelsCallback {\n    void onModel(EpoxyModel model, EpoxyViewHolder viewHolder, int modelIndex);\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    // Defaults to using the span size of the first model. Override this if you need to customize it\n    return models.get(0).spanSize(totalSpanCount, position, itemCount);\n  }\n\n  @Override\n  protected final int getDefaultLayout() {\n    throw new UnsupportedOperationException(\n        \"You should set a layout with layout(...) instead of using this.\");\n  }\n\n  @NonNull\n  public EpoxyModelGroup shouldSaveViewState(boolean shouldSaveViewState) {\n    onMutation();\n    this.shouldSaveViewState = shouldSaveViewState;\n    return this;\n  }\n\n  @Override\n  public boolean shouldSaveViewState() {\n    // By default state is saved if any of the models have saved state enabled.\n    // Override this if you need custom behavior.\n    if (shouldSaveViewState != null) {\n      return shouldSaveViewState;\n    } else {\n      return shouldSaveViewStateDefault;\n    }\n  }\n\n  /**\n   * Whether the layout params set on the view stub for the given model should be carried over to\n   * the model's view. Default is true\n   * <p>\n   * Set this to false if you want the layout params on the model's layout resource to be kept.\n   *\n   * @param model         The model who's view is being created\n   * @param modelPosition The position of the model in the models list\n   */\n  protected boolean useViewStubLayoutParams(EpoxyModel<?> model, int modelPosition) {\n    return true;\n  }\n\n  @Override\n  protected final ModelGroupHolder createNewHolder(@NonNull ViewParent parent) {\n    return new ModelGroupHolder(parent);\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof EpoxyModelGroup)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n\n    EpoxyModelGroup that = (EpoxyModelGroup) o;\n\n    return models.equals(that.models);\n  }\n\n  @Override\n  public int hashCode() {\n    int result = super.hashCode();\n    result = 31 * result + models.hashCode();\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelTouchCallback.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.graphics.Canvas;\nimport android.view.View;\n\nimport com.airbnb.viewmodeladapter.R;\n\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.ItemTouchHelper;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * A wrapper around {@link androidx.recyclerview.widget.ItemTouchHelper.Callback} to enable\n * easier touch support when working with Epoxy models.\n * <p>\n * For simplicity you can use {@link EpoxyTouchHelper} to set up touch handling via this class for\n * you instead of using this class directly. However, you may choose to use this class directly with\n * your own {@link ItemTouchHelper} if you need extra flexibility or customization.\n */\npublic abstract class EpoxyModelTouchCallback<T extends EpoxyModel>\n    extends EpoxyTouchHelperCallback implements EpoxyDragCallback<T>, EpoxySwipeCallback<T> {\n\n  private static final int TOUCH_DEBOUNCE_MILLIS = 300;\n\n  @Nullable private final EpoxyController controller;\n  private final Class<T> targetModelClass;\n  private EpoxyViewHolder holderBeingDragged;\n  private EpoxyViewHolder holderBeingSwiped;\n\n  public EpoxyModelTouchCallback(@Nullable EpoxyController controller, Class<T> targetModelClass) {\n    this.controller = controller;\n    this.targetModelClass = targetModelClass;\n  }\n\n  @Override\n  protected int getMovementFlags(RecyclerView recyclerView, EpoxyViewHolder viewHolder) {\n    EpoxyModel<?> model = viewHolder.getModel();\n\n    // If multiple touch callbacks are registered on the recyclerview (to support combinations of\n    // dragging and dropping) then we won't want to enable anything if another\n    // callback has a view actively selected.\n    boolean isOtherCallbackActive =\n        holderBeingDragged == null\n            && holderBeingSwiped == null\n            && recyclerViewHasSelection(recyclerView);\n\n    if (!isOtherCallbackActive && isTouchableModel(model)) {\n      //noinspection unchecked\n      return getMovementFlagsForModel((T) model, viewHolder.getAdapterPosition());\n    } else {\n      return 0;\n    }\n  }\n\n  @Override\n  protected boolean canDropOver(RecyclerView recyclerView, EpoxyViewHolder current,\n      EpoxyViewHolder target) {\n    // By default we don't allow dropping on a model that isn't a drag target\n    return isTouchableModel(target.getModel());\n  }\n\n  protected boolean isTouchableModel(EpoxyModel<?> model) {\n    return targetModelClass.isInstance(model);\n  }\n\n  @Override\n  protected boolean onMove(RecyclerView recyclerView, EpoxyViewHolder viewHolder,\n      EpoxyViewHolder target) {\n\n    if (controller == null) {\n      throw new IllegalStateException(\n          \"A controller must be provided in the constructor if dragging is enabled\");\n    }\n\n    int fromPosition = viewHolder.getAdapterPosition();\n    int toPosition = target.getAdapterPosition();\n    controller.moveModel(fromPosition, toPosition);\n\n    EpoxyModel<?> model = viewHolder.getModel();\n    if (!isTouchableModel(model)) {\n      throw new IllegalStateException(\n          \"A model was dragged that is not a valid target: \" + model.getClass());\n    }\n\n    //noinspection unchecked\n    onModelMoved(fromPosition, toPosition, (T) model, viewHolder.itemView);\n    return true;\n  }\n\n  @Override\n  public void onModelMoved(int fromPosition, int toPosition, T modelBeingMoved, View itemView) {\n\n  }\n\n  @Override\n  protected void onSwiped(EpoxyViewHolder viewHolder, int direction) {\n    EpoxyModel<?> model = viewHolder.getModel();\n    View view = viewHolder.itemView;\n    int position = viewHolder.getAdapterPosition();\n\n    if (!isTouchableModel(model)) {\n      throw new IllegalStateException(\n          \"A model was swiped that is not a valid target: \" + model.getClass());\n    }\n\n    //noinspection unchecked\n    onSwipeCompleted((T) model, view, position, direction);\n  }\n\n  @Override\n  public void onSwipeCompleted(T model, View itemView, int position, int direction) {\n\n  }\n\n  @Override\n  protected void onSelectedChanged(@Nullable EpoxyViewHolder viewHolder, int actionState) {\n    super.onSelectedChanged(viewHolder, actionState);\n\n    if (viewHolder != null) {\n      EpoxyModel<?> model = viewHolder.getModel();\n      if (!isTouchableModel(model)) {\n        throw new IllegalStateException(\n            \"A model was selected that is not a valid target: \" + model.getClass());\n      }\n\n      markRecyclerViewHasSelection((RecyclerView) viewHolder.itemView.getParent());\n\n      if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {\n        holderBeingSwiped = viewHolder;\n        //noinspection unchecked\n        onSwipeStarted((T) model, viewHolder.itemView, viewHolder.getAdapterPosition());\n      } else if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {\n        holderBeingDragged = viewHolder;\n        //noinspection unchecked\n        onDragStarted((T) model, viewHolder.itemView, viewHolder.getAdapterPosition());\n      }\n    } else if (holderBeingDragged != null) {\n      //noinspection unchecked\n      onDragReleased((T) holderBeingDragged.getModel(), holderBeingDragged.itemView);\n      holderBeingDragged = null;\n    } else if (holderBeingSwiped != null) {\n      //noinspection unchecked\n      onSwipeReleased((T) holderBeingSwiped.getModel(), holderBeingSwiped.itemView);\n      holderBeingSwiped = null;\n    }\n  }\n\n  private void markRecyclerViewHasSelection(RecyclerView recyclerView) {\n    recyclerView.setTag(R.id.epoxy_touch_helper_selection_status, Boolean.TRUE);\n  }\n\n  private boolean recyclerViewHasSelection(RecyclerView recyclerView) {\n    return recyclerView.getTag(R.id.epoxy_touch_helper_selection_status) != null;\n  }\n\n  private void clearRecyclerViewSelectionMarker(RecyclerView recyclerView) {\n    recyclerView.setTag(R.id.epoxy_touch_helper_selection_status, null);\n  }\n\n  @Override\n  public void onSwipeStarted(T model, View itemView, int adapterPosition) {\n\n  }\n\n  @Override\n  public void onSwipeReleased(T model, View itemView) {\n\n  }\n\n  @Override\n  public void onDragStarted(T model, View itemView, int adapterPosition) {\n\n  }\n\n  @Override\n  public void onDragReleased(T model, View itemView) {\n\n  }\n\n  @Override\n  protected void clearView(final RecyclerView recyclerView, EpoxyViewHolder viewHolder) {\n    super.clearView(recyclerView, viewHolder);\n    //noinspection unchecked\n    clearView((T) viewHolder.getModel(), viewHolder.itemView);\n\n    // If multiple touch helpers are in use, one touch helper can pick up buffered touch inputs\n    // immediately after another touch event finishes. This leads to things like a view being\n    // selected for drag when another view finishes its swipe off animation. To prevent that we\n    // keep the recyclerview marked as having an active selection for a brief period after a\n    // touch event ends.\n    recyclerView.postDelayed(new Runnable() {\n      @Override\n      public void run() {\n        clearRecyclerViewSelectionMarker(recyclerView);\n      }\n    }, TOUCH_DEBOUNCE_MILLIS);\n  }\n\n  @Override\n  public void clearView(T model, View itemView) {\n\n  }\n\n  @Override\n  protected void onChildDraw(Canvas c, RecyclerView recyclerView, EpoxyViewHolder viewHolder,\n      float dX, float dY, int actionState, boolean isCurrentlyActive) {\n    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);\n\n    EpoxyModel<?> model;\n    // It’s possible for a touch helper to still draw if the item is being removed, which means it\n    // has technically be unbound by that point. getModel will throw an exception in this case.\n    try {\n      model = viewHolder.getModel();\n    } catch (IllegalStateException ignored) {\n      return;\n    }\n\n    if (!isTouchableModel(model)) {\n      throw new IllegalStateException(\n          \"A model was selected that is not a valid target: \" + model.getClass());\n    }\n\n    View itemView = viewHolder.itemView;\n\n    float swipeProgress;\n    if (Math.abs(dX) > Math.abs(dY)) {\n      swipeProgress = dX / itemView.getWidth();\n    } else {\n      swipeProgress = dY / itemView.getHeight();\n    }\n\n    // Clamp to 1/-1 in the case of side padding where the view can be swiped extra\n    float clampedProgress = Math.max(-1f, Math.min(1f, swipeProgress));\n\n    //noinspection unchecked\n    onSwipeProgressChanged((T) model, itemView, clampedProgress, c);\n  }\n\n  @Override\n  public void onSwipeProgressChanged(T model, View itemView, float swipeProgress,\n      Canvas canvas) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelWithHolder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewParent;\n\nimport com.airbnb.epoxy.VisibilityState.Visibility;\n\nimport java.util.List;\n\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Px;\n\n/**\n * A version of {@link com.airbnb.epoxy.EpoxyModel} that allows you to use a view holder pattern\n * instead of a specific view when binding to your model.\n */\npublic abstract class EpoxyModelWithHolder<T extends EpoxyHolder> extends EpoxyModel<T> {\n\n  public EpoxyModelWithHolder() {\n  }\n\n  public EpoxyModelWithHolder(long id) {\n    super(id);\n  }\n\n  /** This should return a new instance of your {@link com.airbnb.epoxy.EpoxyHolder} class. */\n  protected abstract T createNewHolder(@NonNull ViewParent parent);\n\n  @Override\n  public void bind(@NonNull T holder) {\n    super.bind(holder);\n  }\n\n  @Override\n  public void bind(@NonNull T holder, @NonNull List<Object> payloads) {\n    super.bind(holder, payloads);\n  }\n\n  @Override\n  public void bind(@NonNull T holder, @NonNull EpoxyModel<?> previouslyBoundModel) {\n    super.bind(holder, previouslyBoundModel);\n  }\n\n  @Override\n  public void unbind(@NonNull T holder) {\n    super.unbind(holder);\n  }\n\n\n  @Override\n  public void onVisibilityStateChanged(@Visibility int visibilityState, @NonNull T holder) {\n    super.onVisibilityStateChanged(visibilityState, holder);\n  }\n\n  @Override\n  public void onVisibilityChanged(\n      @FloatRange(from = 0, to = 100) float percentVisibleHeight,\n      @FloatRange(from = 0, to = 100) float percentVisibleWidth,\n      @Px int visibleHeight, @Px int visibleWidth,\n      @NonNull T holder) {\n    super.onVisibilityChanged(\n        percentVisibleHeight, percentVisibleWidth,\n        visibleHeight, visibleWidth,\n        holder);\n  }\n\n  @Override\n  public boolean onFailedToRecycleView(T holder) {\n    return super.onFailedToRecycleView(holder);\n  }\n\n  @Override\n  public void onViewAttachedToWindow(T holder) {\n    super.onViewAttachedToWindow(holder);\n  }\n\n  @Override\n  public void onViewDetachedFromWindow(T holder) {\n    super.onViewDetachedFromWindow(holder);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelWithView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\n\n/**\n * A model that allows its view to be built programmatically instead of by inflating a layout\n * resource. Just implement {@link #buildView} so the adapter can create a new view for this model\n * when needed.\n * <p>\n * {@link #getViewType()} is used by the adapter to know how to reuse views for this model. This\n * means that all models that return the same type should be able to share the same view, and the\n * view won't be shared with models of any other type.\n * <p>\n * If it is left unimplemented then at runtime a unique view type will be created to use for all\n * models of that class. The generated view type will be negative so that it cannot collide with\n * values from resource files, which are used in normal Epoxy models. If you would like to share\n * the same view between models of different classes you can have those classes return the same view\n * type. A good way to manually create a view type value is by creating an R.id. value in an ids\n * resource file.\n */\npublic abstract class EpoxyModelWithView<T extends View> extends EpoxyModel<T> {\n\n  /**\n   * Get the view type associated with this model's view. Any models with the same view type will\n   * have views recycled between them.\n   *\n   * @see androidx.recyclerview.widget.RecyclerView.Adapter#getItemViewType(int)\n   */\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  /**\n   * Create and return a new instance of a view for this model. If no layout params are set on the\n   * returned view then default layout params will be used.\n   *\n   * @param parent The parent ViewGroup that the returned view will be added to.\n   */\n  @Override\n  public abstract T buildView(@NonNull ViewGroup parent);\n\n  @Override\n  protected final int getDefaultLayout() {\n    throw new UnsupportedOperationException(\n        \"Layout resources are unsupported. Views must be created with `buildView`\");\n  }\n\n  @Override\n  public EpoxyModel<T> layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\n        \"Layout resources are unsupported. Views must be created with `buildView`\");\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyRecyclerView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.util.AttributeSet\nimport android.util.TypedValue\nimport android.view.ViewGroup\nimport androidx.annotation.CallSuper\nimport androidx.annotation.DimenRes\nimport androidx.annotation.Dimension\nimport androidx.annotation.Px\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.preload.EpoxyModelPreloader\nimport com.airbnb.epoxy.preload.EpoxyPreloader\nimport com.airbnb.epoxy.preload.PreloadErrorHandler\nimport com.airbnb.epoxy.preload.PreloadRequestHolder\nimport com.airbnb.epoxy.preload.ViewMetadata\nimport com.airbnb.viewmodeladapter.R\n\n/**\n * A RecyclerView implementation that makes for easier integration with Epoxy. The goal of this\n * class is to reduce boilerplate in setting up a RecyclerView by applying common defaults.\n * Additionally, several performance optimizations are made.\n *\n * Improvements in this class are:\n *\n * 1. A single view pool is automatically shared between all [EpoxyRecyclerView] instances in\n * the same activity. This should increase view recycling potential and increase performance when\n * nested RecyclerViews are used. See [.initViewPool].\n *\n * 2. A layout manager is automatically added with assumed defaults. See [createLayoutManager]\n *\n * 3. Fixed size is enabled if this view's size is MATCH_PARENT\n *\n * 4. If a [GridLayoutManager] is used this will automatically sync the span count with the\n * [EpoxyController]. See [syncSpanCount]\n *\n * 5. Helper methods like [withModels], [setModels], [buildModelsWith]\n * make it simpler to set up simple RecyclerViews.\n *\n * 6. Set an EpoxyController and build models in one step -\n * [setControllerAndBuildModels] or [withModels]\n *\n * 7. Support for automatic item spacing. See [.setItemSpacingPx]\n *\n * 8. Defaults for usage as a nested recyclerview are provided in [Carousel].\n *\n * 9. [setClipToPadding] is set to false by default since that behavior is commonly\n * desired in a scrolling list\n */\nopen class EpoxyRecyclerView @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : RecyclerView(context, attrs, defStyleAttr) {\n\n    protected val spacingDecorator = EpoxyItemSpacingDecorator()\n\n    private var epoxyController: EpoxyController? = null\n\n    /**\n     * The adapter that was removed because the RecyclerView was detached from the window. We save it\n     * so we can reattach it if the RecyclerView is reattached to window. This allows us to\n     * automatically restore the adapter, without risking leaking the RecyclerView if this view is\n     * never used again.\n     *\n     * Since the adapter is removed this recyclerview won't get adapter changes, but that's fine since\n     * the view isn't attached to window and isn't being drawn.\n     *\n     * This reference is cleared if another adapter is manually set, so we don't override the user's\n     * adapter choice.\n     *\n     * @see .setRemoveAdapterWhenDetachedFromWindow\n     */\n    private var removedAdapter: RecyclerView.Adapter<*>? = null\n\n    private var removeAdapterWhenDetachedFromWindow = true\n\n    private var delayMsWhenRemovingAdapterOnDetach: Int = DEFAULT_ADAPTER_REMOVAL_DELAY_MS\n\n    /**\n     * Tracks whether [.removeAdapterRunnable] has been posted to run\n     * later. This lets us know if we should cancel the runnable at certain times. This removes the\n     * overhead of needlessly attempting to remove the runnable when it isn't posted.\n     */\n    private var isRemoveAdapterRunnablePosted: Boolean = false\n    private val removeAdapterRunnable = Runnable {\n        if (isRemoveAdapterRunnablePosted) {\n            // Canceling a runnable doesn't work accurately when a view switches between\n            // attached/detached, so we manually check that this should still be run\n            isRemoveAdapterRunnablePosted = false\n            removeAdapter()\n        }\n    }\n\n    private val preloadScrollListeners: MutableList<EpoxyPreloader<*>> = mutableListOf()\n\n    private val preloadConfigs: MutableList<PreloadConfig<*, *, *>> = mutableListOf()\n\n    private class PreloadConfig<T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder>(\n        val maxPreload: Int,\n        val errorHandler: PreloadErrorHandler,\n        val preloader: EpoxyModelPreloader<T, U, P>,\n        val requestHolderFactory: () -> P\n    )\n\n    /**\n     * Setup a preloader to fetch content for a model's view before it is bound.\n     * This can be called multiple times if you would like to add separate preloaders\n     * for different models or content types.\n     *\n     * Preloaders are automatically attached and run, and are updated if the adapter changes.\n     *\n     * @param maxPreloadDistance How many items to prefetch ahead of the last bound item\n     * @param errorHandler Called when the preloader encounters an exception. We recommend throwing an\n     * exception in debug builds, and logging an error in production.\n     * @param preloader Describes how view content for the EpoxyModel should be preloaded\n     * @param requestHolderFactory Should create and return a new [PreloadRequestHolder] each time it is invoked\n     */\n    fun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> addPreloader(\n        maxPreloadDistance: Int = 3,\n        errorHandler: PreloadErrorHandler,\n        preloader: EpoxyModelPreloader<T, U, P>,\n        requestHolderFactory: () -> P\n    ) {\n        preloadConfigs.add(\n            PreloadConfig(\n                maxPreloadDistance,\n                errorHandler,\n                preloader,\n                requestHolderFactory\n            )\n        )\n\n        updatePreloaders()\n    }\n\n    /**\n     * Clears all preloaders added with [addPreloader]\n     */\n    fun clearPreloaders() {\n        preloadConfigs.clear()\n        updatePreloaders()\n    }\n\n    private fun updatePreloaders() {\n        preloadScrollListeners.forEach { removeOnScrollListener(it) }\n        preloadScrollListeners.clear()\n        val currAdapter = adapter ?: return\n\n        preloadConfigs.forEach { preloadConfig ->\n\n            if (currAdapter is EpoxyAdapter) {\n                EpoxyPreloader.with(\n                    currAdapter,\n                    preloadConfig.requestHolderFactory,\n                    preloadConfig.errorHandler,\n                    preloadConfig.maxPreload,\n                    listOf(preloadConfig.preloader)\n                )\n            } else {\n                epoxyController?.let {\n                    EpoxyPreloader.with(\n                        it,\n                        preloadConfig.requestHolderFactory,\n                        preloadConfig.errorHandler,\n                        preloadConfig.maxPreload,\n                        listOf(preloadConfig.preloader)\n                    )\n                }\n            }?.let {\n                preloadScrollListeners.add(it)\n                addOnScrollListener(it)\n            }\n        }\n    }\n\n    /**\n     * If set to true, any adapter set on this recyclerview will be removed when this view is detached\n     * from the window. This is useful to prevent leaking a reference to this RecyclerView. This is\n     * useful in cases where the same adapter can be used across multiple views (views which can be\n     * destroyed and recreated), such as with fragments. In that case the adapter is not necessarily\n     * cleared from previous RecyclerViews, so the adapter will continue to hold a reference to those\n     * views and leak them. More details at https://github.com/airbnb/epoxy/wiki/Avoiding-Memory-Leaks#parent-view\n     *\n     * The default is true, but you can disable this if you don't want your adapter detached\n     * automatically.\n     *\n     * If the adapter is removed via this setting, it will be re-set on the RecyclerView if the\n     * RecyclerView is re-attached to the window at a later point.\n     */\n    fun setRemoveAdapterWhenDetachedFromWindow(removeAdapterWhenDetachedFromWindow: Boolean) {\n        this.removeAdapterWhenDetachedFromWindow = removeAdapterWhenDetachedFromWindow\n    }\n\n    /**\n     * If [.setRemoveAdapterWhenDetachedFromWindow] is set to true, this is the delay\n     * in milliseconds between when [.onDetachedFromWindow] is called and when the adapter is\n     * actually removed.\n     *\n     * By default a delay of {@value #DEFAULT_ADAPTER_REMOVAL_DELAY_MS} ms is used so that view\n     * transitions can complete before the adapter is removed. Otherwise if the adapter is removed\n     * before transitions finish it can clear the screen and break the transition. A notable case is\n     * fragment transitions, in which the fragment view is detached from window before the transition\n     * ends.\n     */\n    fun setDelayMsWhenRemovingAdapterOnDetach(delayMsWhenRemovingAdapterOnDetach: Int) {\n        this.delayMsWhenRemovingAdapterOnDetach = delayMsWhenRemovingAdapterOnDetach\n    }\n\n    init {\n\n        if (attrs != null) {\n            val a = context.obtainStyledAttributes(\n                attrs, R.styleable.EpoxyRecyclerView,\n                defStyleAttr, 0\n            )\n            setItemSpacingPx(\n                a.getDimensionPixelSize(\n                    R.styleable.EpoxyRecyclerView_itemSpacing,\n                    0\n                )\n            )\n            a.recycle()\n        }\n\n        init()\n    }\n\n    @CallSuper\n    protected open fun init() {\n        clipToPadding = false\n        initViewPool()\n    }\n\n    /**\n     * Get or create a view pool to use for this RecyclerView. By default the same pool is shared for\n     * all [EpoxyRecyclerView] usages in the same Activity.\n     *\n     * @see .createViewPool\n     * @see .shouldShareViewPoolAcrossContext\n     */\n    private fun initViewPool() {\n        if (!shouldShareViewPoolAcrossContext()) {\n            setRecycledViewPool(createViewPool())\n            return\n        }\n\n        setRecycledViewPool(\n            ACTIVITY_RECYCLER_POOL.getPool(\n                getContextForSharedViewPool()\n            ) { createViewPool() }.viewPool\n        )\n    }\n\n    /**\n     * Attempts to find this view's parent Activity in order to share the view pool. If this view's\n     * `context` is a ContextWrapper it will continually unwrap it until it finds the Activity. If\n     * no Activity is found it will return the the view's context.\n     */\n    private fun getContextForSharedViewPool(): Context {\n        var workingContext = this.context\n        while (workingContext is ContextWrapper) {\n            if (workingContext is Activity) {\n                return workingContext\n            }\n            workingContext = workingContext.baseContext\n        }\n        return this.context\n    }\n\n    /**\n     * Create a new instance of a view pool to use with this recyclerview. By default a [ ] is used.\n     */\n    protected open fun createViewPool(): RecyclerView.RecycledViewPool {\n        return UnboundedViewPool()\n    }\n\n    /**\n     * To maximize view recycling by default we share the same view pool across all instances in the same Activity. This behavior can be disabled by returning\n     * false here.\n     */\n    open fun shouldShareViewPoolAcrossContext(): Boolean {\n        return true\n    }\n\n    override fun setLayoutParams(params: ViewGroup.LayoutParams) {\n        val isFirstParams = layoutParams == null\n        super.setLayoutParams(params)\n\n        if (isFirstParams) {\n            // Set a default layout manager if one was not set via xml\n            // We need layout params for this to guess at the right size and type\n            if (layoutManager == null) {\n                layoutManager = createLayoutManager()\n            }\n        }\n    }\n\n    /**\n     * Create a new [androidx.recyclerview.widget.RecyclerView.LayoutManager]\n     * instance to use for this RecyclerView.\n     *\n     * By default a LinearLayoutManager is used, and a reasonable default is chosen for scrolling\n     * direction based on layout params.\n     *\n     * If the RecyclerView is set to match parent size then the scrolling orientation is set to\n     * vertical and [.setHasFixedSize] is set to true.\n     *\n     * If the height is set to wrap_content then the scrolling orientation is set to horizontal, and\n     * [.setClipToPadding] is set to false.\n     */\n    protected open fun createLayoutManager(): RecyclerView.LayoutManager {\n        val layoutParams = layoutParams\n\n        // 0 represents matching constraints in a LinearLayout or ConstraintLayout\n        if (layoutParams.height == RecyclerView.LayoutParams.MATCH_PARENT || layoutParams.height == 0) {\n\n            if (layoutParams.width == RecyclerView.LayoutParams.MATCH_PARENT || layoutParams.width == 0) {\n                // If we are filling as much space as possible then we usually are fixed size\n                setHasFixedSize(true)\n            }\n\n            // A sane default is a vertically scrolling linear layout\n            return LinearLayoutManager(context)\n        } else {\n            // This is usually the case for horizontally scrolling carousels and should be a sane\n            // default\n            return LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)\n        }\n    }\n\n    override fun setLayoutManager(layout: RecyclerView.LayoutManager?) {\n        super.setLayoutManager(layout)\n        syncSpanCount()\n    }\n\n    /**\n     * If a grid layout manager is set we sync the span count between the layout and the epoxy\n     * adapter automatically.\n     */\n    private fun syncSpanCount() {\n        val layout = layoutManager\n        val controller = epoxyController\n        if (layout is GridLayoutManager && controller != null) {\n\n            if (controller.spanCount != layout.spanCount || layout.spanSizeLookup !== controller.spanSizeLookup) {\n                controller.spanCount = layout.spanCount\n                layout.spanSizeLookup = controller.spanSizeLookup\n            }\n        }\n    }\n\n    override fun requestLayout() {\n        // Grid layout manager calls this when the span count is changed. Its the easiest way to\n        // detect a span count change and update our controller accordingly.\n        syncSpanCount()\n        super.requestLayout()\n    }\n\n    fun setItemSpacingRes(@DimenRes itemSpacingRes: Int) {\n        setItemSpacingPx(resToPx(itemSpacingRes))\n    }\n\n    fun setItemSpacingDp(@Dimension(unit = Dimension.DP) dp: Int) {\n        setItemSpacingPx(dpToPx(dp))\n    }\n\n    /**\n     * Set a pixel value to use as spacing between items. If this is a positive number an item\n     * decoration will be added to space all items this far apart from each other. If the value is 0\n     * or negative no extra spacing will be used, and any previous spacing will be removed.\n     *\n     * This only works if a [LinearLayoutManager] or [GridLayoutManager] is used with this\n     * RecyclerView.\n     *\n     * This can also be set via the `app:itemSpacing` styleable attribute.\n     *\n     * @see .setItemSpacingDp\n     * @see .setItemSpacingRes\n     */\n    open fun setItemSpacingPx(@Px spacingPx: Int) {\n        removeItemDecoration(spacingDecorator)\n        spacingDecorator.pxBetweenItems = spacingPx\n\n        if (spacingPx > 0) {\n            addItemDecoration(spacingDecorator)\n        }\n    }\n\n    /**\n     * Set a list of [EpoxyModel]'s to show in this RecyclerView.\n     *\n     * Alternatively you can set an [EpoxyController] to handle building models dynamically.\n     *\n     * @see withModels\n     * @see setController\n     * @see setControllerAndBuildModels\n     * @see buildModelsWith\n     */\n\n    open fun setModels(models: List<EpoxyModel<*>>) {\n        val controller = (epoxyController as? SimpleEpoxyController)\n            ?: SimpleEpoxyController().also {\n                setController(it)\n            }\n\n        controller.setModels(models)\n    }\n\n    /**\n     * Set an EpoxyController to populate this RecyclerView. This does not make the controller build\n     * its models, that must be done separately via [requestModelBuild].\n     *\n     * Use this if you don't want [requestModelBuild] called automatically. Common cases\n     * are if you are using [TypedEpoxyController] (in which case you must call setData on the\n     * controller), or if you have not otherwise populated your controller's data yet.\n     *\n     * Otherwise if you want models built automatically for you use [setControllerAndBuildModels]\n     *\n     * The controller can be cleared with [clear]\n     *\n     * @see .setControllerAndBuildModels\n     * @see .buildModelsWith\n     * @see .setModels\n     */\n\n    fun setController(controller: EpoxyController) {\n        epoxyController = controller\n        adapter = controller.adapter\n        syncSpanCount()\n    }\n\n    /**\n     * Set an EpoxyController to populate this RecyclerView, and tell the controller to build\n     * models.\n     *\n     * The controller can be cleared with [clear]\n     *\n     * @see setController\n     * @see buildModelsWith\n     * @see setModels\n     */\n    fun setControllerAndBuildModels(controller: EpoxyController) {\n        controller.requestModelBuild()\n        setController(controller)\n    }\n\n    /**\n     * The simplest way to add models to the RecyclerView without needing to create an EpoxyController.\n     * This is intended for Kotlin usage, and has the EpoxyController as the lambda receiver so\n     * models can be added easily.\n     *\n     * Multiple calls to this will reuse the same underlying EpoxyController so views in the\n     * RecyclerView will be reused.\n     *\n     * The Java equivalent is [buildModelsWith].\n     */\n    fun withModels(buildModels: EpoxyController.() -> Unit) {\n        val controller = (epoxyController as? WithModelsController)\n            ?: WithModelsController().also { setController(it) }\n\n        controller.callback = buildModels\n        controller.requestModelBuild()\n    }\n\n    private class WithModelsController : EpoxyController() {\n        var callback: EpoxyController.() -> Unit = {}\n\n        override fun buildModels() {\n            callback(this)\n        }\n    }\n\n    /**\n     * Allows you to build models via a callback instead of needing to create a new EpoxyController\n     * class. This is useful if your models are simple and you would like to simply declare them in\n     * your activity/fragment.\n     *\n     * Multiple calls to this will reuse the same underlying EpoxyController so views in the\n     * RecyclerView will be reused.\n     *\n     * Another useful pattern is having your Activity or Fragment implement [ModelBuilderCallback].\n     *\n     * If you're using Kotlin, prefer [withModels].\n     *\n     * @see setController\n     * @see setControllerAndBuildModels\n     * @see setModels\n     */\n    fun buildModelsWith(callback: ModelBuilderCallback) {\n        val controller = (epoxyController as? ModelBuilderCallbackController)\n            ?: ModelBuilderCallbackController().also { setController(it) }\n\n        controller.callback = callback\n        controller.requestModelBuild()\n    }\n\n    private class ModelBuilderCallbackController : EpoxyController() {\n        var callback: ModelBuilderCallback = object : ModelBuilderCallback {\n            override fun buildModels(controller: EpoxyController) {\n            }\n        }\n\n        override fun buildModels() {\n            callback.buildModels(this)\n        }\n    }\n\n    /**\n     * A callback for creating models without needing a custom EpoxyController class. Used with [buildModelsWith]\n     */\n    interface ModelBuilderCallback {\n        /**\n         * Analagous to [EpoxyController.buildModels]. You should create new model instances and\n         * add them to the given controller. [AutoModel] cannot be used with models added this\n         * way.\n         */\n        fun buildModels(controller: EpoxyController)\n    }\n\n    /**\n     * Request that the currently set EpoxyController has its models rebuilt. You can use this to\n     * avoid saving your controller as a field.\n     *\n     * You cannot use this if your controller is a [TypedEpoxyController] or if you set\n     * models via [setModels]. In that case you must set data directly on the\n     * controller or set models again.\n     */\n    fun requestModelBuild() {\n        if (epoxyController == null) {\n            throw IllegalStateException(\"A controller must be set before requesting a model build.\")\n        }\n\n        if (epoxyController is SimpleEpoxyController) {\n            throw IllegalStateException(\"Models were set with #setModels, they can not be rebuilt.\")\n        }\n\n        epoxyController!!.requestModelBuild()\n    }\n\n    /**\n     * Clear the currently set EpoxyController or Adapter as well as any models that are displayed.\n     *\n     * Any pending requests to the EpoxyController to build models are canceled.\n     *\n     * Any existing child views are recycled to the view pool.\n     */\n    open fun clear() {\n        // The controller is cleared so the next time models are set we can create a fresh one.\n        epoxyController?.cancelPendingModelBuild()\n        epoxyController = null\n\n        // We use swapAdapter instead of setAdapter so that the view pool is not cleared.\n        // 'removeAndRecycleExistingViews=true' is used in case this is a nested recyclerview\n        // and we want to recycle the views back to a shared view pool\n        swapAdapter(null, true)\n    }\n\n    @Px\n    protected fun dpToPx(@Dimension(unit = Dimension.DP) dp: Int): Int {\n        return TypedValue\n            .applyDimension(\n                TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(),\n                resources.displayMetrics\n            ).toInt()\n    }\n\n    @Px\n    protected fun resToPx(@DimenRes itemSpacingRes: Int): Int {\n        return resources.getDimensionPixelOffset(itemSpacingRes)\n    }\n\n    override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {\n        super.setAdapter(adapter)\n\n        clearRemovedAdapterAndCancelRunnable()\n        updatePreloaders()\n    }\n\n    override fun swapAdapter(\n        adapter: RecyclerView.Adapter<*>?,\n        removeAndRecycleExistingViews: Boolean\n    ) {\n        super.swapAdapter(adapter, removeAndRecycleExistingViews)\n\n        clearRemovedAdapterAndCancelRunnable()\n        updatePreloaders()\n    }\n\n    public override fun onAttachedToWindow() {\n        super.onAttachedToWindow()\n\n        if (removedAdapter != null) {\n            // Restore the adapter that was removed when the view was detached from window\n            swapAdapter(removedAdapter, false)\n        }\n        clearRemovedAdapterAndCancelRunnable()\n    }\n\n    public override fun onDetachedFromWindow() {\n        super.onDetachedFromWindow()\n        preloadScrollListeners.forEach { it.cancelPreloadRequests() }\n\n        if (removeAdapterWhenDetachedFromWindow) {\n            if (delayMsWhenRemovingAdapterOnDetach > 0) {\n\n                isRemoveAdapterRunnablePosted = true\n                postDelayed(removeAdapterRunnable, delayMsWhenRemovingAdapterOnDetach.toLong())\n            } else {\n                removeAdapter()\n            }\n        }\n        clearPoolIfActivityIsDestroyed()\n    }\n\n    private fun removeAdapter() {\n        val currentAdapter = adapter\n        if (currentAdapter != null) {\n            // Clear the adapter so the adapter releases its reference to this RecyclerView.\n            // Views are recycled so they can return to a view pool (default behavior is to not recycle\n            // them).\n            swapAdapter(null, true)\n            // Keep a reference to the removed adapter so we can add it back if the recyclerview is\n            // attached again.\n            removedAdapter = currentAdapter\n        }\n\n        // Do this after clearing the adapter, since that sends views back to the pool\n        clearPoolIfActivityIsDestroyed()\n    }\n\n    private fun clearRemovedAdapterAndCancelRunnable() {\n        removedAdapter = null\n        if (isRemoveAdapterRunnablePosted) {\n            removeCallbacks(removeAdapterRunnable)\n            isRemoveAdapterRunnablePosted = false\n        }\n    }\n\n    private fun clearPoolIfActivityIsDestroyed() {\n        // Views in the pool hold context references which can keep the activity from being GC'd,\n        // plus they can hold significant memory resources. We should clear it asap after the pool\n        // is no longer needed - the main signal we use for this is that the activity is destroyed.\n        if (context.isActivityDestroyed()) {\n            recycledViewPool.clear()\n        }\n    }\n\n    companion object {\n        private const val DEFAULT_ADAPTER_REMOVAL_DELAY_MS = 2000\n\n        /**\n         * Store one unique pool per activity. They are cleared out when activities are destroyed, so this\n         * only needs to hold pools for active activities.\n         */\n        private val ACTIVITY_RECYCLER_POOL = ActivityRecyclerPool()\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxySwipeCallback.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.graphics.Canvas;\nimport android.view.View;\n\nimport androidx.recyclerview.widget.ItemTouchHelper;\n\n/**\n * For use with {@link EpoxyModelTouchCallback}\n */\npublic interface EpoxySwipeCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T> {\n\n  /**\n   * Called when the view switches from an idle state to a swiped state, as the user begins a swipe\n   * interaction with it. You can use this callback to modify the view to indicate it is being\n   * swiped.\n   * <p>\n   * This is the first callback made in the lifecycle of a swipe event.\n   *\n   * @param model           The model representing the view that is being swiped\n   * @param itemView        The view that is being swiped\n   * @param adapterPosition The adapter position of the model\n   */\n  void onSwipeStarted(T model, View itemView, int adapterPosition);\n\n  /**\n   * Once a view has begun swiping with {@link #onSwipeStarted(EpoxyModel, View, int)} it will\n   * receive this callback as the swipe distance changes. This can be called multiple times as the\n   * swipe interaction progresses.\n   *\n   * @param model         The model representing the view that is being swiped\n   * @param itemView      The view that is being swiped\n   * @param swipeProgress A float from -1 to 1 representing the percentage that the view has been\n   *                      swiped relative to its width. This will be positive if the view is being\n   *                      swiped to the right and negative if it is swiped to the left. For\n   *                      example,\n   * @param canvas        The canvas on which RecyclerView is drawing its children. You can draw to\n   *                      this to support custom swipe animations.\n   */\n  void onSwipeProgressChanged(T model, View itemView, float swipeProgress,\n      Canvas canvas);\n\n  /**\n   * Called when the user has released their touch on the view. If the displacement passed the swipe\n   * threshold then {@link #onSwipeCompleted(EpoxyModel, View, int, int)} will be called after this\n   * and the view will be animated off screen. Otherwise the view will animate back to its original\n   * position.\n   *\n   * @param model    The model representing the view that was being swiped\n   * @param itemView The view that was being swiped\n   */\n  void onSwipeReleased(T model, View itemView);\n\n  /**\n   * Called after {@link #onSwipeReleased(EpoxyModel, View)} if the swipe surpassed the threshold to\n   * be considered a full swipe. The view will now be animated off screen.\n   * <p>\n   * You MUST use this callback to remove this item from your backing data and request a model\n   * update.\n   * <p>\n   * {@link #clearView(EpoxyModel, View)} will be called after this.\n   *\n   * @param model     The model representing the view that was being swiped\n   * @param itemView  The view that was being swiped\n   * @param position  The adapter position of the model\n   * @param direction The direction that the view was swiped. Can be any of {@link\n   *                  ItemTouchHelper#LEFT}, {@link ItemTouchHelper#RIGHT}, {@link\n   *                  ItemTouchHelper#UP}, {@link ItemTouchHelper#DOWN} depending on what swipe\n   *                  directions were enabled.\n   */\n  void onSwipeCompleted(T model, View itemView, int position, int direction);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyTouchHelper.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.graphics.Canvas;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.ItemTouchHelper;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags;\n\n/**\n * A simple way to set up drag or swipe interactions with Epoxy.\n * <p>\n * Drag events work with the EpoxyController and automatically update the controller and\n * RecyclerView when an item is moved. You just need to implement a callback to update your data to\n * reflect the change.\n * <p>\n * Both swipe and drag events implement a small lifecycle to help you style the views as they are\n * moved. You can register callbacks for the lifecycle events you care about.\n * <p>\n * If you want to set up multiple drag and swipe rules for the same RecyclerView, you can use this\n * class multiple times to specify different targets or swipe and drag directions and callbacks.\n * <p>\n * If you want more control over configuration and handling, you can opt to not use this class and\n * instead you can implement {@link EpoxyModelTouchCallback} directly with your own {@link\n * ItemTouchHelper}. That class provides an interface that makes it easier to work with Epoxy models\n * and simplifies touch callbacks.\n * <p>\n * If you want even more control you can implement {@link EpoxyTouchHelperCallback}. This is just a\n * light layer over the normal RecyclerView touch callbacks, but it converts all view holders to\n * Epoxy view holders to remove some boilerplate for you.\n */\npublic abstract class EpoxyTouchHelper {\n\n  /**\n   * The entry point for setting up drag support.\n   *\n   * @param controller The EpoxyController with the models that will be dragged. The controller will\n   *                   be updated for you when a model is dragged and moved by a user's touch\n   *                   interaction.\n   */\n  public static DragBuilder initDragging(EpoxyController controller) {\n    return new DragBuilder(controller);\n  }\n\n  public static class DragBuilder {\n\n    private final EpoxyController controller;\n\n    private DragBuilder(EpoxyController controller) {\n      this.controller = controller;\n    }\n\n    /**\n     * The recyclerview that the EpoxyController has its adapter added to. An {@link\n     * androidx.recyclerview.widget.ItemTouchHelper} will be created and configured for you, and\n     * attached to this RecyclerView.\n     */\n    public DragBuilder2 withRecyclerView(RecyclerView recyclerView) {\n      return new DragBuilder2(controller, recyclerView);\n    }\n  }\n\n  public static class DragBuilder2 {\n\n    private final EpoxyController controller;\n    private final RecyclerView recyclerView;\n\n    private DragBuilder2(EpoxyController controller, RecyclerView recyclerView) {\n      this.controller = controller;\n      this.recyclerView = recyclerView;\n    }\n\n    /** Enable dragging vertically, up and down. */\n    public DragBuilder3 forVerticalList() {\n      return withDirections(ItemTouchHelper.UP | ItemTouchHelper.DOWN);\n    }\n\n    /** Enable dragging horizontally, left and right. */\n    public DragBuilder3 forHorizontalList() {\n      return withDirections(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);\n    }\n\n    /** Enable dragging in all directions. */\n    public DragBuilder3 forGrid() {\n      return withDirections(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT\n          | ItemTouchHelper.RIGHT);\n    }\n\n    /**\n     * Set custom movement flags to dictate which drag directions should be allowed.\n     * <p>\n     * Can be any of {@link ItemTouchHelper#LEFT}, {@link ItemTouchHelper#RIGHT}, {@link\n     * ItemTouchHelper#UP}, {@link ItemTouchHelper#DOWN}, {@link ItemTouchHelper#START}, {@link\n     * ItemTouchHelper#END}\n     * <p>\n     * Flags can be OR'd together to allow multiple directions.\n     */\n    public DragBuilder3 withDirections(int directionFlags) {\n      return new DragBuilder3(controller, recyclerView, makeMovementFlags(directionFlags, 0));\n    }\n  }\n\n  public static class DragBuilder3 {\n\n    private final EpoxyController controller;\n    private final RecyclerView recyclerView;\n    private final int movementFlags;\n\n    private DragBuilder3(EpoxyController controller, RecyclerView recyclerView, int movementFlags) {\n      this.controller = controller;\n      this.recyclerView = recyclerView;\n      this.movementFlags = movementFlags;\n    }\n\n    /**\n     * Set the type of Epoxy model that is draggable. This approach works well if you only have one\n     * draggable type.\n     */\n    public <U extends EpoxyModel> DragBuilder4<U> withTarget(Class<U> targetModelClass) {\n      List<Class<? extends EpoxyModel>> targetClasses = new ArrayList<>(1);\n      targetClasses.add(targetModelClass);\n\n      return new DragBuilder4<>(controller, recyclerView, movementFlags, targetModelClass,\n          targetClasses);\n    }\n\n    /**\n     * Specify which Epoxy model types are draggable. Use this if you have more than one type that\n     * is draggable.\n     * <p>\n     * If you only have one draggable type you should use {@link #withTarget(Class)}\n     */\n    public DragBuilder4<EpoxyModel> withTargets(Class<? extends EpoxyModel>... targetModelClasses) {\n      return new DragBuilder4<>(controller, recyclerView, movementFlags, EpoxyModel.class,\n          Arrays.asList(targetModelClasses));\n    }\n\n    /**\n     * Use this if all models in the controller should be draggable, and if there are multiple types\n     * of models in the controller.\n     * <p>\n     * If you only have one model type you should use {@link #withTarget(Class)}\n     */\n    public DragBuilder4<EpoxyModel> forAllModels() {\n      return withTarget(EpoxyModel.class);\n    }\n  }\n\n  public static class DragBuilder4<U extends EpoxyModel> {\n\n    private final EpoxyController controller;\n    private final RecyclerView recyclerView;\n    private final int movementFlags;\n    private final Class<U> targetModelClass;\n    private final List<Class<? extends EpoxyModel>> targetModelClasses;\n\n    private DragBuilder4(EpoxyController controller,\n        RecyclerView recyclerView, int movementFlags,\n        Class<U> targetModelClass, List<Class<? extends EpoxyModel>> targetModelClasses) {\n\n      this.controller = controller;\n      this.recyclerView = recyclerView;\n      this.movementFlags = movementFlags;\n      this.targetModelClass = targetModelClass;\n      this.targetModelClasses = targetModelClasses;\n    }\n\n    /**\n     * Set callbacks to handle drag actions and lifecycle events.\n     * <p>\n     * You MUST implement {@link DragCallbacks#onModelMoved(int, int, EpoxyModel,\n     * View)} to update your data to reflect an item move.\n     * <p>\n     * You can optionally implement the other callbacks to modify the view being dragged. This is\n     * useful if you want to change things like the view background, size, color, etc\n     *\n     * @return An {@link ItemTouchHelper} instance that has been initialized and attached to a\n     * recyclerview. The touch helper has already been fully set up and can be ignored, but you may\n     * want to hold a reference to it if you need to later detach the recyclerview to disable touch\n     * events via setting null on {@link ItemTouchHelper#attachToRecyclerView(RecyclerView)}\n     */\n    public ItemTouchHelper andCallbacks(final DragCallbacks<U> callbacks) {\n      ItemTouchHelper itemTouchHelper =\n          new ItemTouchHelper(new EpoxyModelTouchCallback<U>(controller, targetModelClass) {\n\n            @Override\n            public int getMovementFlagsForModel(U model, int adapterPosition) {\n              return movementFlags;\n            }\n\n            @Override\n            protected boolean isTouchableModel(EpoxyModel<?> model) {\n              boolean isTargetType = targetModelClasses.size() == 1\n                  ? super.isTouchableModel(model)\n                  : targetModelClasses.contains(model.getClass());\n\n              //noinspection unchecked\n              return isTargetType && callbacks.isDragEnabledForModel((U) model);\n            }\n\n            @Override\n            public void onDragStarted(U model, View itemView, int adapterPosition) {\n              callbacks.onDragStarted(model, itemView, adapterPosition);\n            }\n\n            @Override\n            public void onDragReleased(U model, View itemView) {\n              callbacks.onDragReleased(model, itemView);\n            }\n\n            @Override\n            public void onModelMoved(int fromPosition, int toPosition, U modelBeingMoved,\n                View itemView) {\n              callbacks.onModelMoved(fromPosition, toPosition, modelBeingMoved, itemView);\n            }\n\n            @Override\n            public void clearView(U model, View itemView) {\n              callbacks.clearView(model, itemView);\n            }\n          });\n\n      itemTouchHelper.attachToRecyclerView(recyclerView);\n\n      return itemTouchHelper;\n    }\n  }\n\n  public abstract static class DragCallbacks<T extends EpoxyModel>\n      implements EpoxyDragCallback<T> {\n\n    @Override\n    public void onDragStarted(T model, View itemView, int adapterPosition) {\n\n    }\n\n    @Override\n    public void onDragReleased(T model, View itemView) {\n\n    }\n\n    @Override\n    public abstract void onModelMoved(int fromPosition, int toPosition, T modelBeingMoved,\n        View itemView);\n\n    @Override\n    public void clearView(T model, View itemView) {\n\n    }\n\n    /**\n     * Whether the given model should be draggable.\n     * <p>\n     * True by default. You may override this to toggle draggability for a model.\n     */\n    public boolean isDragEnabledForModel(T model) {\n      return true;\n    }\n\n    @Override\n    public final int getMovementFlagsForModel(T model, int adapterPosition) {\n      // No-Op this is not used\n      return 0;\n    }\n  }\n\n  /**\n   * The entry point for setting up swipe support for a RecyclerView. The RecyclerView must be set\n   * with an Epoxy adapter or controller.\n   */\n  public static SwipeBuilder initSwiping(RecyclerView recyclerView) {\n    return new SwipeBuilder(recyclerView);\n  }\n\n  public static class SwipeBuilder {\n\n    private final RecyclerView recyclerView;\n\n    private SwipeBuilder(RecyclerView recyclerView) {\n      this.recyclerView = recyclerView;\n    }\n\n    /** Enable swiping right. */\n    public SwipeBuilder2 right() {\n      return withDirections(ItemTouchHelper.RIGHT);\n    }\n\n    /** Enable swiping left. */\n    public SwipeBuilder2 left() {\n      return withDirections(ItemTouchHelper.LEFT);\n    }\n\n    /** Enable swiping horizontally, left and right. */\n    public SwipeBuilder2 leftAndRight() {\n      return withDirections(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);\n    }\n\n    /**\n     * Set custom movement flags to dictate which swipe directions should be allowed.\n     * <p>\n     * Can be any of {@link ItemTouchHelper#LEFT}, {@link ItemTouchHelper#RIGHT}, {@link\n     * ItemTouchHelper#UP}, {@link ItemTouchHelper#DOWN}, {@link ItemTouchHelper#START}, {@link\n     * ItemTouchHelper#END}\n     * <p>\n     * Flags can be OR'd together to allow multiple directions.\n     */\n    public SwipeBuilder2 withDirections(int directionFlags) {\n      return new SwipeBuilder2(recyclerView, makeMovementFlags(0, directionFlags));\n    }\n  }\n\n  public static class SwipeBuilder2 {\n\n    private final RecyclerView recyclerView;\n    private final int movementFlags;\n\n    private SwipeBuilder2(RecyclerView recyclerView,\n        int movementFlags) {\n      this.recyclerView = recyclerView;\n      this.movementFlags = movementFlags;\n    }\n\n    /**\n     * Set the type of Epoxy model that is swipable. Use this if you only have one\n     * swipable type.\n     */\n    public <U extends EpoxyModel> SwipeBuilder3<U> withTarget(Class<U> targetModelClass) {\n      List<Class<? extends EpoxyModel>> targetClasses = new ArrayList<>(1);\n      targetClasses.add(targetModelClass);\n\n      return new SwipeBuilder3<>(recyclerView, movementFlags, targetModelClass,\n          targetClasses);\n    }\n\n    /**\n     * Specify which Epoxy model types are swipable. Use this if you have more than one type that\n     * is swipable.\n     * <p>\n     * If you only have one swipable type you should use {@link #withTarget(Class)}\n     */\n    public SwipeBuilder3<EpoxyModel> withTargets(\n        Class<? extends EpoxyModel>... targetModelClasses) {\n      return new SwipeBuilder3<>(recyclerView, movementFlags, EpoxyModel.class,\n          Arrays.asList(targetModelClasses));\n    }\n\n    /**\n     * Use this if all models in the controller should be swipable, and if there are multiple types\n     * of models in the controller.\n     * <p>\n     * If you only have one model type you should use {@link #withTarget(Class)}\n     */\n    public SwipeBuilder3<EpoxyModel> forAllModels() {\n      return withTarget(EpoxyModel.class);\n    }\n  }\n\n  public static class SwipeBuilder3<U extends EpoxyModel> {\n\n    private final RecyclerView recyclerView;\n    private final int movementFlags;\n    private final Class<U> targetModelClass;\n    private final List<Class<? extends EpoxyModel>> targetModelClasses;\n\n    private SwipeBuilder3(\n        RecyclerView recyclerView, int movementFlags,\n        Class<U> targetModelClass, List<Class<? extends EpoxyModel>> targetModelClasses) {\n\n      this.recyclerView = recyclerView;\n      this.movementFlags = movementFlags;\n      this.targetModelClass = targetModelClass;\n      this.targetModelClasses = targetModelClasses;\n    }\n\n    /**\n     * Set callbacks to handle swipe actions and lifecycle events.\n     * <p>\n     * You MUST implement {@link SwipeCallbacks#onSwipeCompleted(EpoxyModel, View, int, int)} to\n     * remove the swiped item from your data and request a model build.\n     * <p>\n     * You can optionally implement the other callbacks to modify the view as it is being swiped.\n     *\n     * @return An {@link ItemTouchHelper} instance that has been initialized and attached to a\n     * recyclerview. The touch helper has already been fully set up and can be ignored, but you may\n     * want to hold a reference to it if you need to later detach the recyclerview to disable touch\n     * events via setting null on {@link ItemTouchHelper#attachToRecyclerView(RecyclerView)}\n     */\n    public ItemTouchHelper andCallbacks(final SwipeCallbacks<U> callbacks) {\n      ItemTouchHelper itemTouchHelper =\n          new ItemTouchHelper(new EpoxyModelTouchCallback<U>(null, targetModelClass) {\n\n            @Override\n            public int getMovementFlagsForModel(U model, int adapterPosition) {\n              return movementFlags;\n            }\n\n            @Override\n            protected boolean isTouchableModel(EpoxyModel<?> model) {\n              boolean isTargetType = targetModelClasses.size() == 1\n                  ? super.isTouchableModel(model)\n                  : targetModelClasses.contains(model.getClass());\n\n              //noinspection unchecked\n              return isTargetType && callbacks.isSwipeEnabledForModel((U) model);\n            }\n\n            @Override\n            public void onSwipeStarted(U model, View itemView, int adapterPosition) {\n              callbacks.onSwipeStarted(model, itemView, adapterPosition);\n            }\n\n            @Override\n            public void onSwipeProgressChanged(U model, View itemView, float swipeProgress,\n                Canvas canvas) {\n              callbacks.onSwipeProgressChanged(model, itemView, swipeProgress, canvas);\n            }\n\n            @Override\n            public void onSwipeCompleted(U model, View itemView, int position, int direction) {\n              callbacks.onSwipeCompleted(model, itemView, position, direction);\n            }\n\n            @Override\n            public void onSwipeReleased(U model, View itemView) {\n              callbacks.onSwipeReleased(model, itemView);\n            }\n\n            @Override\n            public void clearView(U model, View itemView) {\n              callbacks.clearView(model, itemView);\n            }\n          });\n\n      itemTouchHelper.attachToRecyclerView(recyclerView);\n\n      return itemTouchHelper;\n    }\n  }\n\n  public abstract static class SwipeCallbacks<T extends EpoxyModel>\n      implements EpoxySwipeCallback<T> {\n\n    @Override\n    public void onSwipeStarted(T model, View itemView, int adapterPosition) {\n\n    }\n\n    @Override\n    public void onSwipeProgressChanged(T model, View itemView, float swipeProgress,\n        Canvas canvas) {\n\n    }\n\n    @Override\n    public abstract void onSwipeCompleted(T model, View itemView, int position, int direction);\n\n    @Override\n    public void onSwipeReleased(T model, View itemView) {\n\n    }\n\n    @Override\n    public void clearView(T model, View itemView) {\n\n    }\n\n    /**\n     * Whether the given model should be swipable.\n     * <p>\n     * True by default. You may override this to toggle swipabaility for a model.\n     */\n    public boolean isSwipeEnabledForModel(T model) {\n      return true;\n    }\n\n    @Override\n    public final int getMovementFlagsForModel(T model, int adapterPosition) {\n      // Not used\n      return 0;\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyTouchHelperCallback.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.graphics.Canvas\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.recyclerview.widget.RecyclerView.ViewHolder\n\n/**\n * A wrapper around [androidx.recyclerview.widget.ItemTouchHelper.Callback] to cast all\n * view holders to [com.airbnb.epoxy.EpoxyViewHolder] for simpler use with Epoxy.\n */\nabstract class EpoxyTouchHelperCallback : ItemTouchHelper.Callback() {\n\n    override fun getMovementFlags(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder\n    ): Int = getMovementFlags(recyclerView, viewHolder as EpoxyViewHolder)\n\n    /**\n     * @see getMovementFlags\n     */\n    protected abstract fun getMovementFlags(\n        recyclerView: RecyclerView,\n        viewHolder: EpoxyViewHolder\n    ): Int\n\n    override fun onMove(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        target: RecyclerView.ViewHolder\n    ): Boolean = onMove(recyclerView, viewHolder as EpoxyViewHolder, target as EpoxyViewHolder)\n\n    /**\n     * @see onMove\n     */\n    protected abstract fun onMove(\n        recyclerView: RecyclerView,\n        viewHolder: EpoxyViewHolder,\n        target: EpoxyViewHolder\n    ): Boolean\n\n    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int): Unit =\n        onSwiped(viewHolder as EpoxyViewHolder, direction)\n\n    /**\n     * @see onSwiped\n     */\n    protected abstract fun onSwiped(viewHolder: EpoxyViewHolder, direction: Int)\n\n    override fun canDropOver(\n        recyclerView: RecyclerView,\n        current: RecyclerView.ViewHolder,\n        target: RecyclerView.ViewHolder\n    ): Boolean = canDropOver(recyclerView, current as EpoxyViewHolder, target as EpoxyViewHolder)\n\n    /**\n     * @see canDropOver\n     */\n    protected open fun canDropOver(\n        recyclerView: RecyclerView,\n        current: EpoxyViewHolder,\n        target: EpoxyViewHolder\n    ): Boolean = super.canDropOver(recyclerView, current, target)\n\n    override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float =\n        getSwipeThreshold(viewHolder as EpoxyViewHolder)\n\n    /**\n     * @see getSwipeThreshold\n     */\n    protected open fun getSwipeThreshold(viewHolder: EpoxyViewHolder): Float =\n        super.getSwipeThreshold(viewHolder)\n\n    override fun getMoveThreshold(viewHolder: RecyclerView.ViewHolder): Float =\n        getMoveThreshold(viewHolder as EpoxyViewHolder)\n\n    /**\n     * @see getMoveThreshold\n     */\n    protected fun getMoveThreshold(viewHolder: EpoxyViewHolder): Float =\n        super.getMoveThreshold(viewHolder)\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun chooseDropTarget(\n        selected: RecyclerView.ViewHolder,\n        dropTargets: List<RecyclerView.ViewHolder>,\n        curX: Int,\n        curY: Int\n    ): EpoxyViewHolder? = chooseDropTarget(\n        selected as EpoxyViewHolder,\n        dropTargets as List<EpoxyViewHolder>,\n        curX,\n        curY\n    )\n\n    /**\n     * @see chooseDropTarget\n     */\n    protected fun chooseDropTarget(\n        selected: EpoxyViewHolder,\n        dropTargets: List<EpoxyViewHolder>,\n        curX: Int,\n        curY: Int\n    ): EpoxyViewHolder? =\n        super.chooseDropTarget(selected, dropTargets, curX, curY) as? EpoxyViewHolder\n\n    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int): Unit =\n        onSelectedChanged(viewHolder as EpoxyViewHolder?, actionState)\n\n    /**\n     * @see onSelectedChanged\n     */\n    protected open fun onSelectedChanged(viewHolder: EpoxyViewHolder?, actionState: Int): Unit =\n        super.onSelectedChanged(viewHolder, actionState)\n\n    override fun onMoved(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        fromPos: Int,\n        target: RecyclerView.ViewHolder,\n        toPos: Int,\n        x: Int,\n        y: Int\n    ): Unit = onMoved(\n        recyclerView,\n        viewHolder as EpoxyViewHolder,\n        fromPos,\n        target as EpoxyViewHolder,\n        toPos,\n        x,\n        y\n    )\n\n    /**\n     * @see onMoved\n     */\n    protected fun onMoved(\n        recyclerView: RecyclerView,\n        viewHolder: EpoxyViewHolder,\n        fromPos: Int,\n        target: EpoxyViewHolder,\n        toPos: Int,\n        x: Int,\n        y: Int\n    ): Unit = super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)\n\n    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Unit =\n        clearView(recyclerView, viewHolder as EpoxyViewHolder)\n\n    /**\n     * @see clearView\n     */\n    protected open fun clearView(recyclerView: RecyclerView, viewHolder: EpoxyViewHolder): Unit =\n        super.clearView(recyclerView, viewHolder)\n\n    override fun onChildDraw(\n        c: Canvas,\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        dX: Float,\n        dY: Float,\n        actionState: Int,\n        isCurrentlyActive: Boolean\n    ): Unit = onChildDraw(\n        c,\n        recyclerView,\n        viewHolder as EpoxyViewHolder,\n        dX,\n        dY,\n        actionState,\n        isCurrentlyActive\n    )\n\n    /**\n     * @see onChildDraw\n     */\n    protected open fun onChildDraw(\n        c: Canvas,\n        recyclerView: RecyclerView,\n        viewHolder: EpoxyViewHolder,\n        dX: Float,\n        dY: Float,\n        actionState: Int,\n        isCurrentlyActive: Boolean\n    ): Unit = super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)\n\n    override fun onChildDrawOver(\n        c: Canvas,\n        recyclerView: RecyclerView,\n        viewHolder: ViewHolder,\n        dX: Float,\n        dY: Float,\n        actionState: Int,\n        isCurrentlyActive: Boolean\n    ) {\n        onChildDrawOver(\n            c, recyclerView, viewHolder as? EpoxyViewHolder, dX, dY, actionState,\n            isCurrentlyActive\n        )\n    }\n\n    /**\n     * @see onChildDrawOver\n     */\n    protected fun onChildDrawOver(\n        c: Canvas,\n        recyclerView: RecyclerView,\n        viewHolder: EpoxyViewHolder?,\n        dX: Float,\n        dY: Float,\n        actionState: Int,\n        isCurrentlyActive: Boolean\n    ): Unit = super.onChildDrawOver(\n        c,\n        recyclerView,\n        viewHolder as ViewHolder,\n        dX,\n        dY,\n        actionState,\n        isCurrentlyActive\n    )\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyViewHolder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\n\nimport com.airbnb.epoxy.ViewHolderState.ViewState;\nimport com.airbnb.epoxy.VisibilityState.Visibility;\n\nimport java.util.List;\n\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.Px;\nimport androidx.recyclerview.widget.RecyclerView;\n\n@SuppressWarnings(\"WeakerAccess\")\npublic class EpoxyViewHolder extends RecyclerView.ViewHolder {\n  @SuppressWarnings(\"rawtypes\") private EpoxyModel epoxyModel;\n  private List<Object> payloads;\n  private EpoxyHolder epoxyHolder;\n  @Nullable ViewHolderState.ViewState initialViewState;\n\n  // Once the EpoxyHolder is created parent will be set to null.\n  private ViewParent parent;\n\n  public EpoxyViewHolder(ViewParent parent, View view, boolean saveInitialState) {\n    super(view);\n\n    this.parent = parent;\n    if (saveInitialState) {\n      // We save the initial state of the view when it is created so that we can reset this initial\n      // state before a model is bound for the first time. Otherwise the view may carry over\n      // state from a previously bound model.\n      initialViewState = new ViewState();\n      initialViewState.save(itemView);\n    }\n  }\n\n  void restoreInitialViewState() {\n    if (initialViewState != null) {\n      initialViewState.restore(itemView);\n    }\n  }\n\n  public void bind(@SuppressWarnings(\"rawtypes\") EpoxyModel model,\n      @Nullable EpoxyModel<?> previouslyBoundModel, List<Object> payloads, int position) {\n    this.payloads = payloads;\n\n    if (epoxyHolder == null && model instanceof EpoxyModelWithHolder) {\n      epoxyHolder = ((EpoxyModelWithHolder) model).createNewHolder(parent);\n      epoxyHolder.bindView(itemView);\n    }\n    // Safe to set to null as it is only used for createNewHolder method\n    parent = null;\n\n    if (model instanceof GeneratedModel) {\n      // The generated method will enforce that only a properly typed listener can be set\n      //noinspection unchecked\n      ((GeneratedModel) model).handlePreBind(this, objectToBind(), position);\n    }\n\n    // noinspection unchecked\n    model.preBind(objectToBind(), previouslyBoundModel);\n\n    if (previouslyBoundModel != null) {\n      // noinspection unchecked\n      model.bind(objectToBind(), previouslyBoundModel);\n    } else if (payloads.isEmpty()) {\n      // noinspection unchecked\n      model.bind(objectToBind());\n    } else {\n      // noinspection unchecked\n      model.bind(objectToBind(), payloads);\n    }\n\n    if (model instanceof GeneratedModel) {\n      // The generated method will enforce that only a properly typed listener can be set\n      //noinspection unchecked\n      ((GeneratedModel) model).handlePostBind(objectToBind(), position);\n    }\n\n    epoxyModel = model;\n  }\n\n  @NonNull\n  Object objectToBind() {\n    return epoxyHolder != null ? epoxyHolder : itemView;\n  }\n\n  public void unbind() {\n    assertBound();\n    // noinspection unchecked\n    epoxyModel.unbind(objectToBind());\n\n    epoxyModel = null;\n    payloads = null;\n  }\n\n  public void visibilityStateChanged(@Visibility int visibilityState) {\n    assertBound();\n    // noinspection unchecked\n    epoxyModel.onVisibilityStateChanged(visibilityState, objectToBind());\n  }\n\n  public void visibilityChanged(\n      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleHeight,\n      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleWidth,\n      @Px int visibleHeight,\n      @Px int visibleWidth\n  ) {\n    assertBound();\n    // noinspection unchecked\n    epoxyModel.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight,\n        visibleWidth, objectToBind());\n  }\n\n  public List<Object> getPayloads() {\n    assertBound();\n    return payloads;\n  }\n\n  public EpoxyModel<?> getModel() {\n    assertBound();\n    return epoxyModel;\n  }\n\n  public EpoxyHolder getHolder() {\n    assertBound();\n    return epoxyHolder;\n  }\n\n  private void assertBound() {\n    if (epoxyModel == null) {\n      throw new IllegalStateException(\"This holder is not currently bound.\");\n    }\n  }\n\n  @Override\n  public String toString() {\n    return \"EpoxyViewHolder{\"\n        + \"epoxyModel=\" + epoxyModel\n        + \", view=\" + itemView\n        + \", super=\" + super.toString()\n        + '}';\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyVisibilityItem.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.graphics.Rect\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.annotation.IntRange\nimport androidx.annotation.Px\nimport androidx.annotation.VisibleForTesting\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * This class represent an item in a [android.view.ViewGroup] and it is\n * being reused with multiple model via the update method. There is 1:1 relationship between an\n * EpoxyVisibilityItem and a child within the [android.view.ViewGroup].\n *\n * It contains the logic to compute the visibility state of an item. It will also invoke the\n * visibility callbacks on [com.airbnb.epoxy.EpoxyViewHolder]\n *\n * This class should remain non-public and is intended to be used by [EpoxyVisibilityTracker]\n * only.\n */\n@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)\nclass EpoxyVisibilityItem(adapterPosition: Int? = null) {\n\n    private val localVisibleRect = Rect()\n\n    var adapterPosition = RecyclerView.NO_POSITION\n        private set\n\n    @Px\n    private var height = 0\n\n    @Px\n    private var width = 0\n\n    @Px\n    private var visibleHeight = 0\n\n    @Px\n    private var visibleWidth = 0\n\n    @Px\n    private var viewportHeight = 0\n\n    @Px\n    private var viewportWidth = 0\n    private var partiallyVisible = false\n    private var fullyVisible = false\n    private var visible = false\n    private var focusedVisible = false\n    private var viewVisibility = View.GONE\n\n    /** Store last value for de-duping  */\n    private var lastVisibleHeightNotified: Int? = null\n    private var lastVisibleWidthNotified: Int? = null\n    private var lastVisibilityNotified: Int? = null\n\n    init {\n        adapterPosition?.let {\n            reset(it)\n        }\n    }\n\n    /**\n     * Update the visibility item according the current layout.\n     *\n     * @param view        the current [com.airbnb.epoxy.EpoxyViewHolder]'s itemView\n     * @param parent      the [android.view.ViewGroup]\n     * @return true if the view has been measured\n     */\n    fun update(view: View, parent: ViewGroup, detachEvent: Boolean): Boolean {\n        // Clear the rect before calling getLocalVisibleRect\n        localVisibleRect.setEmpty()\n        val viewDrawn = view.getLocalVisibleRect(localVisibleRect) && !detachEvent\n        height = view.height\n        width = view.width\n        viewportHeight = parent.height\n        viewportWidth = parent.width\n        visibleHeight = if (viewDrawn) localVisibleRect.height() else 0\n        visibleWidth = if (viewDrawn) localVisibleRect.width() else 0\n        viewVisibility = view.visibility\n        return height > 0 && width > 0\n    }\n\n    fun reset(newAdapterPosition: Int) {\n        fullyVisible = false\n        visible = false\n        focusedVisible = false\n        adapterPosition = newAdapterPosition\n        lastVisibleHeightNotified = null\n        lastVisibleWidthNotified = null\n        lastVisibilityNotified = null\n    }\n\n    fun handleVisible(epoxyHolder: EpoxyViewHolder, detachEvent: Boolean) {\n        val previousVisible = visible\n        visible = !detachEvent && isVisible()\n        if (visible != previousVisible) {\n            if (visible) {\n                epoxyHolder.visibilityStateChanged(VisibilityState.VISIBLE)\n            } else {\n                epoxyHolder.visibilityStateChanged(VisibilityState.INVISIBLE)\n            }\n        }\n    }\n\n    fun handleFocus(epoxyHolder: EpoxyViewHolder, detachEvent: Boolean) {\n        val previousFocusedVisible = focusedVisible\n        focusedVisible = !detachEvent && isInFocusVisible()\n        if (focusedVisible != previousFocusedVisible) {\n            if (focusedVisible) {\n                epoxyHolder.visibilityStateChanged(VisibilityState.FOCUSED_VISIBLE)\n            } else {\n                epoxyHolder.visibilityStateChanged(VisibilityState.UNFOCUSED_VISIBLE)\n            }\n        }\n    }\n\n    fun handlePartialImpressionVisible(\n        epoxyHolder: EpoxyViewHolder,\n        detachEvent: Boolean,\n        @IntRange(from = 0, to = 100) thresholdPercentage: Int\n    ) {\n        val previousPartiallyVisible = partiallyVisible\n        partiallyVisible = !detachEvent && isPartiallyVisible(thresholdPercentage)\n        if (partiallyVisible != previousPartiallyVisible) {\n            if (partiallyVisible) {\n                epoxyHolder.visibilityStateChanged(VisibilityState.PARTIAL_IMPRESSION_VISIBLE)\n            } else {\n                epoxyHolder.visibilityStateChanged(VisibilityState.PARTIAL_IMPRESSION_INVISIBLE)\n            }\n        }\n    }\n\n    fun handleFullImpressionVisible(epoxyHolder: EpoxyViewHolder, detachEvent: Boolean) {\n        val previousFullyVisible = fullyVisible\n        fullyVisible = !detachEvent && isFullyVisible()\n        if (fullyVisible != previousFullyVisible) {\n            if (fullyVisible) {\n                epoxyHolder.visibilityStateChanged(VisibilityState.FULL_IMPRESSION_VISIBLE)\n            }\n        }\n    }\n\n    fun handleChanged(epoxyHolder: EpoxyViewHolder, visibilityChangedEnabled: Boolean): Boolean {\n        var changed = false\n        if (visibleHeight != lastVisibleHeightNotified || visibleWidth != lastVisibleWidthNotified || viewVisibility != lastVisibilityNotified) {\n            if (visibilityChangedEnabled) {\n                if (viewVisibility == View.GONE) {\n                    epoxyHolder.visibilityChanged(0f, 0f, 0, 0)\n                } else {\n                    epoxyHolder.visibilityChanged(\n                        100f / height * visibleHeight,\n                        100f / width * visibleWidth,\n                        visibleHeight, visibleWidth\n                    )\n                }\n            }\n            lastVisibleHeightNotified = visibleHeight\n            lastVisibleWidthNotified = visibleWidth\n            lastVisibilityNotified = viewVisibility\n            changed = true\n        }\n        return changed\n    }\n\n    private fun isVisible(): Boolean {\n        return viewVisibility == View.VISIBLE && visibleHeight > 0 && visibleWidth > 0\n    }\n\n    private fun isInFocusVisible(): Boolean {\n        val halfViewportArea = viewportHeight * viewportWidth / 2\n        val totalArea = height * width\n        val visibleArea = visibleHeight * visibleWidth\n        // The model has entered the focused range either if it is larger than half of the viewport\n        // and it occupies at least half of the viewport or if it is smaller than half of the viewport\n        // and it is fully visible.\n        return viewVisibility == View.VISIBLE &&\n            if (totalArea >= halfViewportArea) visibleArea >= halfViewportArea else totalArea == visibleArea\n    }\n\n    private fun isPartiallyVisible(\n        @IntRange(\n            from = 0,\n            to = 100\n        ) thresholdPercentage: Int\n    ): Boolean {\n        // special case 0%: trigger as soon as some pixels are one the screen\n        if (thresholdPercentage == 0) return isVisible()\n        val totalArea = height * width\n        val visibleArea = visibleHeight * visibleWidth\n        val visibleAreaPercentage = visibleArea / totalArea.toFloat() * 100\n        return viewVisibility == View.VISIBLE && visibleAreaPercentage >= thresholdPercentage\n    }\n\n    private fun isFullyVisible(): Boolean {\n        return viewVisibility == View.VISIBLE && visibleHeight == height && visibleWidth == width\n    }\n\n    fun shiftBy(offsetPosition: Int) {\n        adapterPosition += offsetPosition\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyVisibilityTracker.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.util.Log\nimport android.util.SparseArray\nimport android.view.View\nimport androidx.annotation.IdRes\nimport androidx.annotation.IntRange\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.viewmodeladapter.R\nimport java.util.ArrayList\nimport java.util.HashMap\n\n/**\n * A simple way to track visibility events on [com.airbnb.epoxy.EpoxyModel].\n *\n * [EpoxyVisibilityTracker] works with any [androidx.recyclerview.widget.RecyclerView]\n * backed by an Epoxy controller. Once attached the events will be forwarded to the Epoxy model (or\n * to the Epoxy view when using annotations).\n *\n * Note that support for visibility events on an [EpoxyModelGroup] is somewhat limited. Only model\n * additions will receive visibility events. Models that are removed from the group will not receive\n * events (e.g. [VisibilityState.INVISIBLE]) because the model group does not keep a reference,\n * nor does it get notified of model removals.\n *\n * @see OnVisibilityChanged\n *\n * @see OnVisibilityStateChanged\n *\n * @see OnModelVisibilityChangedListener\n *\n * @see OnModelVisibilityStateChangedListener\n */\nopen class EpoxyVisibilityTracker {\n\n    /**\n     * Used to listen to [RecyclerView.ItemAnimator] ending animations.\n     */\n    private val itemAnimatorFinishedListener =\n        RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {\n            processChangeEvent(\n                \"ItemAnimatorFinishedListener.onAnimationsFinished\",\n                /* don't check item animator to prevent recursion */ false\n            )\n        }\n\n    /** Maintain visibility item indexed by view id (identity hashcode)  */\n    private val visibilityIdToItemMap = SparseArray<EpoxyVisibilityItem>()\n    private val visibilityIdToItems: MutableList<EpoxyVisibilityItem> = ArrayList()\n\n    /** listener used to process scroll, layout and attach events  */\n    private val listener = Listener()\n\n    /** listener used to process data events  */\n    private val observer = DataObserver()\n\n    private var attachedRecyclerView: RecyclerView? = null\n\n    private var lastAdapterSeen: RecyclerView.Adapter<*>? = null\n\n    /** All nested visibility trackers  */\n    private val nestedTrackers: MutableMap<RecyclerView, EpoxyVisibilityTracker> = HashMap()\n\n    /** This flag is for optimizing the process on detach. If detach is from data changed then it\n     * need to re-process all views, else no need (ex: scroll). */\n    private var visibleDataChanged = false\n\n    /**\n     * Enable or disable visibility changed event. Default is `true`, disable it if you don't need\n     * (triggered by every pixel scrolled).\n     *\n     * @see OnVisibilityChanged\n     *\n     * @see OnModelVisibilityChangedListener\n     */\n    var onChangedEnabled = true\n\n    /**\n     * Set the threshold of percentage visible area to identify the partial impression view state.\n     *\n     * @param thresholdPercentage Percentage of visible area of an element in the range [0..100].\n     * Defaults to `null`, which disables\n     * [VisibilityState.PARTIAL_IMPRESSION_VISIBLE] and\n     * [VisibilityState.PARTIAL_IMPRESSION_INVISIBLE] events.\n     */\n    @IntRange(from = 0, to = 100)\n    var partialImpressionThresholdPercentage: Int? = null\n\n    /**\n     * Attach the tracker.\n     *\n     * @param recyclerView The recyclerview that the EpoxyController has its adapter added to.\n     */\n    open fun attach(recyclerView: RecyclerView) {\n        attachedRecyclerView = recyclerView\n        recyclerView.addOnScrollListener(listener)\n        recyclerView.addOnLayoutChangeListener(listener)\n        recyclerView.addOnChildAttachStateChangeListener(listener)\n        setTracker(recyclerView, this)\n    }\n\n    /**\n     * Detach the tracker\n     *\n     * @param recyclerView The recycler view that the EpoxyController has its adapter added to.\n     */\n    open fun detach(recyclerView: RecyclerView) {\n        recyclerView.removeOnScrollListener(listener)\n        recyclerView.removeOnLayoutChangeListener(listener)\n        recyclerView.removeOnChildAttachStateChangeListener(listener)\n        setTracker(recyclerView, null)\n        attachedRecyclerView = null\n    }\n\n    /**\n     * The tracker is storing visibility states internally and is using if to send events, only the\n     * difference is sent. Use this method to clear the states and thus regenerate the visibility\n     * events. This may be useful when you change the adapter on the [RecyclerView].\n     */\n    fun clearVisibilityStates() {\n        // Clear our visibility items\n        visibilityIdToItemMap.clear()\n        visibilityIdToItems.clear()\n    }\n\n    /**\n     * Calling this method will make the visibility tracking check and trigger events if necessary. It\n     * is particularly useful when the visibility of an Epoxy model is changed outside of an Epoxy\n     * RecyclerView.\n     *\n     * An example is when you nest an horizontal Epoxy backed RecyclerView in a non Epoxy vertical\n     * RecyclerView. When the vertical RecyclerView scroll you want to notify the visibility tracker\n     * attached on the horizontal RecyclerView.\n     */\n    fun requestVisibilityCheck() {\n        processChangeEvent(\"requestVisibilityCheck\")\n    }\n\n    /**\n     * Process a change event.\n     * @param debug: string for debug usually the source of the call\n     * @param checkItemAnimator: true if it need to check if ItemAnimator is running\n     */\n    private fun processChangeEvent(debug: String, checkItemAnimator: Boolean = true) {\n\n        // Only if attached\n        val recyclerView = attachedRecyclerView ?: return\n\n        val itemAnimator = recyclerView.itemAnimator\n        if (checkItemAnimator && itemAnimator != null) {\n            // `itemAnimatorFinishedListener.onAnimationsFinished` will process visibility check\n            // - If the animations are running `onAnimationsFinished` will be invoked on animations end.\n            // - If the animations are not running `onAnimationsFinished` will be invoked right away.\n            if (itemAnimator.isRunning(itemAnimatorFinishedListener)) {\n                // If running process visibility now as `onAnimationsFinished` was not yet called\n                processChangeEventWithDetachedView(null, debug)\n            }\n        } else {\n            processChangeEventWithDetachedView(null, debug)\n        }\n    }\n\n    private fun processChangeEventWithDetachedView(detachedView: View?, debug: String) {\n\n        // Only if attached\n        val recyclerView = attachedRecyclerView ?: return\n\n        // On every every events lookup for a new adapter\n        processNewAdapterIfNecessary()\n\n        // Process the detached child if any\n        detachedView?.let { processChild(it, true, debug) }\n\n        // Process all attached children\n        for (i in 0 until recyclerView.childCount) {\n            val child = recyclerView.getChildAt(i)\n            if (child != null && child !== detachedView) {\n                // Is some case the detached child is still in the recycler view. Don't process it as it\n                // was already processed.\n                processChild(child, false, debug)\n            }\n        }\n    }\n\n    /**\n     * If there is a new adapter on the attached RecyclerView it will register the data observer and\n     * clear the current visibility states\n     */\n    private fun processNewAdapterIfNecessary() {\n        attachedRecyclerView?.adapter?.let { adapter ->\n            if (lastAdapterSeen != adapter) {\n                // Unregister the old adapter\n                lastAdapterSeen?.unregisterAdapterDataObserver(observer)\n                // Register the new adapter\n                adapter.registerAdapterDataObserver(observer)\n                lastAdapterSeen = adapter\n            }\n        }\n    }\n\n    /**\n     * Don't call this method directly, it is called from\n     * [EpoxyVisibilityTracker.processVisibilityEvents]\n     *\n     * @param child               the view to process for visibility event\n     * @param detachEvent         true if the child was just detached\n     * @param eventOriginForDebug a debug strings used for logs\n     */\n    private fun processChild(child: View, detachEvent: Boolean, eventOriginForDebug: String) {\n\n        // Only if attached\n        val recyclerView = attachedRecyclerView ?: return\n\n        // Preemptive check for child's parent validity to prevent `IllegalArgumentException` in\n        // `getChildViewHolder`.\n        val isParentValid = child.parent == null || child.parent === recyclerView\n        val viewHolder = if (isParentValid) recyclerView.getChildViewHolder(child) else null\n        if (viewHolder is EpoxyViewHolder) {\n            val epoxyHolder = viewHolder.holder\n            processChild(recyclerView, child, detachEvent, eventOriginForDebug, viewHolder)\n            if (epoxyHolder is ModelGroupHolder) {\n                processModelGroupChildren(recyclerView, epoxyHolder, detachEvent, eventOriginForDebug)\n            }\n        }\n    }\n\n    /**\n     * Loop through the children of the model group and process visibility events on each one in\n     * relation to the model group's layout. This will attach or detach trackers to any nested\n     * [RecyclerView]s.\n     *\n     * @param epoxyHolder         the [ModelGroupHolder] with children to process\n     * @param detachEvent         true if the child was just detached\n     * @param eventOriginForDebug a debug strings used for logs\n     */\n    private fun processModelGroupChildren(\n        recyclerView: RecyclerView,\n        epoxyHolder: ModelGroupHolder,\n        detachEvent: Boolean,\n        eventOriginForDebug: String\n    ) {\n        // Iterate through models in the group and process each of them instead of the group\n        for (groupChildHolder in epoxyHolder.viewHolders) {\n            // Since the group is likely using a ViewGroup other than a RecyclerView, handle the\n            // potential of a nested RecyclerView. This cannot be done through the normal flow\n            // without recursively searching through the view children.\n            if (groupChildHolder.itemView is RecyclerView) {\n                if (detachEvent) {\n                    processChildRecyclerViewDetached(groupChildHolder.itemView as RecyclerView)\n                } else {\n                    processChildRecyclerViewAttached(groupChildHolder.itemView as RecyclerView)\n                }\n            }\n            processChild(\n                recyclerView,\n                groupChildHolder.itemView,\n                detachEvent,\n                eventOriginForDebug,\n                groupChildHolder\n            )\n        }\n    }\n\n    /**\n     * Process visibility events for a view and propagate to a nested tracker if the view is a\n     * [RecyclerView].\n     *\n     * @param child               the view to process for visibility event\n     * @param detachEvent         true if the child was just detached\n     * @param eventOriginForDebug a debug strings used for logs\n     * @param viewHolder          the view holder for the child view\n     */\n    private fun processChild(\n        recyclerView: RecyclerView,\n        child: View,\n        detachEvent: Boolean,\n        eventOriginForDebug: String,\n        viewHolder: EpoxyViewHolder\n    ) {\n        val changed = processVisibilityEvents(\n            recyclerView,\n            viewHolder,\n            detachEvent,\n            eventOriginForDebug\n        )\n        if (changed && child is RecyclerView) {\n            nestedTrackers[child]?.processChangeEvent(\"parent\")\n        }\n    }\n\n    /**\n     * Call this methods every time something related to ui (scroll, layout, ...) or something related\n     * to data changed.\n     *\n     * @param recyclerView        the recycler view\n     * @param epoxyHolder         the [RecyclerView]\n     * @param detachEvent         true if the event originated from a view detached from the\n     * recycler view\n     * @param eventOriginForDebug a debug strings used for logs\n     * @return true if changed\n     */\n    private fun processVisibilityEvents(\n        recyclerView: RecyclerView,\n        epoxyHolder: EpoxyViewHolder,\n        detachEvent: Boolean,\n        eventOriginForDebug: String\n    ): Boolean {\n        if (DEBUG_LOG) {\n            Log.d(\n                TAG,\n                \"$eventOriginForDebug.processVisibilityEvents \" +\n                    \"${System.identityHashCode(epoxyHolder)}, \" +\n                    \"$detachEvent, ${epoxyHolder.adapterPosition}\"\n            )\n        }\n        val itemView = epoxyHolder.itemView\n        val id = System.identityHashCode(itemView)\n        var vi = visibilityIdToItemMap[id]\n        if (vi == null) {\n            // New view discovered, assign an EpoxyVisibilityItem\n            vi = EpoxyVisibilityItem(epoxyHolder.adapterPosition)\n            visibilityIdToItemMap.put(id, vi)\n            visibilityIdToItems.add(vi)\n        } else if (epoxyHolder.adapterPosition != RecyclerView.NO_POSITION &&\n            vi.adapterPosition != epoxyHolder.adapterPosition\n        ) {\n            // EpoxyVisibilityItem being re-used for a different adapter position\n            vi.reset(epoxyHolder.adapterPosition)\n        }\n        var changed = false\n        if (vi.update(itemView, recyclerView, detachEvent)) {\n            // View is measured, process events\n            vi.handleVisible(epoxyHolder, detachEvent)\n            partialImpressionThresholdPercentage?.let { percentage ->\n                vi.handlePartialImpressionVisible(\n                    epoxyHolder, detachEvent,\n                    percentage\n                )\n            }\n            vi.handleFocus(epoxyHolder, detachEvent)\n            vi.handleFullImpressionVisible(epoxyHolder, detachEvent)\n            changed = vi.handleChanged(epoxyHolder, onChangedEnabled)\n        }\n        return changed\n    }\n\n    private fun processChildRecyclerViewAttached(childRecyclerView: RecyclerView) {\n        // Register itself in the EpoxyVisibilityTracker. This will take care of nested list\n        // tracking (ex: carousel)\n        val tracker = getTracker(childRecyclerView) ?: EpoxyVisibilityTracker().let { nested ->\n            nested.partialImpressionThresholdPercentage = partialImpressionThresholdPercentage\n            nested.attach(childRecyclerView)\n            nested\n        }\n        nestedTrackers[childRecyclerView] = tracker\n    }\n\n    private fun processChildRecyclerViewDetached(childRecyclerView: RecyclerView) {\n        nestedTrackers.remove(childRecyclerView)\n    }\n\n    /**\n     * Helper class that host the [androidx.recyclerview.widget.RecyclerView] listener\n     * implementations\n     */\n    private inner class Listener :\n        RecyclerView.OnScrollListener(),\n        View.OnLayoutChangeListener,\n        RecyclerView.OnChildAttachStateChangeListener {\n        override fun onLayoutChange(\n            recyclerView: View,\n            left: Int,\n            top: Int,\n            right: Int,\n            bottom: Int,\n            oldLeft: Int,\n            oldTop: Int,\n            oldRight: Int,\n            oldBottom: Int\n        ) {\n            processChangeEvent(\"onLayoutChange\")\n        }\n\n        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {\n            processChangeEvent(\"onScrolled\")\n        }\n\n        override fun onChildViewAttachedToWindow(child: View) {\n            if (child is RecyclerView) {\n                processChildRecyclerViewAttached(child)\n            }\n            processChild(child, false, \"onChildViewAttachedToWindow\")\n        }\n\n        override fun onChildViewDetachedFromWindow(child: View) {\n            if (child is RecyclerView) {\n                processChildRecyclerViewDetached(child)\n            }\n            if (visibleDataChanged) {\n                // On detach event caused by data set changed we need to re-process all children because\n                // the removal caused the others views to changes.\n                processChangeEventWithDetachedView(child, \"onChildViewDetachedFromWindow\")\n                visibleDataChanged = false\n            } else {\n                processChild(child, true, \"onChildViewDetachedFromWindow\")\n            }\n        }\n    }\n\n    /**\n     * The layout/scroll events are not enough to detect all sort of visibility changes. We also\n     * need to look at the data events from the adapter.\n     */\n    internal inner class DataObserver : RecyclerView.AdapterDataObserver() {\n        /**\n         * Clear the current visibility statues\n         */\n        override fun onChanged() {\n            if (notEpoxyManaged(attachedRecyclerView)) {\n                return\n            }\n            if (DEBUG_LOG) {\n                Log.d(TAG, \"onChanged()\")\n            }\n            visibilityIdToItemMap.clear()\n            visibilityIdToItems.clear()\n            visibleDataChanged = true\n        }\n\n        /**\n         * For all items after the inserted range shift each [EpoxyVisibilityTracker] adapter\n         * position by inserted item count.\n         */\n        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n            if (notEpoxyManaged(attachedRecyclerView)) {\n                return\n            }\n            if (DEBUG_LOG) {\n                Log.d(TAG, \"onItemRangeInserted($positionStart, $itemCount)\")\n            }\n            for (item in visibilityIdToItems) {\n                if (item.adapterPosition >= positionStart) {\n                    visibleDataChanged = true\n                    item.shiftBy(itemCount)\n                }\n            }\n        }\n\n        /**\n         * For all items after the removed range reverse-shift each [EpoxyVisibilityTracker]\n         * adapter position by removed item count\n         */\n        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {\n            if (notEpoxyManaged(attachedRecyclerView)) {\n                return\n            }\n            if (DEBUG_LOG) {\n                Log.d(TAG, \"onItemRangeRemoved($positionStart, $itemCount)\")\n            }\n            for (item in visibilityIdToItems) {\n                if (item.adapterPosition >= positionStart) {\n                    visibleDataChanged = true\n                    item.shiftBy(-itemCount)\n                }\n            }\n        }\n\n        /**\n         * This is a bit more complex, for move we need to first swap the moved position then shift the\n         * items between the swap. To simplify we split any range passed to individual item moved.\n         *\n         * ps: anyway [androidx.recyclerview.widget.AdapterListUpdateCallback]\n         * does not seem to use range for moved items.\n         */\n        override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n            if (notEpoxyManaged(attachedRecyclerView)) {\n                return\n            }\n            for (i in 0 until itemCount) {\n                onItemMoved(fromPosition + i, toPosition + i)\n            }\n        }\n\n        private fun onItemMoved(fromPosition: Int, toPosition: Int) {\n            if (notEpoxyManaged(attachedRecyclerView)) {\n                return\n            }\n            if (DEBUG_LOG) {\n                Log.d(TAG, \"onItemRangeMoved($fromPosition, $fromPosition, 1)\")\n            }\n            for (item in visibilityIdToItems) {\n                val position = item.adapterPosition\n                if (position == fromPosition) {\n                    // We found the item to be moved, just swap the position.\n                    item.shiftBy(toPosition - fromPosition)\n                    visibleDataChanged = true\n                } else if (fromPosition < toPosition) {\n                    // Item will be moved down in the list\n                    if (position in (fromPosition + 1)..toPosition) {\n                        // Item is between the moved from and to indexes, it should move up\n                        item.shiftBy(-1)\n                        visibleDataChanged = true\n                    }\n                } else if (fromPosition > toPosition) {\n                    // Item will be moved up in the list\n                    if (position in toPosition until fromPosition) {\n                        // Item is between the moved to and from indexes, it should move down\n                        item.shiftBy(1)\n                        visibleDataChanged = true\n                    }\n                }\n            }\n        }\n\n        /**\n         * @param recyclerView the recycler view\n         * @return true if managed by an [BaseEpoxyAdapter]\n         */\n        private fun notEpoxyManaged(recyclerView: RecyclerView?): Boolean {\n            return recyclerView == null || recyclerView.adapter !is BaseEpoxyAdapter\n        }\n    }\n\n    companion object {\n        private const val TAG = \"EpoxyVisibilityTracker\"\n\n        @IdRes\n        private val TAG_ID = R.id.epoxy_visibility_tracker\n\n        /**\n         * @param recyclerView the view.\n         * @return the tracker for the given [RecyclerView]. Null if no tracker was attached.\n         */\n        private fun getTracker(recyclerView: RecyclerView): EpoxyVisibilityTracker? {\n            return recyclerView.getTag(TAG_ID) as EpoxyVisibilityTracker?\n        }\n\n        /**\n         * Store the tracker for the given [RecyclerView].\n         * @param recyclerView the view\n         * @param tracker the tracker\n         */\n        private fun setTracker(\n            recyclerView: RecyclerView,\n            tracker: EpoxyVisibilityTracker?\n        ) {\n            recyclerView.setTag(TAG_ID, tracker)\n        }\n\n        // Not actionable at runtime. It is only useful for internal test-troubleshooting.\n        const val DEBUG_LOG = false\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/GeneratedModel.java",
    "content": "package com.airbnb.epoxy;\n\n/** Interface applied to generated models to allow the base adapter to interact with them. */\npublic interface GeneratedModel<T> {\n  /**\n   * Called on the generated model immediately before the main model onBind method has been called.\n   * This let's the generated model handle binding setup of its own\n   * <p>\n   * The ViewHolder is needed to get the model's adapter position when clicked.\n   */\n  void handlePreBind(EpoxyViewHolder holder, T objectToBind, int position);\n  /**\n   * Called on the generated model immediately after the main model onBind method has been called.\n   * This let's the generated model handle binding of its own and dispatch calls to its onBind\n   * listener.\n   * <p>\n   * We don't want to rely on the main onBind method to dispatch the onBind listener call because\n   * there are two onBind methods (one for payloads and one for no payloads), and one can call into\n   * the other. We don't want to dispatch two onBind listener calls in that case.\n   */\n  void handlePostBind(T objectToBind, int position);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/GroupModel.kt",
    "content": "package com.airbnb.epoxy\n\nimport androidx.annotation.LayoutRes\n\n/**\n * An [EpoxyModelGroup] usable in a DSL manner via the [group] extension.\n * <p>\n * Example:\n * ```\n * group {\n *   id(\"photos\")\n *   layout(R.layout.photo_grid)\n *\n *   // add your models here, example:\n *   for (photo in photos) {\n *     imageView {\n *       id(photo.id)\n *       url(photo.url)\n *     }\n *   }\n * }\n * ```\n */\n@EpoxyModelClass\nabstract class GroupModel : EpoxyModelGroup, ModelCollector {\n    constructor() : super()\n    constructor(@LayoutRes layoutRes: Int) : super(layoutRes)\n\n    override fun add(model: EpoxyModel<*>) {\n        super.addModel(model)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/HandlerExecutor.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\nimport android.os.Looper;\n\nimport java.util.concurrent.Executor;\n\nimport androidx.annotation.NonNull;\n\n/**\n * An executor that does it's work via posting to a Handler.\n * <p>\n * A key feature of this is the runnable is executed synchronously if the current thread is the\n * same as the handler's thread.\n */\nclass HandlerExecutor implements Executor {\n  final Handler handler;\n\n  HandlerExecutor(Handler handler) {\n    this.handler = handler;\n  }\n\n  @Override\n  public void execute(@NonNull Runnable command) {\n    // If we're already on the same thread then we can execute this synchronously\n    if (Looper.myLooper() == handler.getLooper()) {\n      command.run();\n    } else {\n      handler.post(command);\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/HiddenEpoxyModel.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport android.widget.Space;\n\nimport com.airbnb.viewmodeladapter.R;\n\n/**\n * Used by the {@link EpoxyAdapter} as a placeholder for when {@link EpoxyModel#isShown()} is false.\n * Using a zero height and width {@link Space} view, as well as 0 span size, to exclude itself from\n * view.\n */\nclass HiddenEpoxyModel extends EpoxyModel<Space> {\n  @Override\n  public int getDefaultLayout() {\n    return R.layout.view_holder_empty_view;\n  }\n\n  @Override\n  public int getSpanSize(int spanCount, int position, int itemCount) {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/IdUtils.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\n\n/**\n * Utilities for generating 64-bit long IDs from types such as {@link CharSequence}.\n */\npublic final class IdUtils {\n  private IdUtils() {\n  }\n\n  /**\n   * Hash a long into 64 bits instead of the normal 32. This uses a xor shift implementation to\n   * attempt psuedo randomness so object ids have an even spread for less chance of collisions.\n   * <p>\n   * From http://stackoverflow.com/a/11554034\n   * <p>\n   * http://www.javamex.com/tutorials/random_numbers/xorshift.shtml\n   */\n  public static long hashLong64Bit(long value) {\n    value ^= (value << 21);\n    value ^= (value >>> 35);\n    value ^= (value << 4);\n    return value;\n  }\n\n  /**\n   * Hash a string into 64 bits instead of the normal 32. This allows us to better use strings as a\n   * model id with less chance of collisions. This uses the FNV-1a algorithm for a good mix of speed\n   * and distribution.\n   * <p>\n   * Performance comparisons found at http://stackoverflow.com/a/1660613\n   * <p>\n   * Hash implementation from http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a\n   */\n  public static long hashString64Bit(@Nullable CharSequence str) {\n    if (str == null) {\n      return 0;\n    }\n\n    long result = 0xcbf29ce484222325L;\n    final int len = str.length();\n    for (int i = 0; i < len; i++) {\n      result ^= str.charAt(i);\n      result *= 0x100000001b3L;\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/IllegalEpoxyUsage.java",
    "content": "package com.airbnb.epoxy;\n\npublic class IllegalEpoxyUsage extends RuntimeException {\n  public IllegalEpoxyUsage(String message) {\n    super(message);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ImmutableModelException.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Thrown if a model is changed after it is added to an {@link com.airbnb.epoxy.EpoxyController}.\n */\nclass ImmutableModelException extends RuntimeException {\n  private static final String MODEL_CANNOT_BE_CHANGED_MESSAGE =\n      \"Epoxy attribute fields on a model cannot be changed once the model is added to a \"\n          + \"controller. Check that these fields are not updated, or that the assigned objects \"\n          + \"are not mutated, outside of the buildModels method. The only exception is if \"\n          + \"the change is made inside an Interceptor callback. Consider using an interceptor\"\n          + \" if you need to change a model after it is added to the controller and before it\"\n          + \" is set on the adapter. If the model is already set on the adapter then you must\"\n          + \" call `requestModelBuild` instead to recreate all models.\";\n\n  ImmutableModelException(EpoxyModel model, int modelPosition) {\n    this(model, \"\", modelPosition);\n  }\n\n  ImmutableModelException(EpoxyModel model,\n      String descriptionOfWhenChangeHappened, int modelPosition) {\n    super(buildMessage(model, descriptionOfWhenChangeHappened, modelPosition));\n  }\n\n  @NonNull\n  private static String buildMessage(EpoxyModel model,\n      String descriptionOfWhenChangeHappened, int modelPosition) {\n    return new StringBuilder(descriptionOfWhenChangeHappened)\n        .append(\" Position: \")\n        .append(modelPosition)\n        .append(\" Model: \")\n        .append(model.toString())\n        .append(\"\\n\\n\")\n        .append(MODEL_CANNOT_BE_CHANGED_MESSAGE)\n        .toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/InternalExposer.kt",
    "content": "package com.airbnb.epoxy\n\n/**\n * Exposes package private things as internal so files in other packages can use them.\n */\n\ninternal fun EpoxyViewHolder.objectToBindInternal() = objectToBind()\n\ninternal fun EpoxyModel<*>.viewTypeInternal() = viewType\ninternal fun BaseEpoxyAdapter.boundViewHoldersInternal() = boundViewHolders\ninternal fun BaseEpoxyAdapter.getModelForPositionInternal(position: Int): EpoxyModel<*>? {\n    return getModelForPosition(position)\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ListenersUtils.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\n\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.RecyclerView.ViewHolder;\n\npublic class ListenersUtils {\n\n  @Nullable\n  static EpoxyViewHolder getEpoxyHolderForChildView(View v) {\n    RecyclerView recyclerView = findParentRecyclerView(v);\n    if (recyclerView == null) {\n      return null;\n    }\n\n    ViewHolder viewHolder = recyclerView.findContainingViewHolder(v);\n    if (viewHolder == null) {\n      return null;\n    }\n\n    if (!(viewHolder instanceof EpoxyViewHolder)) {\n      return null;\n    }\n\n    return (EpoxyViewHolder) viewHolder;\n  }\n\n  @Nullable\n  private static RecyclerView findParentRecyclerView(@Nullable View v) {\n    if (v == null) {\n      return null;\n    }\n\n    ViewParent parent = v.getParent();\n    if (parent instanceof RecyclerView) {\n      return (RecyclerView) parent;\n    }\n\n    if (parent instanceof View) {\n      return findParentRecyclerView((View) parent);\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/MainThreadExecutor.java",
    "content": "package com.airbnb.epoxy;\n\nimport static com.airbnb.epoxy.EpoxyAsyncUtil.AYSNC_MAIN_THREAD_HANDLER;\nimport static com.airbnb.epoxy.EpoxyAsyncUtil.MAIN_THREAD_HANDLER;\n\nclass MainThreadExecutor extends HandlerExecutor {\n  static final MainThreadExecutor INSTANCE = new MainThreadExecutor(false);\n  static final MainThreadExecutor ASYNC_INSTANCE = new MainThreadExecutor(true);\n\n  MainThreadExecutor(boolean async) {\n    super(async ? AYSNC_MAIN_THREAD_HANDLER : MAIN_THREAD_HANDLER);\n  }\n}\n\n\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelCollector.kt",
    "content": "package com.airbnb.epoxy\n\n/**\n * Interface used to collect models. Used by [EpoxyController]. It is also convenient to build DSL\n * helpers for carousel: @link https://github.com/airbnb/epoxy/issues/847.\n */\n@EpoxyBuildScope\ninterface ModelCollector {\n\n    fun add(model: EpoxyModel<*>)\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelGroupHolder.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.ViewParent\nimport android.view.ViewStub\nimport androidx.annotation.VisibleForTesting\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.viewmodeladapter.R\nimport java.util.ArrayList\n\nclass ModelGroupHolder(private val modelGroupParent: ViewParent) : EpoxyHolder() {\n    val viewHolders = ArrayList<EpoxyViewHolder>(4)\n\n    /** Use parent pool or create a local pool */\n    @VisibleForTesting\n    val viewPool = findViewPool(modelGroupParent)\n\n    /**\n     * Get the root view group (aka\n     * [androidx.recyclerview.widget.RecyclerView.ViewHolder.itemView].\n     * You can override [EpoxyModelGroup.bind] and use this method to make custom\n     * changes to the root view.\n     */\n    lateinit var rootView: ViewGroup\n        private set\n\n    private lateinit var childContainer: ViewGroup\n    private lateinit var stubs: List<ViewStubData>\n    private var boundGroup: EpoxyModelGroup? = null\n\n    private fun usingStubs(): Boolean = stubs.isNotEmpty()\n\n    override fun bindView(itemView: View) {\n        if (itemView !is ViewGroup) {\n            throw IllegalStateException(\n                \"The layout provided to EpoxyModelGroup must be a ViewGroup\"\n            )\n        }\n\n        rootView = itemView\n        childContainer = findChildContainer(rootView)\n\n        stubs = if (childContainer.childCount != 0) {\n            createViewStubData(childContainer)\n        } else {\n            emptyList()\n        }\n    }\n\n    /**\n     * By default the outermost viewgroup is used as the container that views are added to. However,\n     * users can specify a different, nested view group to use as the child container by marking it\n     * with a special id.\n     */\n    private fun findChildContainer(outermostRoot: ViewGroup): ViewGroup {\n        val customRoot = outermostRoot.findViewById<View>(R.id.epoxy_model_group_child_container)\n\n        return customRoot as? ViewGroup ?: outermostRoot\n    }\n\n    private fun createViewStubData(viewGroup: ViewGroup): List<ViewStubData> {\n        return ArrayList<ViewStubData>(4).apply {\n\n            collectViewStubs(viewGroup, this)\n\n            if (isEmpty()) {\n                throw IllegalStateException(\n                    \"No view stubs found. If viewgroup is not empty it must contain ViewStubs.\"\n                )\n            }\n        }\n    }\n\n    private fun collectViewStubs(\n        viewGroup: ViewGroup,\n        stubs: ArrayList<ViewStubData>\n    ) {\n        for (i in 0 until viewGroup.childCount) {\n            val child = viewGroup.getChildAt(i)\n\n            if (child is ViewGroup) {\n                collectViewStubs(child, stubs)\n            } else if (child is ViewStub) {\n                stubs.add(ViewStubData(viewGroup, child, i))\n            }\n        }\n    }\n\n    fun bindGroupIfNeeded(group: EpoxyModelGroup) {\n        val previouslyBoundGroup = this.boundGroup\n\n        if (previouslyBoundGroup === group) {\n            return\n        } else if (previouslyBoundGroup != null) {\n            // A different group is being bound; this can happen when an onscreen model is changed.\n            // The models or their layouts could have changed, so views may need to be updated\n\n            if (previouslyBoundGroup.models.size > group.models.size) {\n                for (i in previouslyBoundGroup.models.size - 1 downTo group.models.size) {\n                    removeAndRecycleView(i)\n                }\n            }\n        }\n\n        this.boundGroup = group\n        val models = group.models\n        val modelCount = models.size\n\n        if (usingStubs() && stubs.size < modelCount) {\n            throw IllegalStateException(\n                \"Insufficient view stubs for EpoxyModelGroup. $modelCount models were provided but only ${stubs.size} view stubs exist.\"\n            )\n        }\n        viewHolders.ensureCapacity(modelCount)\n\n        for (i in 0 until modelCount) {\n            val model = models[i]\n            val previouslyBoundModel = previouslyBoundGroup?.models?.getOrNull(i)\n            val stubData = stubs.getOrNull(i)\n            val parent = stubData?.viewGroup ?: childContainer\n\n            if (previouslyBoundModel != null) {\n                if (areSameViewType(previouslyBoundModel, model)) {\n                    continue\n                }\n\n                removeAndRecycleView(i)\n            }\n\n            val holder = getViewHolder(parent, model)\n\n            if (stubData == null) {\n                childContainer.addView(holder.itemView, i)\n            } else {\n                stubData.setView(holder.itemView, group.useViewStubLayoutParams(model, i))\n            }\n\n            viewHolders.add(i, holder)\n        }\n    }\n\n    private fun areSameViewType(model1: EpoxyModel<*>, model2: EpoxyModel<*>?): Boolean {\n        return ViewTypeManager.getViewType(model1) == ViewTypeManager.getViewType(model2)\n    }\n\n    private fun getViewHolder(parent: ViewGroup, model: EpoxyModel<*>): EpoxyViewHolder {\n        val viewType = ViewTypeManager.getViewType(model)\n        val recycledView = viewPool.getRecycledView(viewType)\n\n        return recycledView as? EpoxyViewHolder\n            ?: HELPER_ADAPTER.createViewHolder(\n                modelGroupParent,\n                model,\n                parent,\n                viewType\n            )\n    }\n\n    fun unbindGroup() {\n        if (boundGroup == null) {\n            throw IllegalStateException(\"Group is not bound\")\n        }\n\n        repeat(viewHolders.size) {\n            // Remove from the end for more efficient list actions\n            removeAndRecycleView(viewHolders.size - 1)\n        }\n\n        boundGroup = null\n    }\n\n    private fun removeAndRecycleView(modelPosition: Int) {\n        if (usingStubs()) {\n            stubs[modelPosition].resetStub()\n        } else {\n            childContainer.removeViewAt(modelPosition)\n        }\n\n        val viewHolder = viewHolders.removeAt(modelPosition)\n        viewHolder.unbind()\n        viewPool.putRecycledView(viewHolder)\n    }\n\n    companion object {\n\n        private val HELPER_ADAPTER = HelperAdapter()\n\n        private fun findViewPool(view: ViewParent): RecyclerView.RecycledViewPool {\n            var viewPool: RecyclerView.RecycledViewPool? = null\n            while (viewPool == null) {\n                viewPool = if (view is RecyclerView) {\n                    view.recycledViewPool\n                } else {\n                    val parent = view.parent\n                    if (parent is ViewParent) {\n                        findViewPool(parent)\n                    } else {\n                        // This model group is is not in a RecyclerView\n                        LocalGroupRecycledViewPool()\n                    }\n                }\n            }\n            return viewPool\n        }\n    }\n}\n\nprivate class ViewStubData(\n    val viewGroup: ViewGroup,\n    val viewStub: ViewStub,\n    val position: Int\n) {\n\n    fun setView(view: View, useStubLayoutParams: Boolean) {\n        removeCurrentView()\n\n        // Carry over the stub id manually since we aren't inflating via the stub\n        val inflatedId = viewStub.inflatedId\n        if (inflatedId != View.NO_ID) {\n            view.id = inflatedId\n        }\n\n        if (useStubLayoutParams) {\n            viewGroup.addView(view, position, viewStub.layoutParams)\n        } else {\n            viewGroup.addView(view, position)\n        }\n    }\n\n    fun resetStub() {\n        removeCurrentView()\n        viewGroup.addView(viewStub, position)\n    }\n\n    private fun removeCurrentView() {\n        val view = viewGroup.getChildAt(position)\n            ?: throw IllegalStateException(\"No view exists at position $position\")\n        viewGroup.removeView(view)\n    }\n}\n\n/**\n * Local pool to the [ModelGroupHolder]\n */\nprivate class LocalGroupRecycledViewPool : RecyclerView.RecycledViewPool()\n\n/**\n * A viewholder's viewtype can only be set internally in an adapter when the viewholder\n * is created. To work around that we do the creation in an adapter.\n */\nprivate class HelperAdapter : RecyclerView.Adapter<EpoxyViewHolder>() {\n\n    private var model: EpoxyModel<*>? = null\n    private var modelGroupParent: ViewParent? = null\n\n    fun createViewHolder(\n        modelGroupParent: ViewParent,\n        model: EpoxyModel<*>,\n        parent: ViewGroup,\n        viewType: Int\n    ): EpoxyViewHolder {\n        this.model = model\n        this.modelGroupParent = modelGroupParent\n        val viewHolder = createViewHolder(parent, viewType)\n        this.model = null\n        this.modelGroupParent = null\n        return viewHolder\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpoxyViewHolder {\n        return EpoxyViewHolder(modelGroupParent, model!!.buildView(parent), model!!.shouldSaveViewState())\n    }\n\n    override fun onBindViewHolder(holder: EpoxyViewHolder, position: Int) {\n    }\n\n    override fun getItemCount() = 1\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelList.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.ConcurrentModificationException;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.NoSuchElementException;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Used by our {@link EpoxyAdapter} to track models. It simply wraps ArrayList and notifies an\n * observer when remove or insertion operations are done on the list. This allows us to optimize\n * diffing since we have a knowledge of what changed in the list.\n */\nclass ModelList extends ArrayList<EpoxyModel<?>> {\n\n  ModelList(int expectedModelCount) {\n    super(expectedModelCount);\n  }\n\n  ModelList() {\n\n  }\n\n  interface ModelListObserver {\n    void onItemRangeInserted(int positionStart, int itemCount);\n    void onItemRangeRemoved(int positionStart, int itemCount);\n  }\n\n  private boolean notificationsPaused;\n  private ModelListObserver observer;\n\n  void pauseNotifications() {\n    if (notificationsPaused) {\n      throw new IllegalStateException(\"Notifications already paused\");\n    }\n    notificationsPaused = true;\n  }\n\n  void resumeNotifications() {\n    if (!notificationsPaused) {\n      throw new IllegalStateException(\"Notifications already resumed\");\n    }\n    notificationsPaused = false;\n  }\n\n  void setObserver(ModelListObserver observer) {\n    this.observer = observer;\n  }\n\n  private void notifyInsertion(int positionStart, int itemCount) {\n    if (!notificationsPaused && observer != null) {\n      observer.onItemRangeInserted(positionStart, itemCount);\n    }\n  }\n\n  private void notifyRemoval(int positionStart, int itemCount) {\n    if (!notificationsPaused && observer != null) {\n      observer.onItemRangeRemoved(positionStart, itemCount);\n    }\n  }\n\n  @Override\n  public EpoxyModel<?> set(int index, EpoxyModel<?> element) {\n    EpoxyModel<?> previousModel = super.set(index, element);\n\n    if (previousModel.id() != element.id()) {\n      notifyRemoval(index, 1);\n      notifyInsertion(index, 1);\n    }\n\n    return previousModel;\n  }\n\n  @Override\n  public boolean add(EpoxyModel<?> epoxyModel) {\n    notifyInsertion(size(), 1);\n    return super.add(epoxyModel);\n  }\n\n  @Override\n  public void add(int index, EpoxyModel<?> element) {\n    notifyInsertion(index, 1);\n    super.add(index, element);\n  }\n\n  @Override\n  public boolean addAll(Collection<? extends EpoxyModel<?>> c) {\n    notifyInsertion(size(), c.size());\n    return super.addAll(c);\n  }\n\n  @Override\n  public boolean addAll(int index, Collection<? extends EpoxyModel<?>> c) {\n    notifyInsertion(index, c.size());\n    return super.addAll(index, c);\n  }\n\n  @Override\n  public EpoxyModel<?> remove(int index) {\n    notifyRemoval(index, 1);\n    return super.remove(index);\n  }\n\n  @Override\n  public boolean remove(Object o) {\n    int index = indexOf(o);\n\n    if (index == -1) {\n      return false;\n    }\n\n    notifyRemoval(index, 1);\n    super.remove(index);\n    return true;\n  }\n\n  @Override\n  public void clear() {\n    if (!isEmpty()) {\n      notifyRemoval(0, size());\n      super.clear();\n    }\n  }\n\n  @Override\n  protected void removeRange(int fromIndex, int toIndex) {\n    if (fromIndex == toIndex) {\n      return;\n    }\n\n    notifyRemoval(fromIndex, toIndex - fromIndex);\n    super.removeRange(fromIndex, toIndex);\n  }\n\n  @Override\n  public boolean removeAll(Collection<?> collection) {\n    // Using this implementation from the Android ArrayList since the Java 1.8 ArrayList\n    // doesn't call through to remove. Calling through to remove lets us leverage the notification\n    // done there\n    boolean result = false;\n    Iterator<?> it = iterator();\n    while (it.hasNext()) {\n      if (collection.contains(it.next())) {\n        it.remove();\n        result = true;\n      }\n    }\n    return result;\n  }\n\n  @Override\n  public boolean retainAll(Collection<?> collection) {\n    // Using this implementation from the Android ArrayList since the Java 1.8 ArrayList\n    // doesn't call through to remove. Calling through to remove lets us leverage the notification\n    // done there\n    boolean result = false;\n    Iterator<?> it = iterator();\n    while (it.hasNext()) {\n      if (!collection.contains(it.next())) {\n        it.remove();\n        result = true;\n      }\n    }\n    return result;\n  }\n\n  @NonNull\n  @Override\n  public Iterator<EpoxyModel<?>> iterator() {\n    return new Itr();\n  }\n\n  /**\n   * An Iterator implementation that calls through to the parent list's methods for modification.\n   * Some implementations, like the Android ArrayList.ArrayListIterator class, modify the list data\n   * directly instead of calling into the parent list's methods. We need the implementation to call\n   * the parent methods so that the proper notifications are done.\n   */\n  private class Itr implements Iterator<EpoxyModel<?>> {\n    int cursor;       // index of next element to return\n    int lastRet = -1; // index of last element returned; -1 if no such\n    int expectedModCount = modCount;\n\n    public boolean hasNext() {\n      return cursor != size();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public EpoxyModel<?> next() {\n      checkForComodification();\n      int i = cursor;\n      cursor = i + 1;\n      lastRet = i;\n      return ModelList.this.get(i);\n    }\n\n    public void remove() {\n      if (lastRet < 0) {\n        throw new IllegalStateException();\n      }\n      checkForComodification();\n\n      try {\n        ModelList.this.remove(lastRet);\n        cursor = lastRet;\n        lastRet = -1;\n        expectedModCount = modCount;\n      } catch (IndexOutOfBoundsException ex) {\n        throw new ConcurrentModificationException();\n      }\n    }\n\n    final void checkForComodification() {\n      if (modCount != expectedModCount) {\n        throw new ConcurrentModificationException();\n      }\n    }\n  }\n\n  @NonNull\n  @Override\n  public ListIterator<EpoxyModel<?>> listIterator() {\n    return new ListItr(0);\n  }\n\n  @NonNull\n  @Override\n  public ListIterator<EpoxyModel<?>> listIterator(int index) {\n    return new ListItr(index);\n  }\n\n  /**\n   * A ListIterator implementation that calls through to the parent list's methods for modification.\n   * Some implementations may modify the list data directly instead of calling into the parent\n   * list's methods. We need the implementation to call the parent methods so that the proper\n   * notifications are done.\n   */\n  private class ListItr extends Itr implements ListIterator<EpoxyModel<?>> {\n    ListItr(int index) {\n      cursor = index;\n    }\n\n    public boolean hasPrevious() {\n      return cursor != 0;\n    }\n\n    public int nextIndex() {\n      return cursor;\n    }\n\n    public int previousIndex() {\n      return cursor - 1;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public EpoxyModel<?> previous() {\n      checkForComodification();\n      int i = cursor - 1;\n      if (i < 0) {\n        throw new NoSuchElementException();\n      }\n\n      cursor = i;\n      lastRet = i;\n      return ModelList.this.get(i);\n    }\n\n    public void set(EpoxyModel<?> e) {\n      if (lastRet < 0) {\n        throw new IllegalStateException();\n      }\n      checkForComodification();\n\n      try {\n        ModelList.this.set(lastRet, e);\n      } catch (IndexOutOfBoundsException ex) {\n        throw new ConcurrentModificationException();\n      }\n    }\n\n    public void add(EpoxyModel<?> e) {\n      checkForComodification();\n\n      try {\n        int i = cursor;\n        ModelList.this.add(i, e);\n        cursor = i + 1;\n        lastRet = -1;\n        expectedModCount = modCount;\n      } catch (IndexOutOfBoundsException ex) {\n        throw new ConcurrentModificationException();\n      }\n    }\n  }\n\n  @NonNull\n  @Override\n  public List<EpoxyModel<?>> subList(int start, int end) {\n    if (start >= 0 && end <= size()) {\n      if (start <= end) {\n        return new SubList(this, start, end);\n      }\n      throw new IllegalArgumentException();\n    }\n    throw new IndexOutOfBoundsException();\n  }\n\n  /**\n   * A SubList implementation from Android's AbstractList class. It's copied here to make sure the\n   * implementation doesn't change, since some implementations, like the Java 1.8 ArrayList.SubList\n   * class, modify the list data directly instead of calling into the parent list's methods. We need\n   * the implementation to call the parent methods so that the proper notifications are done.\n   */\n  private static class SubList extends AbstractList<EpoxyModel<?>> {\n    private final ModelList fullList;\n    private int offset;\n    private int size;\n\n    private static final class SubListIterator implements ListIterator<EpoxyModel<?>> {\n      private final SubList subList;\n      private final ListIterator<EpoxyModel<?>> iterator;\n      private int start;\n      private int end;\n\n      SubListIterator(ListIterator<EpoxyModel<?>> it, SubList list, int offset, int length) {\n        iterator = it;\n        subList = list;\n        start = offset;\n        end = start + length;\n      }\n\n      public void add(EpoxyModel<?> object) {\n        iterator.add(object);\n        subList.sizeChanged(true);\n        end++;\n      }\n\n      public boolean hasNext() {\n        return iterator.nextIndex() < end;\n      }\n\n      public boolean hasPrevious() {\n        return iterator.previousIndex() >= start;\n      }\n\n      public EpoxyModel<?> next() {\n        if (iterator.nextIndex() < end) {\n          return iterator.next();\n        }\n        throw new NoSuchElementException();\n      }\n\n      public int nextIndex() {\n        return iterator.nextIndex() - start;\n      }\n\n      public EpoxyModel<?> previous() {\n        if (iterator.previousIndex() >= start) {\n          return iterator.previous();\n        }\n        throw new NoSuchElementException();\n      }\n\n      public int previousIndex() {\n        int previous = iterator.previousIndex();\n        if (previous >= start) {\n          return previous - start;\n        }\n        return -1;\n      }\n\n      public void remove() {\n        iterator.remove();\n        subList.sizeChanged(false);\n        end--;\n      }\n\n      public void set(EpoxyModel<?> object) {\n        iterator.set(object);\n      }\n    }\n\n    SubList(ModelList list, int start, int end) {\n      fullList = list;\n      modCount = fullList.modCount;\n      offset = start;\n      size = end - start;\n    }\n\n    @Override\n    public void add(int location, EpoxyModel<?> object) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location <= size) {\n          fullList.add(location + offset, object);\n          size++;\n          modCount = fullList.modCount;\n        } else {\n          throw new IndexOutOfBoundsException();\n        }\n      } else {\n        throw new ConcurrentModificationException();\n      }\n    }\n\n    @Override\n    public boolean addAll(int location, Collection<? extends EpoxyModel<?>> collection) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location <= size) {\n          boolean result = fullList.addAll(location + offset, collection);\n          if (result) {\n            size += collection.size();\n            modCount = fullList.modCount;\n          }\n          return result;\n        }\n        throw new IndexOutOfBoundsException();\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @Override\n    public boolean addAll(@NonNull Collection<? extends EpoxyModel<?>> collection) {\n      if (modCount == fullList.modCount) {\n        boolean result = fullList.addAll(offset + size, collection);\n        if (result) {\n          size += collection.size();\n          modCount = fullList.modCount;\n        }\n        return result;\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @Override\n    public EpoxyModel<?> get(int location) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location < size) {\n          return fullList.get(location + offset);\n        }\n        throw new IndexOutOfBoundsException();\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @NonNull\n    @Override\n    public Iterator<EpoxyModel<?>> iterator() {\n      return listIterator(0);\n    }\n\n    @NonNull\n    @Override\n    public ListIterator<EpoxyModel<?>> listIterator(int location) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location <= size) {\n          return new SubListIterator(fullList.listIterator(location + offset), this, offset, size);\n        }\n        throw new IndexOutOfBoundsException();\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @Override\n    public EpoxyModel<?> remove(int location) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location < size) {\n          EpoxyModel<?> result = fullList.remove(location + offset);\n          size--;\n          modCount = fullList.modCount;\n          return result;\n        }\n        throw new IndexOutOfBoundsException();\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @Override\n    protected void removeRange(int start, int end) {\n      if (start != end) {\n        if (modCount == fullList.modCount) {\n          fullList.removeRange(start + offset, end + offset);\n          size -= end - start;\n          modCount = fullList.modCount;\n        } else {\n          throw new ConcurrentModificationException();\n        }\n      }\n    }\n\n    @Override\n    public EpoxyModel<?> set(int location, EpoxyModel<?> object) {\n      if (modCount == fullList.modCount) {\n        if (location >= 0 && location < size) {\n          return fullList.set(location + offset, object);\n        }\n        throw new IndexOutOfBoundsException();\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    @Override\n    public int size() {\n      if (modCount == fullList.modCount) {\n        return size;\n      }\n      throw new ConcurrentModificationException();\n    }\n\n    void sizeChanged(boolean increment) {\n      if (increment) {\n        size++;\n      } else {\n        size--;\n      }\n      modCount = fullList.modCount;\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelState.java",
    "content": "package com.airbnb.epoxy;\n\n/** Helper to store relevant information about a model that we need to determine if it changed. */\nclass ModelState {\n  long id;\n  int hashCode;\n  int position;\n  EpoxyModel<?> model;\n\n  /**\n   * A link to the item with the same id in the other list when diffing two lists. This will be null\n   * if the item doesn't exist, in the case of insertions or removals. This is an optimization to\n   * prevent having to look up the matching pair in a hash map every time.\n   */\n  ModelState pair;\n\n  /**\n   * How many movement operations have been applied to this item in order to update its position. As\n   * we find more item movements we need to update the position of affected items in the list in\n   * order to correctly calculate the next movement. Instead of iterating through all items in the\n   * list every time a movement operation happens we keep track of how many of these operations have\n   * been applied to an item, and apply all new operations in order when we need to get this item's\n   * up to date position.\n   */\n  int lastMoveOp;\n\n  static ModelState build(EpoxyModel<?> model, int position, boolean immutableModel) {\n    ModelState state = new ModelState();\n\n    state.lastMoveOp = 0;\n    state.pair = null;\n    state.id = model.id();\n    state.position = position;\n\n    if (immutableModel) {\n      state.model = model;\n    } else {\n      state.hashCode = model.hashCode();\n    }\n\n    return state;\n  }\n\n  /**\n   * Used for an item inserted into the new list when we need to track moves that effect the\n   * inserted item in the old list.\n   */\n  void pairWithSelf() {\n    if (pair != null) {\n      throw new IllegalStateException(\"Already paired.\");\n    }\n\n    pair = new ModelState();\n    pair.lastMoveOp = 0;\n    pair.id = id;\n    pair.position = position;\n    pair.hashCode = hashCode;\n    pair.pair = this;\n    pair.model = model;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelState{\"\n        + \"id=\" + id\n        + \", model=\" + model\n        + \", hashCode=\" + hashCode\n        + \", position=\" + position\n        + \", pair=\" + pair\n        + \", lastMoveOp=\" + lastMoveOp\n        + '}';\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/NoOpControllerHelper.java",
    "content": "package com.airbnb.epoxy;\n\n/**\n * A {@link ControllerHelper} implementation for adapters with no {@link\n * com.airbnb.epoxy.AutoModel} usage.\n */\nclass NoOpControllerHelper extends ControllerHelper<EpoxyController> {\n\n  @Override\n  public void resetAutoModels() {\n    // No - Op\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/NoOpTimer.java",
    "content": "package com.airbnb.epoxy;\n\nclass NoOpTimer implements Timer {\n  @Override\n  public void start(String sectionName) {\n\n  }\n\n  @Override\n  public void stop() {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/NotifyBlocker.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\n/**\n * We don't allow any data change notifications except the ones done though diffing. Forcing\n * changes to happen through diffing reduces the chance for developer error when implementing an\n * adapter.\n * <p>\n * This observer throws upon any changes done outside of diffing.\n */\nclass NotifyBlocker extends AdapterDataObserver {\n\n  private boolean changesAllowed;\n\n  void allowChanges() {\n    changesAllowed = true;\n  }\n\n  void blockChanges() {\n    changesAllowed = false;\n  }\n\n  @Override\n  public void onChanged() {\n    if (!changesAllowed) {\n      throw new IllegalStateException(\n          \"You cannot notify item changes directly. Call `requestModelBuild` instead.\");\n    }\n  }\n\n  @Override\n  public void onItemRangeChanged(int positionStart, int itemCount) {\n    onChanged();\n  }\n\n  @Override\n  public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {\n    onChanged();\n  }\n\n  @Override\n  public void onItemRangeInserted(int positionStart, int itemCount) {\n    onChanged();\n  }\n\n  @Override\n  public void onItemRangeRemoved(int positionStart, int itemCount) {\n    onChanged();\n  }\n\n  @Override\n  public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\n    onChanged();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelBoundListener.java",
    "content": "package com.airbnb.epoxy;\n\n/** Used to register an onBind callback with a generated model. */\npublic interface OnModelBoundListener<T extends EpoxyModel<?>, V> {\n  /**\n   * This will be called immediately after a model was bound, with the model and view that were\n   * bound together.\n   *\n   * @param model    The model being bound\n   * @param view     The view that is being bound to the model\n   * @param position The adapter position of the model\n   */\n  void onModelBound(T model, V view, int position);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelBuildFinishedListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Used with {@link EpoxyController#addModelBuildListener(OnModelBuildFinishedListener)} to be\n * alerted to new model changes.\n */\npublic interface OnModelBuildFinishedListener {\n  /**\n   * Called after {@link EpoxyController#buildModels()} has run and changes have been notified to\n   * the adapter. This will be called even if no changes existed.\n   */\n  void onModelBuildFinished(@NonNull DiffResult result);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelCheckedChangeListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.widget.CompoundButton;\n\npublic interface OnModelCheckedChangeListener<T extends EpoxyModel<?>, V> {\n  /**\n   * Called when the view bound to the model is checked.\n   *\n   * @param model       The model that the view is bound to.\n   * @param parentView  The view bound to the model which received the click.\n   * @param checkedView The view that received the click. This is either a child of the parentView\n   *                    or the parentView itself\n   * @param isChecked   The new value for isChecked property.\n   * @param position    The position of the model in the adapter.\n   */\n  void onChecked(T model, V parentView,\n      CompoundButton checkedView, boolean isChecked, int position);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelClickListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\n/** Used to register a click listener on a generated model. */\npublic interface OnModelClickListener<T extends EpoxyModel<?>, V> {\n  /**\n   * Called when the view bound to the model is clicked.\n   *\n   * @param model       The model that the view is bound to.\n   * @param parentView  The view bound to the model which received the click.\n   * @param clickedView The view that received the click. This is either a child of the parentView\n   *                    or the parentView itself\n   * @param position    The position of the model in the adapter.\n   */\n  void onClick(T model, V parentView, View clickedView, int position);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelLongClickListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\npublic interface OnModelLongClickListener<T extends EpoxyModel<?>, V> {\n  /**\n   * Called when the view bound to the model is clicked.\n   *\n   * @param model       The model that the view is bound to.\n   * @param parentView  The view bound to the model which received the click.\n   * @param clickedView The view that received the click. This is either a child of the parentView\n   *                    or the parentView itself\n   * @param position    The position of the model in the adapter.\n   */\n  boolean onLongClick(T model, V parentView, View clickedView, int position);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelUnboundListener.java",
    "content": "package com.airbnb.epoxy;\n\n/** Used to register an onUnbind callback with a generated model. */\npublic interface OnModelUnboundListener<T extends EpoxyModel<?>, V> {\n  /**\n   * This will be called immediately after a model is unbound from a view, with the view and model\n   * that were unbound.\n   */\n  void onModelUnbound(T model, V view);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelVisibilityChangedListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.Px;\n\n/** Used to register an onVisibilityChanged callback with a generated model. */\npublic interface OnModelVisibilityChangedListener<T extends EpoxyModel<V>, V> {\n\n  /**\n   * This will be called once the view visible part changes.\n   * <p>\n   * OnModelVisibilityChangedListener should be used with particular care since they will be\n   * dispatched on every frame while scrolling. No heavy work should be done inside the\n   * implementation. Using {@link OnModelVisibilityStateChangedListener} is recommended whenever\n   * possible.\n   * <p>\n   * @param model                The model being bound\n   * @param view                 The view that is being bound to the model\n   * @param percentVisibleHeight The percentage of height visible (0-100)\n   * @param percentVisibleWidth  The percentage of width visible (0-100)\n   * @param heightVisible        The visible height in pixel\n   * @param widthVisible         The visible width in pixel\n   */\n  void onVisibilityChanged(T model, V view,\n      @FloatRange(from = 0, to = 100) float percentVisibleHeight,\n      @FloatRange(from = 0, to = 100) float percentVisibleWidth,\n      @Px int heightVisible, @Px int widthVisible);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/OnModelVisibilityStateChangedListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.VisibilityState.Visibility;\n\n/** Used to register an onVisibilityChanged callback with a generated model. */\npublic interface OnModelVisibilityStateChangedListener<T extends EpoxyModel<V>, V> {\n\n  /**\n   * This will be called once the visibility changed.\n   * <p>\n   * @param model           The model being bound\n   * @param view            The view that is being bound to the model\n   * @param visibilityState The new visibility\n   * <p>\n   * @see VisibilityState\n   */\n  void onVisibilityStateChanged(T model, V view, @Visibility int visibilityState);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/QuantityStringResAttribute.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\n\nimport java.util.Arrays;\n\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\n\npublic class QuantityStringResAttribute {\n  @PluralsRes private final int id;\n  private final int quantity;\n  @Nullable private final Object[] formatArgs;\n\n  public QuantityStringResAttribute(@PluralsRes int id, int quantity,\n      @Nullable Object[] formatArgs) {\n    this.quantity = quantity;\n    this.id = id;\n    this.formatArgs = formatArgs;\n  }\n\n  public QuantityStringResAttribute(int id, int quantity) {\n    this(id, quantity, null);\n  }\n\n  @PluralsRes\n  public int getId() {\n    return id;\n  }\n\n  public int getQuantity() {\n    return quantity;\n  }\n\n  @Nullable\n  public Object[] getFormatArgs() {\n    return formatArgs;\n  }\n\n  public CharSequence toString(Context context) {\n    if (formatArgs == null || formatArgs.length == 0) {\n      return context.getResources().getQuantityString(id, quantity);\n    } else {\n      return context.getResources().getQuantityString(id, quantity, formatArgs);\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof QuantityStringResAttribute)) {\n      return false;\n    }\n\n    QuantityStringResAttribute that = (QuantityStringResAttribute) o;\n\n    if (id != that.id) {\n      return false;\n    }\n    if (quantity != that.quantity) {\n      return false;\n    }\n    // Probably incorrect - comparing Object[] arrays with Arrays.equals\n    return Arrays.equals(formatArgs, that.formatArgs);\n  }\n\n  @Override\n  public int hashCode() {\n    int result = id;\n    result = 31 * result + quantity;\n    result = 31 * result + Arrays.hashCode(formatArgs);\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/SimpleEpoxyAdapter.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * A non-abstract version of {@link com.airbnb.epoxy.EpoxyAdapter} that exposes all methods and\n * models as public. Use this if you don't want to create your own adapter subclass and instead want\n * to modify the adapter from elsewhere, such as from an activity.\n */\npublic class SimpleEpoxyAdapter extends EpoxyAdapter {\n\n  public List<EpoxyModel<?>> getModels() {\n    return models;\n  }\n\n  @Override\n  public void enableDiffing() {\n    super.enableDiffing();\n  }\n\n  @Override\n  public void notifyModelsChanged() {\n    super.notifyModelsChanged();\n  }\n\n  @Override\n  public BoundViewHolders getBoundViewHolders() {\n    return super.getBoundViewHolders();\n  }\n\n  @Override\n  public void notifyModelChanged(EpoxyModel<?> model) {\n    super.notifyModelChanged(model);\n  }\n\n  @Override\n  public void addModels(EpoxyModel<?>... modelsToAdd) {\n    super.addModels(modelsToAdd);\n  }\n\n  @Override\n  public void addModels(Collection<? extends EpoxyModel<?>> modelsToAdd) {\n    super.addModels(modelsToAdd);\n  }\n\n  @Override\n  public void insertModelBefore(EpoxyModel<?> modelToInsert, EpoxyModel<?> modelToInsertBefore) {\n    super.insertModelBefore(modelToInsert, modelToInsertBefore);\n  }\n\n  @Override\n  public void insertModelAfter(EpoxyModel<?> modelToInsert, EpoxyModel<?> modelToInsertAfter) {\n    super.insertModelAfter(modelToInsert, modelToInsertAfter);\n  }\n\n  @Override\n  public void removeModel(EpoxyModel<?> model) {\n    super.removeModel(model);\n  }\n\n  @Override\n  public void removeAllModels() {\n    super.removeAllModels();\n  }\n\n  @Override\n  public void removeAllAfterModel(EpoxyModel<?> model) {\n    super.removeAllAfterModel(model);\n  }\n\n  @Override\n  public void showModel(EpoxyModel<?> model, boolean show) {\n    super.showModel(model, show);\n  }\n\n  @Override\n  public void showModel(EpoxyModel<?> model) {\n    super.showModel(model);\n  }\n\n  @Override\n  public void showModels(EpoxyModel<?>... models) {\n    super.showModels(models);\n  }\n\n  @Override\n  public void showModels(boolean show, EpoxyModel<?>... models) {\n    super.showModels(show, models);\n  }\n\n  @Override\n  public void showModels(Iterable<EpoxyModel<?>> epoxyModels) {\n    super.showModels(epoxyModels);\n  }\n\n  @Override\n  public void showModels(Iterable<EpoxyModel<?>> epoxyModels, boolean show) {\n    super.showModels(epoxyModels, show);\n  }\n\n  @Override\n  public void hideModel(EpoxyModel<?> model) {\n    super.hideModel(model);\n  }\n\n  @Override\n  public void hideModels(Iterable<EpoxyModel<?>> epoxyModels) {\n    super.hideModels(epoxyModels);\n  }\n\n  @Override\n  public void hideModels(EpoxyModel<?>... models) {\n    super.hideModels(models);\n  }\n\n  @Override\n  public void hideAllAfterModel(EpoxyModel<?> model) {\n    super.hideAllAfterModel(model);\n  }\n\n  @Override\n  public List<EpoxyModel<?>> getAllModelsAfter(EpoxyModel<?> model) {\n    return super.getAllModelsAfter(model);\n  }\n\n  @Override\n  public int getModelPosition(EpoxyModel<?> model) {\n    return super.getModelPosition(model);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/SimpleEpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\n/**\n * A small wrapper around {@link com.airbnb.epoxy.EpoxyController} that lets you set a list of\n * models directly.\n */\npublic class SimpleEpoxyController extends EpoxyController {\n  private List<? extends EpoxyModel<?>> currentModels;\n  private boolean insideSetModels;\n\n  /**\n   * Set the models to add to this controller. Clears any previous models and adds this new list\n   * .\n   */\n  public void setModels(List<? extends EpoxyModel<?>> models) {\n    currentModels = models;\n    insideSetModels = true;\n    requestModelBuild();\n    insideSetModels = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!insideSetModels) {\n      throw new IllegalEpoxyUsage(\n          \"You cannot call `requestModelBuild` directly. Call `setModels` instead.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  protected final void buildModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalEpoxyUsage(\n          \"You cannot call `buildModels` directly. Call `setModels` instead.\");\n    }\n    add(currentModels);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/SimpleEpoxyModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport androidx.annotation.CallSuper;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\n\n/**\n * Helper class for cases where you don't need to do anything special when binding the view. This\n * allows you to just provide the layout instead of needing to create a separate {@link EpoxyModel}\n * subclass. This is useful for static layouts. You can also specify an onClick listener and the\n * span size.\n */\npublic class SimpleEpoxyModel extends EpoxyModel<View> {\n  @LayoutRes private final int layoutRes;\n  private View.OnClickListener onClickListener;\n  private int spanCount = 1;\n\n  public SimpleEpoxyModel(@LayoutRes int layoutRes) {\n    this.layoutRes = layoutRes;\n  }\n\n  public SimpleEpoxyModel onClick(View.OnClickListener listener) {\n    this.onClickListener = listener;\n    return this;\n  }\n\n  public SimpleEpoxyModel span(int span) {\n    spanCount = span;\n    return this;\n  }\n\n  @CallSuper\n  @Override\n  public void bind(@NonNull View view) {\n    super.bind(view);\n    view.setOnClickListener(onClickListener);\n    view.setClickable(onClickListener != null);\n  }\n\n  @CallSuper\n  @Override\n  public void unbind(@NonNull View view) {\n    super.unbind(view);\n    view.setOnClickListener(null);\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return layoutRes;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return spanCount;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof SimpleEpoxyModel)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n\n    SimpleEpoxyModel that = (SimpleEpoxyModel) o;\n\n    if (layoutRes != that.layoutRes) {\n      return false;\n    }\n    if (spanCount != that.spanCount) {\n      return false;\n    }\n    return onClickListener != null ? onClickListener.equals(that.onClickListener)\n        : that.onClickListener == null;\n  }\n\n  @Override\n  public int hashCode() {\n    int result = super.hashCode();\n    result = 31 * result + layoutRes;\n    result = 31 * result + (onClickListener != null ? onClickListener.hashCode() : 0);\n    result = 31 * result + spanCount;\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/StringAttributeData.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\n\nimport java.util.Arrays;\n\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\n\npublic class StringAttributeData {\n  private final boolean hasDefault;\n  @Nullable private final CharSequence defaultString;\n  @StringRes private final int defaultStringRes;\n\n  @Nullable private CharSequence string;\n  @StringRes private int stringRes;\n  @PluralsRes private int pluralRes;\n  private int quantity;\n  @Nullable private Object[] formatArgs;\n\n  public StringAttributeData() {\n    hasDefault = false;\n    defaultString = null;\n    defaultStringRes = 0;\n  }\n\n  public StringAttributeData(@Nullable CharSequence defaultString) {\n    hasDefault = true;\n    this.defaultString = defaultString;\n    string = defaultString;\n    defaultStringRes = 0;\n  }\n\n  public StringAttributeData(@StringRes int defaultStringRes) {\n    hasDefault = true;\n    this.defaultStringRes = defaultStringRes;\n    stringRes = defaultStringRes;\n    defaultString = null;\n  }\n\n  public void setValue(@Nullable CharSequence string) {\n    this.string = string;\n    stringRes = 0;\n    pluralRes = 0;\n  }\n\n  public void setValue(@StringRes int stringRes) {\n    setValue(stringRes, null);\n  }\n\n  public void setValue(@StringRes int stringRes, @Nullable Object[] formatArgs) {\n    if (stringRes != 0) {\n      this.stringRes = stringRes;\n      this.formatArgs = formatArgs;\n      string = null;\n      pluralRes = 0;\n    } else {\n      handleInvalidStringRes();\n    }\n  }\n\n  private void handleInvalidStringRes() {\n    if (hasDefault) {\n      if (defaultStringRes != 0) {\n        setValue(defaultStringRes);\n      } else {\n        setValue(defaultString);\n      }\n    } else {\n      throw new IllegalArgumentException(\"0 is an invalid value for required strings.\");\n    }\n  }\n\n  public void setValue(@PluralsRes int pluralRes, int quantity, @Nullable Object[] formatArgs) {\n    if (pluralRes != 0) {\n      this.pluralRes = pluralRes;\n      this.quantity = quantity;\n      this.formatArgs = formatArgs;\n      string = null;\n      stringRes = 0;\n    } else {\n      handleInvalidStringRes();\n    }\n  }\n\n  public CharSequence toString(Context context) {\n    if (pluralRes != 0) {\n      if (formatArgs != null) {\n        return context.getResources().getQuantityString(pluralRes, quantity, formatArgs);\n      } else {\n        return context.getResources().getQuantityString(pluralRes, quantity);\n      }\n    } else if (stringRes != 0) {\n      if (formatArgs != null) {\n        return context.getResources().getString(stringRes, formatArgs);\n      } else {\n        return context.getResources().getText(stringRes);\n      }\n    } else {\n      return string;\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof StringAttributeData)) {\n      return false;\n    }\n\n    StringAttributeData that = (StringAttributeData) o;\n\n    if (stringRes != that.stringRes) {\n      return false;\n    }\n    if (pluralRes != that.pluralRes) {\n      return false;\n    }\n    if (quantity != that.quantity) {\n      return false;\n    }\n    if (string != null ? !string.equals(that.string) : that.string != null) {\n      return false;\n    }\n\n    return Arrays.equals(formatArgs, that.formatArgs);\n  }\n\n  @Override\n  public int hashCode() {\n    int result = string != null ? string.hashCode() : 0;\n    result = 31 * result + stringRes;\n    result = 31 * result + pluralRes;\n    result = 31 * result + quantity;\n    result = 31 * result + Arrays.hashCode(formatArgs);\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/StyleBuilderCallback.java",
    "content": "package com.airbnb.epoxy;\n\n/**\n * Used for specifying dynamic styling for a view when creating a model. This is only used if the\n * view is set up to be styled with the Paris library.\n */\npublic interface StyleBuilderCallback<T> {\n  void buildStyle(T builder);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/Timer.java",
    "content": "package com.airbnb.epoxy;\n\ninterface Timer {\n  void start(String sectionName);\n  void stop();\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/Typed2EpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\n\n/**\n * This is a wrapper around {@link com.airbnb.epoxy.EpoxyController} to simplify how data is\n * accessed. Use this if the data required to build your models is represented by two objects.\n * <p>\n * To use this, create a subclass typed with your data object. Then, call {@link #setData}\n * whenever that data changes. This class will handle calling {@link #buildModels} with the\n * latest data.\n * <p>\n * You should NOT call {@link #requestModelBuild()} directly.\n *\n * @see TypedEpoxyController\n * @see Typed3EpoxyController\n * @see Typed4EpoxyController\n */\npublic abstract class Typed2EpoxyController<T, U> extends EpoxyController {\n\n  private T data1;\n  private U data2;\n  private boolean allowModelBuildRequests;\n\n  public Typed2EpoxyController() {\n  }\n\n  public Typed2EpoxyController(Handler modelBuildingHandler, Handler diffingHandler) {\n    super(modelBuildingHandler, diffingHandler);\n  }\n\n  /**\n   * Call this with the latest data when you want models to be rebuilt. The data will be passed on\n   * to {@link #buildModels(Object, Object)}\n   */\n  public void setData(T data1, U data2) {\n    this.data1 = data1;\n    this.data2 = data2;\n    allowModelBuildRequests = true;\n    requestModelBuild();\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  public void moveModel(int fromPosition, int toPosition) {\n    allowModelBuildRequests = true;\n    super.moveModel(fromPosition, toPosition);\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public void requestDelayedModelBuild(int delayMs) {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestDelayedModelBuild(delayMs);\n  }\n\n  @Override\n  protected final void buildModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalStateException(\n          \"You cannot call `buildModels` directly. Call `setData` instead to trigger a model \"\n              + \"refresh with new data.\");\n    }\n    buildModels(data1, data2);\n  }\n\n  protected abstract void buildModels(T data1, U data2);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/Typed3EpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\n\n/**\n * This is a wrapper around {@link com.airbnb.epoxy.EpoxyController} to simplify how data is\n * accessed. Use this if the data required to build your models is represented by three objects.\n * <p>\n * To use this, create a subclass typed with your data object. Then, call {@link #setData}\n * whenever that data changes. This class will handle calling {@link #buildModels} with the\n * latest data.\n * <p>\n * You should NOT call {@link #requestModelBuild()} directly.\n *\n * @see TypedEpoxyController\n * @see Typed2EpoxyController\n * @see Typed4EpoxyController\n */\npublic abstract class Typed3EpoxyController<T, U, V> extends EpoxyController {\n\n  private T data1;\n  private U data2;\n  private V data3;\n  private boolean allowModelBuildRequests;\n\n  public Typed3EpoxyController() {\n  }\n\n  public Typed3EpoxyController(Handler modelBuildingHandler, Handler diffingHandler) {\n    super(modelBuildingHandler, diffingHandler);\n  }\n\n  /**\n   * Call this with the latest data when you want models to be rebuilt. The data will be passed on\n   * to {@link #buildModels(Object, Object, Object)}\n   */\n  public void setData(T data1, U data2, V data3) {\n    this.data1 = data1;\n    this.data2 = data2;\n    this.data3 = data3;\n    allowModelBuildRequests = true;\n    requestModelBuild();\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  public void moveModel(int fromPosition, int toPosition) {\n    allowModelBuildRequests = true;\n    super.moveModel(fromPosition, toPosition);\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public void requestDelayedModelBuild(int delayMs) {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestDelayedModelBuild(delayMs);\n  }\n\n  @Override\n  protected final void buildModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalStateException(\n          \"You cannot call `buildModels` directly. Call `setData` instead to trigger a model \"\n              + \"refresh with new data.\");\n    }\n    buildModels(data1, data2, data3);\n  }\n\n  protected abstract void buildModels(T data1, U data2, V data3);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/Typed4EpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\n\n/**\n * This is a wrapper around {@link com.airbnb.epoxy.EpoxyController} to simplify how data is\n * accessed. Use this if the data required to build your models is represented by four objects.\n * <p>\n * To use this, create a subclass typed with your data object. Then, call {@link #setData}\n * whenever that data changes. This class will handle calling {@link #buildModels} with the\n * latest data.\n * <p>\n * You should NOT call {@link #requestModelBuild()} directly.\n *\n * @see TypedEpoxyController\n * @see Typed2EpoxyController\n * @see Typed3EpoxyController\n */\npublic abstract class Typed4EpoxyController<T, U, V, W> extends EpoxyController {\n\n  private T data1;\n  private U data2;\n  private V data3;\n  private W data4;\n  private boolean allowModelBuildRequests;\n\n  public Typed4EpoxyController() {\n  }\n\n  public Typed4EpoxyController(Handler modelBuildingHandler, Handler diffingHandler) {\n    super(modelBuildingHandler, diffingHandler);\n  }\n\n  /**\n   * Call this with the latest data when you want models to be rebuilt. The data will be passed on\n   * to {@link #buildModels(Object, Object, Object, Object)}\n   */\n  public void setData(T data1, U data2, V data3, W data4) {\n    this.data1 = data1;\n    this.data2 = data2;\n    this.data3 = data3;\n    this.data4 = data4;\n    allowModelBuildRequests = true;\n    requestModelBuild();\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  public void moveModel(int fromPosition, int toPosition) {\n    allowModelBuildRequests = true;\n    super.moveModel(fromPosition, toPosition);\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public void requestDelayedModelBuild(int delayMs) {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestDelayedModelBuild(delayMs);\n  }\n\n  @Override\n  protected final void buildModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalStateException(\n          \"You cannot call `buildModels` directly. Call `setData` instead to trigger a model \"\n              + \"refresh with new data.\");\n    }\n    buildModels(data1, data2, data3, data4);\n  }\n\n  protected abstract void buildModels(T data1, U data2, V data3, W data4);\n}\n\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/TypedEpoxyController.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.Handler;\nimport androidx.annotation.Nullable;\n\n/**\n * This is a wrapper around {@link com.airbnb.epoxy.EpoxyController} to simplify how data is\n * accessed. Use this if the data required to build your models is represented by a single object.\n * <p>\n * To use this, create a subclass typed with your data object. Then, call {@link #setData(Object)}\n * whenever that data changes. This class will handle calling {@link #buildModels(Object)} with the\n * latest data.\n * <p>\n * You should NOT call {@link #requestModelBuild()} directly.\n *\n * @see Typed2EpoxyController\n * @see Typed3EpoxyController\n * @see Typed4EpoxyController\n */\npublic abstract class TypedEpoxyController<T> extends EpoxyController {\n  private T currentData;\n  private boolean allowModelBuildRequests;\n\n  public TypedEpoxyController() {\n  }\n\n  public TypedEpoxyController(Handler modelBuildingHandler, Handler diffingHandler) {\n    super(modelBuildingHandler, diffingHandler);\n  }\n\n  public final void setData(T data) {\n    currentData = data;\n    allowModelBuildRequests = true;\n    requestModelBuild();\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  public void moveModel(int fromPosition, int toPosition) {\n    allowModelBuildRequests = true;\n    super.moveModel(fromPosition, toPosition);\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public void requestDelayedModelBuild(int delayMs) {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestDelayedModelBuild(delayMs);\n  }\n\n  @Nullable\n  public final T getCurrentData() {\n    return currentData;\n  }\n\n  @Override\n  protected final void buildModels() {\n    if (!isBuildingModels()) {\n      throw new IllegalStateException(\n          \"You cannot call `buildModels` directly. Call `setData` instead to trigger a model \"\n              + \"refresh with new data.\");\n    }\n    buildModels(currentData);\n  }\n\n  protected abstract void buildModels(T data);\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/UnboundedViewPool.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.util.SparseArray\nimport androidx.recyclerview.widget.RecyclerView.RecycledViewPool\nimport androidx.recyclerview.widget.RecyclerView.ViewHolder\nimport java.util.LinkedList\nimport java.util.Queue\n\n/**\n * Like its parent, UnboundedViewPool lets you share Views between multiple RecyclerViews. However\n * there is no maximum number of recycled views that it will store. This usually ends up being\n * optimal, barring any hard memory constraints, as RecyclerViews do not recycle more Views than\n * they need.\n */\ninternal class UnboundedViewPool : RecycledViewPool() {\n\n    private val scrapHeaps = SparseArray<Queue<ViewHolder>>()\n\n    override fun clear() {\n        scrapHeaps.clear()\n    }\n\n    override fun setMaxRecycledViews(viewType: Int, max: Int) {\n        throw UnsupportedOperationException(\n            \"UnboundedViewPool does not support setting a maximum number of recycled views\"\n        )\n    }\n\n    override fun getRecycledView(viewType: Int): ViewHolder? {\n        val scrapHeap = scrapHeaps.get(viewType)\n        return scrapHeap?.poll()\n    }\n\n    override fun putRecycledView(viewHolder: ViewHolder) {\n        getScrapHeapForType(viewHolder.itemViewType).add(viewHolder)\n    }\n\n    override fun getRecycledViewCount(viewType: Int): Int {\n        return scrapHeaps.get(viewType)?.size ?: 0\n    }\n\n    private fun getScrapHeapForType(viewType: Int): Queue<ViewHolder> {\n        var scrapHeap: Queue<ViewHolder>? = scrapHeaps.get(viewType)\n        if (scrapHeap == null) {\n            scrapHeap = LinkedList()\n            scrapHeaps.put(viewType, scrapHeap)\n        }\n        return scrapHeap\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/UpdateOp.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.ArrayList;\n\nimport androidx.annotation.IntDef;\nimport androidx.annotation.Nullable;\n\n/** Defines an operation that makes a change to the epoxy model list. */\nclass UpdateOp {\n\n  @IntDef({ADD, REMOVE, UPDATE, MOVE})\n  @Retention(RetentionPolicy.SOURCE)\n  @interface Type {\n  }\n\n  static final int ADD = 0;\n  static final int REMOVE = 1;\n  static final int UPDATE = 2;\n  static final int MOVE = 3;\n\n  @Type int type;\n  int positionStart;\n  /** Holds the target position if this is a MOVE */\n  int itemCount;\n  ArrayList<EpoxyModel<?>> payloads;\n\n  private UpdateOp() {\n  }\n\n  static UpdateOp instance(@Type int type, int positionStart, int itemCount,\n      @Nullable EpoxyModel<?> payload) {\n    UpdateOp op = new UpdateOp();\n\n    op.type = type;\n    op.positionStart = positionStart;\n    op.itemCount = itemCount;\n\n    op.addPayload(payload);\n\n    return op;\n  }\n\n  /** Returns the index one past the last item in the affected range. */\n  int positionEnd() {\n    return positionStart + itemCount;\n  }\n\n  boolean isAfter(int position) {\n    return position < positionStart;\n  }\n\n  boolean isBefore(int position) {\n    return position >= positionEnd();\n  }\n\n  boolean contains(int position) {\n    return position >= positionStart && position < positionEnd();\n  }\n\n  void addPayload(@Nullable EpoxyModel<?> payload) {\n    if (payload == null) {\n      return;\n    }\n\n    if (payloads == null) {\n      // In most cases this won't be a batch update so we can expect just one payload\n      payloads = new ArrayList<>(1);\n    } else if (payloads.size() == 1) {\n      // There are multiple payloads, but we don't know how big the batch will end up being.\n      // To prevent resizing the list many times we bump it to a medium size\n      payloads.ensureCapacity(10);\n    }\n\n    payloads.add(payload);\n  }\n\n  @Override\n  public String toString() {\n    return \"UpdateOp{\"\n        + \"type=\" + type\n        + \", positionStart=\" + positionStart\n        + \", itemCount=\" + itemCount\n        + '}';\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/UpdateOpHelper.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.UpdateOp.Type;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.annotation.Nullable;\n\nimport static com.airbnb.epoxy.UpdateOp.ADD;\nimport static com.airbnb.epoxy.UpdateOp.MOVE;\nimport static com.airbnb.epoxy.UpdateOp.REMOVE;\nimport static com.airbnb.epoxy.UpdateOp.UPDATE;\n\n/** Helper class to collect changes in a diff, batching when possible. */\nclass UpdateOpHelper {\n  final List<UpdateOp> opList = new ArrayList<>();\n  // We have to be careful to update all item positions in the list when we\n  // do a MOVE. This adds some complexity.\n  // To do this we keep track of all moves and apply them to an item when we\n  // need the up to date position\n  final List<UpdateOp> moves = new ArrayList<>();\n  private UpdateOp lastOp;\n  private int numInsertions;\n  private int numInsertionBatches;\n  private int numRemovals;\n  private int numRemovalBatches;\n\n  void reset() {\n    opList.clear();\n    moves.clear();\n    lastOp = null;\n    numInsertions = 0;\n    numInsertionBatches = 0;\n    numRemovals = 0;\n    numRemovalBatches = 0;\n  }\n\n  void add(int indexToInsert) {\n    add(indexToInsert, 1);\n  }\n\n  void add(int startPosition, int itemCount) {\n    numInsertions += itemCount;\n\n    // We can append to a previously ADD batch if the new items are added anywhere in the\n    // range of the previous batch batch\n    boolean batchWithLast = isLastOp(ADD)\n        && (lastOp.contains(startPosition) || lastOp.positionEnd() == startPosition);\n\n    if (batchWithLast) {\n      addItemsToLastOperation(itemCount, null);\n    } else {\n      numInsertionBatches++;\n      addNewOperation(ADD, startPosition, itemCount);\n    }\n  }\n\n  void update(int indexToChange) {\n    update(indexToChange, null);\n  }\n\n  void update(final int indexToChange, EpoxyModel<?> payload) {\n    if (isLastOp(UPDATE)) {\n      if (lastOp.positionStart == indexToChange + 1) {\n        // Change another item at the start of the batch range\n        addItemsToLastOperation(1, payload);\n        lastOp.positionStart = indexToChange;\n      } else if (lastOp.positionEnd() == indexToChange) {\n        // Add another item at the end of the batch range\n        addItemsToLastOperation(1, payload);\n      } else if (lastOp.contains(indexToChange)) {\n        // This item is already included in the existing batch range, so we don't add any items\n        // to the batch count, but we still need to add the new payload\n        addItemsToLastOperation(0, payload);\n      } else {\n        // The item can't be batched with the previous update operation\n        addNewOperation(UPDATE, indexToChange, 1, payload);\n      }\n    } else {\n      addNewOperation(UPDATE, indexToChange, 1, payload);\n    }\n  }\n\n  void remove(int indexToRemove) {\n    remove(indexToRemove, 1);\n  }\n\n  void remove(int startPosition, int itemCount) {\n    numRemovals += itemCount;\n\n    boolean batchWithLast = false;\n    if (isLastOp(REMOVE)) {\n      if (lastOp.positionStart == startPosition) {\n        // Remove additional items at the end of the batch range\n        batchWithLast = true;\n      } else if (lastOp.isAfter(startPosition)\n          && startPosition + itemCount >= lastOp.positionStart) {\n        // Removes additional items at the start and (possibly) end of the batch\n        lastOp.positionStart = startPosition;\n        batchWithLast = true;\n      }\n    }\n\n    if (batchWithLast) {\n      addItemsToLastOperation(itemCount, null);\n    } else {\n      numRemovalBatches++;\n      addNewOperation(REMOVE, startPosition, itemCount);\n    }\n  }\n\n  private boolean isLastOp(@UpdateOp.Type int updateType) {\n    return lastOp != null && lastOp.type == updateType;\n  }\n\n  private void addNewOperation(@Type int type, int position, int itemCount) {\n    addNewOperation(type, position, itemCount, null);\n  }\n\n  private void addNewOperation(@Type int type, int position, int itemCount,\n      @Nullable EpoxyModel<?> payload) {\n    lastOp = UpdateOp.instance(type, position, itemCount, payload);\n    opList.add(lastOp);\n  }\n\n  private void addItemsToLastOperation(int numItemsToAdd, EpoxyModel<?> payload) {\n    lastOp.itemCount += numItemsToAdd;\n    lastOp.addPayload(payload);\n  }\n\n  void move(int from, int to) {\n    // We can't batch moves\n    lastOp = null;\n    UpdateOp op = UpdateOp.instance(MOVE, from, to, null);\n    opList.add(op);\n    moves.add(op);\n  }\n\n  int getNumRemovals() {\n    return numRemovals;\n  }\n\n  boolean hasRemovals() {\n    return numRemovals > 0;\n  }\n\n  int getNumInsertions() {\n    return numInsertions;\n  }\n\n  boolean hasInsertions() {\n    return numInsertions > 0;\n  }\n\n  int getNumMoves() {\n    return moves.size();\n  }\n\n  int getNumInsertionBatches() {\n    return numInsertionBatches;\n  }\n\n  int getNumRemovalBatches() {\n    return numRemovalBatches;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ViewHolderState.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\nimport android.util.SparseArray;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ViewHolderState.ViewState;\nimport com.airbnb.viewmodeladapter.R;\n\nimport java.util.Collection;\n\nimport androidx.collection.LongSparseArray;\n\n/**\n * Helper for {@link EpoxyAdapter} to store the state of Views in the adapter. This is useful for\n * saving changes due to user input, such as text input or selection, when a view is scrolled off\n * screen or if the adapter needs to be recreated.\n * <p/>\n * This saved state is separate from the state represented by a {@link EpoxyModel}, which should\n * represent the more permanent state of the data shown in the view. This class stores transient\n * state that is added to the View after it is bound to a {@link EpoxyModel}. For example, a {@link\n * EpoxyModel} may inflate and bind an EditText and then be responsible for styling it and attaching\n * listeners. If the user then inputs text, scrolls the view offscreen and then scrolls back, this\n * class will preserve the inputted text without the {@link EpoxyModel} needing to be aware of its\n * existence.\n * <p/>\n * This class relies on the adapter having stable ids, as the state of a view is mapped to the id of\n * the {@link EpoxyModel}.\n */\n@SuppressWarnings(\"WeakerAccess\")\nclass ViewHolderState extends LongSparseArray<ViewState> implements Parcelable {\n  ViewHolderState() {\n  }\n\n  private ViewHolderState(int size) {\n    super(size);\n  }\n\n  @Override\n  public int describeContents() {\n    return 0;\n  }\n\n  @Override\n  public void writeToParcel(Parcel dest, int flags) {\n    final int size = size();\n    dest.writeInt(size);\n    for (int i = 0; i < size; i++) {\n      dest.writeLong(keyAt(i));\n      dest.writeParcelable(valueAt(i), 0);\n    }\n  }\n\n  public static final Creator<ViewHolderState> CREATOR = new Creator<ViewHolderState>() {\n\n    public ViewHolderState[] newArray(int size) {\n      return new ViewHolderState[size];\n    }\n\n    public ViewHolderState createFromParcel(Parcel source) {\n      int size = source.readInt();\n      ViewHolderState state = new ViewHolderState(size);\n\n      for (int i = 0; i < size; i++) {\n        long key = source.readLong();\n        ViewState value = source.readParcelable(ViewState.class.getClassLoader());\n        state.put(key, value);\n      }\n\n      return state;\n    }\n  };\n\n  public boolean hasStateForHolder(EpoxyViewHolder holder) {\n    return get(holder.getItemId()) != null;\n  }\n\n  public void save(Collection<EpoxyViewHolder> holders) {\n    for (EpoxyViewHolder holder : holders) {\n      save(holder);\n    }\n  }\n\n  /** Save the state of the view bound to the given holder. */\n  public void save(EpoxyViewHolder holder) {\n    if (!holder.getModel().shouldSaveViewState()) {\n      return;\n    }\n\n    // Reuse the previous sparse array if available. We shouldn't need to clear it since the\n    // exact same view type is being saved to it, which\n    // should have identical ids for all its views, and will just overwrite the previous state.\n    ViewState state = get(holder.getItemId());\n    if (state == null) {\n      state = new ViewState();\n    }\n\n    state.save(holder.itemView);\n    put(holder.getItemId(), state);\n  }\n\n  /**\n   * If a state was previously saved for this view holder via {@link #save} it will be restored\n   * here.\n   */\n  public void restore(EpoxyViewHolder holder) {\n    if (!holder.getModel().shouldSaveViewState()) {\n      return;\n    }\n\n    ViewState state = get(holder.getItemId());\n    if (state != null) {\n      state.restore(holder.itemView);\n    } else {\n      // The first time a model is bound it won't have previous state. We need to make sure\n      // the view is reset to its initial state to clear any changes from previously bound models\n      holder.restoreInitialViewState();\n    }\n  }\n\n  /**\n   * A wrapper around a sparse array as a helper to save the state of a view. This also adds\n   * parcelable support.\n   */\n  public static class ViewState extends SparseArray<Parcelable> implements Parcelable {\n\n    ViewState() {\n    }\n\n    private ViewState(int size, int[] keys, Parcelable[] values) {\n      super(size);\n      for (int i = 0; i < size; ++i) {\n        put(keys[i], values[i]);\n      }\n    }\n\n    public void save(View view) {\n      int originalId = view.getId();\n      setIdIfNoneExists(view);\n\n      view.saveHierarchyState(this);\n      view.setId(originalId);\n    }\n\n    public void restore(View view) {\n      int originalId = view.getId();\n      setIdIfNoneExists(view);\n\n      view.restoreHierarchyState(this);\n      view.setId(originalId);\n    }\n\n    /**\n     * If a view hasn't had an id set we need to set a temporary one in order to save state, since a\n     * view won't save its state unless it has an id. The view's id is also the key into the sparse\n     * array for its saved state, so the temporary one we choose just needs to be consistent between\n     * saving and restoring state.\n     */\n    private void setIdIfNoneExists(View view) {\n      if (view.getId() == View.NO_ID) {\n        view.setId(R.id.view_model_state_saving_id);\n      }\n    }\n\n    @Override\n    public int describeContents() {\n      return 0;\n    }\n\n    @Override\n    public void writeToParcel(Parcel parcel, int flags) {\n      int size = size();\n      int[] keys = new int[size];\n      Parcelable[] values = new Parcelable[size];\n      for (int i = 0; i < size; ++i) {\n        keys[i] = keyAt(i);\n        values[i] = valueAt(i);\n      }\n      parcel.writeInt(size);\n      parcel.writeIntArray(keys);\n      parcel.writeParcelableArray(values, flags);\n    }\n\n    public static final Creator<ViewState> CREATOR =\n        new Parcelable.ClassLoaderCreator<ViewState>() {\n          @Override\n          public ViewState createFromParcel(Parcel source, ClassLoader loader) {\n            int size = source.readInt();\n            int[] keys = new int[size];\n            source.readIntArray(keys);\n            Parcelable[] values = source.readParcelableArray(loader);\n            return new ViewState(size, keys, values);\n          }\n\n          @Override\n          public ViewState createFromParcel(Parcel source) {\n            return createFromParcel(source, null);\n          }\n\n          @Override\n          public ViewState[] newArray(int size) {\n            return new ViewState[size];\n          }\n        };\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/ViewTypeManager.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nclass ViewTypeManager {\n  private static final Map<Class, Integer> VIEW_TYPE_MAP = new HashMap<>();\n  /**\n   * The last model that had its view type looked up. This is stored so in most cases we can quickly\n   * look up what view type belongs to which model.\n   */\n  @Nullable\n  EpoxyModel<?> lastModelForViewTypeLookup;\n\n  /**\n   * The type map is static so that models of the same class share the same views across different\n   * adapters. This is useful for view recycling when the adapter instance changes, or when there\n   * are multiple adapters. For testing purposes though it is good to be able to clear the map so we\n   * don't carry over values across tests.\n   */\n  @VisibleForTesting\n  void resetMapForTesting() {\n    VIEW_TYPE_MAP.clear();\n  }\n\n  int getViewTypeAndRememberModel(EpoxyModel<?> model) {\n    lastModelForViewTypeLookup = model;\n    return getViewType(model);\n  }\n\n  static int getViewType(EpoxyModel<?> model) {\n    int defaultViewType = model.getViewType();\n    if (defaultViewType != 0) {\n      return defaultViewType;\n    }\n\n    // If a model does not specify a view type then we generate a value to use for models of that\n    // class.\n    Class modelClass = model.getClass();\n\n    Integer viewType = VIEW_TYPE_MAP.get(modelClass);\n\n    if (viewType == null) {\n      viewType = -VIEW_TYPE_MAP.size() - 1;\n      VIEW_TYPE_MAP.put(modelClass, viewType);\n    }\n\n    return viewType;\n  }\n\n  /**\n   * Find the model that has the given view type so we can create a view for that model. In most\n   * cases this value is a layout resource and we could simply inflate it, but to support {@link\n   * EpoxyModelWithView} we can't assume the view type is a layout. In that case we need to lookup\n   * the model so we can ask it to create a new view for itself.\n   * <p>\n   * To make this efficient, we rely on the RecyclerView implementation detail that {@link\n   * BaseEpoxyAdapter#getItemViewType(int)} is called immediately before {@link\n   * BaseEpoxyAdapter#onCreateViewHolder(android.view.ViewGroup, int)} . We cache the last model\n   * that had its view type looked up, and unless that implementation changes we expect to have a\n   * very fast lookup for the correct model.\n   * <p>\n   * To be safe, we fallback to searching through all models for a view type match. This is slow and\n   * shouldn't be needed, but is a guard against recyclerview behavior changing.\n   */\n  EpoxyModel<?> getModelForViewType(BaseEpoxyAdapter adapter, int viewType) {\n    if (lastModelForViewTypeLookup != null\n        && getViewType(lastModelForViewTypeLookup) == viewType) {\n      // We expect this to be a hit 100% of the time\n      return lastModelForViewTypeLookup;\n    }\n\n    adapter.onExceptionSwallowed(\n        new IllegalStateException(\"Last model did not match expected view type\"));\n\n    // To be extra safe in case RecyclerView implementation details change...\n    for (EpoxyModel<?> model : adapter.getCurrentModels()) {\n      if (getViewType(model) == viewType) {\n        return model;\n      }\n    }\n\n    // Check for the hidden model.\n    HiddenEpoxyModel hiddenEpoxyModel = new HiddenEpoxyModel();\n    if (viewType == hiddenEpoxyModel.getViewType()) {\n      return hiddenEpoxyModel;\n    }\n\n    throw new IllegalStateException(\"Could not find model for view type: \" + viewType);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/VisibilityState.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\nimport androidx.annotation.IntDef;\n\npublic final class VisibilityState {\n\n  @Retention(RetentionPolicy.SOURCE)\n  @IntDef({VISIBLE,\n           INVISIBLE,\n           FOCUSED_VISIBLE,\n           UNFOCUSED_VISIBLE,\n           FULL_IMPRESSION_VISIBLE,\n           PARTIAL_IMPRESSION_VISIBLE,\n           PARTIAL_IMPRESSION_INVISIBLE})\n  public @interface Visibility {\n  }\n\n  /**\n   * Event triggered when a Component enters the Visible Range. This happens when at least a pixel\n   * of the Component is visible.\n   */\n  public static final int VISIBLE = 0;\n\n  /**\n   * Event triggered when a Component becomes invisible. This is the same with exiting the Visible\n   * Range, the Focused Range and the Full Impression Range. All the code that needs to be executed\n   * when a component leaves any of these ranges should be written in the handler for this event.\n   */\n  public static final int INVISIBLE = 1;\n\n  /**\n   * Event triggered when a Component enters the Focused Range. This happens when either the\n   * Component occupies at least half of the viewport or, if the Component is smaller than half of\n   * the viewport, when the it is fully visible.\n   */\n  public static final int FOCUSED_VISIBLE = 2;\n\n  /**\n   * Event triggered when a Component exits the Focused Range. The Focused Range is defined as at\n   * least half of the viewport or, if the Component is smaller than half of the viewport, when the\n   * it is fully visible.\n   */\n  public static final int UNFOCUSED_VISIBLE = 3;\n\n  /**\n   * Event triggered when a Component enters the Full Impression Range. This happens, for instance\n   * in the case of a vertical RecyclerView, when both the top and bottom edges of the component\n   * become visible.\n   */\n  public static final int FULL_IMPRESSION_VISIBLE = 4;\n\n  /**\n   * Event triggered when a Component enters the Partial Impression Range. This happens, for\n   * instance in the case of a vertical RecyclerView, when the percentage of the visible area is\n   * at least the specified threshold. The threshold can be set in\n   * {@link EpoxyVisibilityTracker#setPartialImpressionThresholdPercentage(int)}.\n   */\n  public static final int PARTIAL_IMPRESSION_VISIBLE = 5;\n\n  /**\n   * Event triggered when a Component exits the Partial Impression Range. This happens, for\n   * instance in the case of a vertical RecyclerView, when the percentage of the visible area is\n   * less than a specified threshold. The threshold can be set in\n   * {@link EpoxyVisibilityTracker#setPartialImpressionThresholdPercentage(int)}.\n   */\n  public static final int PARTIAL_IMPRESSION_INVISIBLE = 6;\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.widget.CompoundButton;\nimport android.widget.CompoundButton.OnCheckedChangeListener;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * Used in the generated models to transform normal checked change listener to model\n * checked change.\n */\npublic class WrappedEpoxyModelCheckedChangeListener<T extends EpoxyModel<?>, V>\n    implements OnCheckedChangeListener {\n\n  private final OnModelCheckedChangeListener<T, V> originalCheckedChangeListener;\n\n  public WrappedEpoxyModelCheckedChangeListener(\n      OnModelCheckedChangeListener<T, V> checkedListener\n  ) {\n    if (checkedListener == null) {\n      throw new IllegalArgumentException(\"Checked change listener cannot be null\");\n    }\n\n    this.originalCheckedChangeListener = checkedListener;\n  }\n\n  @Override\n  public void onCheckedChanged(CompoundButton button, boolean isChecked) {\n    EpoxyViewHolder epoxyHolder = ListenersUtils.getEpoxyHolderForChildView(button);\n    if (epoxyHolder == null) {\n      // Initial binding can trigger the checked changed listener when the checked value is set.\n      // The view is not attached at this point so the holder can't be looked up, and in any case\n      // it is generally better to not trigger a callback for the binding anyway, since it isn't\n      // a user action.\n      //\n      // https://github.com/airbnb/epoxy/issues/797\n      return;\n    }\n\n    final int adapterPosition = epoxyHolder.getAdapterPosition();\n    if (adapterPosition != RecyclerView.NO_POSITION) {\n      originalCheckedChangeListener\n          .onChecked((T) epoxyHolder.getModel(), (V) epoxyHolder.objectToBind(), button,\n          isChecked, adapterPosition);\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof WrappedEpoxyModelCheckedChangeListener)) {\n      return false;\n    }\n\n    WrappedEpoxyModelCheckedChangeListener<?, ?>\n        that = (WrappedEpoxyModelCheckedChangeListener<?, ?>) o;\n\n    return originalCheckedChangeListener.equals(that.originalCheckedChangeListener);\n  }\n\n  @Override\n  public int hashCode() {\n    return originalCheckedChangeListener.hashCode();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/WrappedEpoxyModelClickListener.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.view.View.OnClickListener\nimport android.view.View.OnLongClickListener\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * Used in the generated models to transform normal view click listeners to model click\n * listeners.\n */\nclass WrappedEpoxyModelClickListener<T : EpoxyModel<*>, V> : OnClickListener, OnLongClickListener {\n    // Save the original click listener to call back to when clicked.\n    // This also lets us call back to the original hashCode and equals methods\n    private val originalClickListener: OnModelClickListener<T, V>?\n    private val originalLongClickListener: OnModelLongClickListener<T, V>?\n\n    constructor(clickListener: OnModelClickListener<T, V>?) {\n        requireNotNull(clickListener) {\n            \"Click listener cannot be null\"\n        }\n\n        this.originalClickListener = clickListener\n        originalLongClickListener = null\n    }\n\n    constructor(clickListener: OnModelLongClickListener<T, V>?) {\n        requireNotNull(clickListener) {\n            \"Click listener cannot be null\"\n        }\n\n        this.originalLongClickListener = clickListener\n        originalClickListener = null\n    }\n\n    override fun onClick(view: View) {\n        val modelInfo = getClickedModelInfo(view) ?: return\n\n        @Suppress(\"UNCHECKED_CAST\")\n        originalClickListener?.onClick(\n            modelInfo.model as T,\n            modelInfo.boundObject as V,\n            view,\n            modelInfo.adapterPosition\n        ) ?: error(\"Original click listener is null\")\n    }\n\n    override fun onLongClick(view: View): Boolean {\n        val modelInfo = getClickedModelInfo(view) ?: return false\n\n        @Suppress(\"UNCHECKED_CAST\")\n        return originalLongClickListener?.onLongClick(\n            modelInfo.model as T,\n            modelInfo.boundObject as V,\n            view,\n            modelInfo.adapterPosition\n        ) ?: error(\"Original long click listener is null\")\n    }\n\n    private fun getClickedModelInfo(view: View): ClickedModelInfo? {\n        val epoxyHolder = ListenersUtils.getEpoxyHolderForChildView(view)\n            ?: error(\"Could not find RecyclerView holder for clicked view\")\n\n        val adapterPosition = epoxyHolder.adapterPosition\n        if (adapterPosition == RecyclerView.NO_POSITION) return null\n\n        val boundObject = epoxyHolder.objectToBind()\n\n        val holderToUse = if (boundObject is ModelGroupHolder) {\n            // For a model group the clicked view could belong to any of the nested models in the group.\n            // We check the viewholder of each model to see if the clicked view is in that hierarchy\n            // in order to figure out which model it belongs to.\n            // If it doesn't match any of the nested models then it could be set by the top level\n            // parent model.\n            boundObject.viewHolders\n                .firstOrNull { view in it.itemView.allViewsInHierarchy }\n                ?: epoxyHolder\n        } else {\n            epoxyHolder\n        }\n\n        // We return the holder and position because since we may be returning a nested group\n        // holder the callee cannot use that to get the adapter position of the main model.\n        return ClickedModelInfo(\n            holderToUse.model,\n            adapterPosition,\n            holderToUse.objectToBind()\n        )\n    }\n\n    private class ClickedModelInfo(\n        val model: EpoxyModel<*>,\n        val adapterPosition: Int,\n        val boundObject: Any\n    )\n\n    /**\n     * Returns a sequence of this View plus any and all children, recursively.\n     */\n    private val View.allViewsInHierarchy: Sequence<View>\n        get() {\n            return if (this is ViewGroup) {\n                children.flatMap {\n                    sequenceOf(it) + if (it is ViewGroup) it.allViewsInHierarchy else emptySequence()\n                }.plus(this)\n            } else {\n                sequenceOf(this)\n            }\n        }\n\n    /** Returns a [Sequence] over the child views in this view group. */\n    internal val ViewGroup.children: Sequence<View>\n        get() = object : Sequence<View> {\n            override fun iterator() = this@children.iterator()\n        }\n\n    /** Returns a [MutableIterator] over the views in this view group. */\n    internal operator fun ViewGroup.iterator() = object : MutableIterator<View> {\n        private var index = 0\n        override fun hasNext() = index < childCount\n        override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException()\n        override fun remove() = removeViewAt(--index)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) {\n            return true\n        }\n\n        if (other !is WrappedEpoxyModelClickListener<*, *>) {\n            return false\n        }\n\n        if (if (originalClickListener != null) {\n            originalClickListener != other.originalClickListener\n        } else {\n                other.originalClickListener != null\n            }\n        ) {\n            return false\n        }\n        return if (originalLongClickListener != null) {\n            originalLongClickListener == other.originalLongClickListener\n        } else {\n            other.originalLongClickListener == null\n        }\n    }\n\n    override fun hashCode(): Int {\n        var result = originalClickListener?.hashCode() ?: 0\n        result = 31 * result + (originalLongClickListener?.hashCode() ?: 0)\n        return result\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/EpoxyModelPreloader.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyModel\n\n/**\n * Describes how view content for an EpoxyModel should be preloaded.\n *\n * @param T The type of EpoxyModel that this preloader applies to\n * @param U The type of view metadata to provide to the request builder.\n * @param P The type of [PreloadRequestHolder] that will execute the preload request\n */\nabstract class EpoxyModelPreloader<T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder>(\n\n    val modelType: Class<T>,\n\n    /**\n     * A list of view ids, one for each view that should be preloaded.\n     * This should be left empty if the EpoxyModel's type uses the [Preloadable] interface.\n     */\n    val preloadableViewIds: List<Int>\n) {\n\n    /**\n     * An optional signature to differentiate views within the same model. This is useful if your EpoxyModel can contain varying amounts of preloadable views,\n     * or preloadable views of varying sizes.\n     *\n     * By default the model's class, span size, and layout resource, are used to differentiate views. This signature allows additional differentiation.\n     * For example, if your EpoxyModel shows an preloadable view that varies between portrait or landscape, this orientation will affect the view dimensions.\n     * In this case you could return a boolean here to differentiate the two cases so that the preloaded data has the correct orientation.\n     *\n     * The returned object can be anything, but it must implement [Object.hashCode]\n     */\n    open fun viewSignature(epoxyModel: T): Any? = null\n\n    /**\n     * Provide optional metadata about a view. This can be used in [EpoxyModelPreloader.buildRequest]\n     *\n     * A preload request works best if it exactly matches the actual request (in order to match cache keys exactly)\n     * Things such as request transformations, thumbnails, or crop type can affect the cache key.\n     * If your preloadable view is configurable you can capture those options via this metadata.\n     */\n    abstract fun buildViewMetadata(view: View): U\n\n    /**\n     * Start a preload request with the given target.\n     *\n     * @param epoxyModel The EpoxyModel whose content is being preloaded.\n     * @param preloadTarget The target to ues to create and store the request.\n     * @param viewData Information about the view that will hold the preloaded content.\n     */\n    abstract fun startPreload(\n        epoxyModel: T,\n        preloadTarget: P,\n        viewData: ViewData<U>\n    )\n\n    companion object {\n\n        /**\n         * Helper to create a [EpoxyModelPreloader].\n         *\n         * @param viewSignature see [EpoxyModelPreloader.viewSignature]\n         * @param preloadableViewIds see [EpoxyModelPreloader.preloadableViewIds]\n         * @param viewMetadata see [EpoxyModelPreloader.buildViewMetadata]\n         * @param doPreload see [EpoxyModelPreloader.startPreload]\n         */\n        inline fun <reified T : EpoxyModel<*>, P : PreloadRequestHolder> with(\n            preloadableViewIds: List<Int> = emptyList(),\n            noinline doPreload: (epoxyModel: T, preloadTarget: P, viewData: ViewData<ViewMetadata?>) -> Unit\n        ): EpoxyModelPreloader<T, ViewMetadata?, P> =\n            with(\n                preloadableViewIds,\n                viewMetadata = { ViewMetadata.getDefault(it) },\n                viewSignature = { null },\n                doPreload = doPreload\n            )\n\n        /**\n         * Helper to create a [EpoxyModelPreloader].\n         *\n         * @param viewSignature see [EpoxyModelPreloader.viewSignature]\n         * @param preloadableViewIds see [EpoxyModelPreloader.preloadableViewIds]\n         * @param viewMetadata see [EpoxyModelPreloader.buildViewMetadata]\n         * @param doPreload see [EpoxyModelPreloader.startPreload]\n         */\n        inline fun <reified T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> with(\n            preloadableViewIds: List<Int> = emptyList(),\n            noinline viewMetadata: (View) -> U,\n            noinline viewSignature: (T) -> Any? = { _ -> null },\n            noinline doPreload: (epoxyModel: T, preloadTarget: P, viewData: ViewData<U>) -> Unit\n        ): EpoxyModelPreloader<T, U, P> =\n            with(\n                preloadableViewIds = preloadableViewIds,\n                epoxyModelClass = T::class.java,\n                viewMetadata = viewMetadata,\n                viewSignature = viewSignature,\n                doPreload = doPreload\n            )\n\n        /**\n         * Helper to create a [EpoxyModelPreloader]. This is similar to the other helper methods but not inlined so it can be used with Java.\n         *\n         * @param epoxyModelClass The specific type of EpoxyModel that this preloader is for.\n         * @param viewSignature see [EpoxyModelPreloader.viewSignature]\n         * @param preloadableViewIds see [EpoxyModelPreloader.preloadableViewIds]\n         * @param viewMetadata see [EpoxyModelPreloader.buildViewMetadata]\n         * @param doPreload see [EpoxyModelPreloader.startPreload]\n         */\n        fun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> with(\n            preloadableViewIds: List<Int> = emptyList(),\n            epoxyModelClass: Class<T>,\n            viewMetadata: (View) -> U,\n            viewSignature: (T) -> Any? = { _ -> null },\n            doPreload: (epoxyModel: T, preloadTarget: P, viewData: ViewData<U>) -> Unit\n        ): EpoxyModelPreloader<T, U, P> = object : EpoxyModelPreloader<T, U, P>(\n            modelType = epoxyModelClass,\n            preloadableViewIds = preloadableViewIds\n        ) {\n\n            override fun buildViewMetadata(view: View) = viewMetadata(view)\n\n            override fun viewSignature(epoxyModel: T) = viewSignature(epoxyModel)\n\n            override fun startPreload(epoxyModel: T, preloadTarget: P, viewData: ViewData<U>) {\n                doPreload(epoxyModel, preloadTarget, viewData)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/EpoxyPreloader.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport android.content.Context\nimport android.view.View\nimport android.widget.ImageView\nimport androidx.annotation.IdRes\nimport androidx.annotation.Px\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.BaseEpoxyAdapter\nimport com.airbnb.epoxy.EpoxyAdapter\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.getModelForPositionInternal\nimport kotlin.math.max\nimport kotlin.math.min\n\n/**\n * A scroll listener that prefetches view content.\n *\n * To use this, create implementations of [EpoxyModelPreloader] for each EpoxyModel class that you want to preload.\n * Then, use the [EpoxyPreloader.with] methods to create an instance that preloads models of that type.\n * Finally, add the resulting scroll listener to your RecyclerView.\n *\n * If you are using [com.airbnb.epoxy.EpoxyRecyclerView] then use [com.airbnb.epoxy.EpoxyRecyclerView.addPreloader]\n * to setup the preloader as a listener.\n *\n * Otherwise there is a [RecyclerView.addEpoxyPreloader] extension for easy usage.\n */\nclass EpoxyPreloader<P : PreloadRequestHolder> private constructor(\n    private val adapter: BaseEpoxyAdapter,\n    preloadTargetFactory: () -> P,\n    errorHandler: PreloadErrorHandler,\n    private val maxItemsToPreload: Int,\n    modelPreloaders: List<EpoxyModelPreloader<*, *, out P>>\n) : RecyclerView.OnScrollListener() {\n\n    private var lastVisibleRange: IntRange = IntRange.EMPTY\n    private var lastPreloadRange: IntProgression = IntRange.EMPTY\n    private var totalItemCount = -1\n    private var scrollState: Int = RecyclerView.SCROLL_STATE_IDLE\n\n    private val modelPreloaders: Map<Class<out EpoxyModel<*>>, EpoxyModelPreloader<*, *, out P>> =\n        modelPreloaders.associateBy { it.modelType }\n\n    private val requestHolderFactory =\n        PreloadTargetProvider(maxItemsToPreload, preloadTargetFactory)\n\n    private val viewDataCache = PreloadableViewDataProvider(adapter, errorHandler)\n\n    constructor(\n        epoxyController: EpoxyController,\n        requestHolderFactory: () -> P,\n        errorHandler: PreloadErrorHandler,\n        maxItemsToPreload: Int,\n        modelPreloaders: List<EpoxyModelPreloader<*, *, out P>>\n    ) : this(\n        epoxyController.adapter,\n        requestHolderFactory,\n        errorHandler,\n        maxItemsToPreload,\n        modelPreloaders\n    )\n\n    constructor(\n        adapter: EpoxyAdapter,\n        requestHolderFactory: () -> P,\n        errorHandler: PreloadErrorHandler,\n        maxItemsToPreload: Int,\n        modelPreloaders: List<EpoxyModelPreloader<*, *, out P>>\n    ) : this(\n        adapter as BaseEpoxyAdapter,\n        requestHolderFactory,\n        errorHandler,\n        maxItemsToPreload,\n        modelPreloaders\n    )\n\n    init {\n        require(maxItemsToPreload > 0) {\n            \"maxItemsToPreload must be greater than 0. Was $maxItemsToPreload\"\n        }\n    }\n\n    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {\n        scrollState = newState\n    }\n\n    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {\n        if (dx == 0 && dy == 0) {\n            // Sometimes flings register a bunch of 0 dx/dy scroll events. To avoid redundant prefetching we just skip these\n            // Additionally, the first RecyclerView layout notifies a scroll of 0, since that can be an important time for\n            // performance (eg page load) we avoid prefetching at the same time.\n            return\n        }\n\n        if (dx.isFling() || dy.isFling()) {\n            // We avoid preloading during flings for two reasons\n            // 1. Image requests are expensive and we don't want to drop frames on fling\n            // 2. We'll likely scroll past the preloading item anyway\n            return\n        }\n\n        // Update item count before anything else because validations depend on it\n        totalItemCount = recyclerView.adapter?.itemCount ?: 0\n\n        val layoutManager = recyclerView.layoutManager as LinearLayoutManager\n        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()\n        val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()\n\n        if (firstVisiblePosition.isInvalid() || lastVisiblePosition.isInvalid()) {\n            lastVisibleRange = IntRange.EMPTY\n            lastPreloadRange = IntRange.EMPTY\n            return\n        }\n\n        val visibleRange = IntRange(firstVisiblePosition, lastVisiblePosition)\n        if (visibleRange == lastVisibleRange) {\n            return\n        }\n\n        val isIncreasing =\n            visibleRange.first > lastVisibleRange.first || visibleRange.last > lastVisibleRange.last\n\n        val preloadRange =\n            calculatePreloadRange(firstVisiblePosition, lastVisiblePosition, isIncreasing)\n\n        // Start preload for any items that weren't already preloaded\n        preloadRange\n            .subtract(lastPreloadRange)\n            .forEach { preloadAdapterPosition(it) }\n\n        lastVisibleRange = visibleRange\n        lastPreloadRange = preloadRange\n    }\n\n    /**\n     * @receiver The number of pixels scrolled.\n     * @return True if this distance is large enough to be considered a fast fling.\n     */\n    private fun Int.isFling() = Math.abs(this) > FLING_THRESHOLD_PX\n\n    private fun calculatePreloadRange(\n        firstVisiblePosition: Int,\n        lastVisiblePosition: Int,\n        isIncreasing: Boolean\n    ): IntProgression {\n        val from = if (isIncreasing) lastVisiblePosition + 1 else firstVisiblePosition - 1\n        val to = from + if (isIncreasing) maxItemsToPreload - 1 else 1 - maxItemsToPreload\n\n        return IntProgression.fromClosedRange(\n            rangeStart = from.clampToAdapterRange(),\n            rangeEnd = to.clampToAdapterRange(),\n            step = if (isIncreasing) 1 else -1\n        )\n    }\n\n    /** Check if an item index is valid. It may not be if the adapter is empty, or if adapter changes have been dispatched since the last layout pass. */\n    private fun Int.isInvalid() = this == RecyclerView.NO_POSITION || this >= totalItemCount\n\n    private fun Int.clampToAdapterRange() = min(totalItemCount - 1, max(this, 0))\n\n    private fun preloadAdapterPosition(position: Int) {\n        @Suppress(\"UNCHECKED_CAST\")\n        val epoxyModel = adapter.getModelForPositionInternal(position) as? EpoxyModel<Any>\n            ?: return\n\n        @Suppress(\"UNCHECKED_CAST\")\n        val preloader =\n            modelPreloaders[epoxyModel::class.java] as? EpoxyModelPreloader<EpoxyModel<*>, ViewMetadata?, P>\n                ?: return\n\n        viewDataCache\n            .dataForModel(preloader, epoxyModel, position)\n            .forEach { viewData ->\n                val preloadTarget = requestHolderFactory.next()\n                preloader.startPreload(epoxyModel, preloadTarget, viewData)\n            }\n    }\n\n    /**\n     * Cancels all current preload requests in progress.\n     */\n    fun cancelPreloadRequests() {\n        requestHolderFactory.clearAll()\n    }\n\n    companion object {\n\n        /**\n         *\n         * Represents a threshold for fast scrolling.\n         * This is a bit arbitrary and was determined by looking at values while flinging vs slow scrolling.\n         * Ideally it would be based on DP, but this is simpler.\n         */\n        private const val FLING_THRESHOLD_PX = 75\n\n        /**\n         * Helper to create a preload scroll listener. Add the result to your RecyclerView.\n         * for different models or content types.\n         *\n         * @param maxItemsToPreload How many items to prefetch ahead of the last bound item\n         * @param errorHandler Called when the preloader encounters an exception. By default this throws only\n         * if the app is not in a debuggle model\n         * @param modelPreloader Describes how view content for the EpoxyModel should be preloaded\n         * @param requestHolderFactory Should create and return a new [PreloadRequestHolder] each time it is invoked\n         */\n        fun <P : PreloadRequestHolder> with(\n            epoxyController: EpoxyController,\n            requestHolderFactory: () -> P,\n            errorHandler: PreloadErrorHandler,\n            maxItemsToPreload: Int,\n            modelPreloader: EpoxyModelPreloader<out EpoxyModel<*>, out ViewMetadata?, out P>\n        ): EpoxyPreloader<P> =\n            with(\n                epoxyController,\n                requestHolderFactory,\n                errorHandler,\n                maxItemsToPreload,\n                listOf(modelPreloader)\n            )\n\n        fun <P : PreloadRequestHolder> with(\n            epoxyController: EpoxyController,\n            requestHolderFactory: () -> P,\n            errorHandler: PreloadErrorHandler,\n            maxItemsToPreload: Int,\n            modelPreloaders: List<EpoxyModelPreloader<out EpoxyModel<*>, out ViewMetadata?, out P>>\n        ): EpoxyPreloader<P> {\n\n            return EpoxyPreloader(\n                epoxyController,\n                requestHolderFactory,\n                errorHandler,\n                maxItemsToPreload,\n                modelPreloaders\n            )\n        }\n\n        /** Helper to create a preload scroll listener. Add the result to your RecyclerView. */\n        fun <P : PreloadRequestHolder> with(\n            epoxyAdapter: EpoxyAdapter,\n            requestHolderFactory: () -> P,\n            errorHandler: PreloadErrorHandler,\n            maxItemsToPreload: Int,\n            modelPreloaders: List<EpoxyModelPreloader<out EpoxyModel<*>, out ViewMetadata?, out P>>\n        ): EpoxyPreloader<P> {\n\n            return EpoxyPreloader(\n                epoxyAdapter,\n                requestHolderFactory,\n                errorHandler,\n                maxItemsToPreload,\n                modelPreloaders\n            )\n        }\n    }\n}\n\nclass EpoxyPreloadException(errorMessage: String) : RuntimeException(errorMessage)\n\ntypealias PreloadErrorHandler = (Context, RuntimeException) -> Unit\n\n/**\n * Data about an image view to be preloaded. This data is used to construct a Glide image request.\n *\n * @param metadata Any custom, additional data that the [EpoxyModelPreloader] chooses to provide that may be necessary to create the image request.\n */\nclass ViewData<out U : ViewMetadata?>(\n    @IdRes val viewId: Int,\n    @Px val width: Int,\n    @Px val height: Int,\n    val metadata: U\n)\n\ninterface ViewMetadata {\n    companion object {\n        fun getDefault(view: View): ViewMetadata? {\n            return when (view) {\n                is ImageView -> ImageViewMetadata(view.scaleType)\n                else -> null\n            }\n        }\n    }\n}\n\n/**\n * Default implementation of [ViewMetadata] for an ImageView.\n * This data can help the preload request know how to configure itself.\n */\nopen class ImageViewMetadata(\n    val scaleType: ImageView.ScaleType\n) : ViewMetadata\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/PreloadTargetProvider.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport java.util.ArrayDeque\n\ninternal class PreloadTargetProvider<P : PreloadRequestHolder>(\n    maxPreload: Int,\n    requestHolderFactory: () -> P\n) {\n    private val queue = ArrayDeque<P>((0 until maxPreload).map { requestHolderFactory() })\n\n    internal fun next(): P {\n        val result = queue.poll()\n        queue.offer(result)\n        result.clear()\n        return result\n    }\n\n    fun clearAll() {\n        queue.forEach { it.clear() }\n    }\n}\n\n/**\n * This is responsible for holding details for a preloading request.\n * Your implementation can do anything it wants with the request, but it must\n * cancel and clear itself when [clear] is called.\n *\n * It is also recommended that your implementation calls [clear] when your request finishes loading\n * to avoid unnecessarily hanging onto the request result (assuming the result is also stored in\n * cache). Otherwise this holder can be stored in a pool for later use and may leak the preloaded\n * data.\n */\ninterface PreloadRequestHolder {\n    /** Clear any ongoing preload request. */\n    fun clear()\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/Preloadable.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport android.view.View\n\n/**\n * Declares Views that should be preloaded. This can either be implemented by a custom view or by an [EpoxyHolder].\n *\n * The preloadable views can be recursive ie if [Preloadable.viewsToPreload] includes any views that are themselves Preloadable those nested\n * views will instead by used.\n */\ninterface Preloadable {\n    val viewsToPreload: List<View>\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/PreloadableViewDataProvider.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport android.view.View\nimport androidx.core.view.ViewCompat\nimport com.airbnb.epoxy.BaseEpoxyAdapter\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.boundViewHoldersInternal\nimport com.airbnb.epoxy.objectToBindInternal\nimport com.airbnb.epoxy.viewTypeInternal\n\n/**\n * In order to preload content we need to know the size of the view that they it be loaded into.\n * This class provides the view size, as well as other view metadata that might be necessary to construct the preload request.\n */\ninternal class PreloadableViewDataProvider(\n    val adapter: BaseEpoxyAdapter,\n    val errorHandler: PreloadErrorHandler\n) {\n\n    /**\n     * A given model class might have different sized preloadable views depending on configuration.\n     * We use this cache key to separate view configurations.\n     */\n    private data class CacheKey(\n        val epoxyModelClass: Class<out EpoxyModel<*>>,\n        val spanSize: Int,\n        val viewType: Int,\n        /** An optional, custom signature provided by the model preloader. This allows the user to specify custom cache mixins */\n        val signature: Any?\n    )\n\n    private val cache = mutableMapOf<CacheKey, List<ViewData<*>>?>()\n\n    /** @return A list containing the data necessary to load each view in the given model. */\n    fun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> dataForModel(\n        preloader: EpoxyModelPreloader<T, U, P>,\n        epoxyModel: T,\n        position: Int\n    ): List<ViewData<U>> {\n        val cacheKey = cacheKey(preloader, epoxyModel, position)\n\n        @Suppress(\"UNCHECKED_CAST\")\n        return cache.getOrPut(cacheKey) {\n            // Look up view data based on currently bound views. This can be null if a matching view type is not found.\n            // In that case we save the null so we know to try the lookup again next time.\n            findViewData(preloader, epoxyModel, cacheKey)\n        } as? List<ViewData<U>> ?: return emptyList()\n    }\n\n    private fun <T : EpoxyModel<*>> cacheKey(\n        preloader: EpoxyModelPreloader<T, *, *>,\n        epoxyModel: T,\n        position: Int\n    ): CacheKey {\n        val modelSpanSize = if (adapter.isMultiSpan) {\n            epoxyModel.spanSize(adapter.spanCount, position, adapter.itemCount)\n        } else {\n            1\n        }\n\n        return CacheKey(\n            epoxyModel.javaClass,\n            modelSpanSize,\n            epoxyModel.viewTypeInternal(),\n            preloader.viewSignature(epoxyModel)\n        )\n    }\n\n    private fun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> findViewData(\n        preloader: EpoxyModelPreloader<T, U, P>,\n        epoxyModel: T,\n        cacheKey: CacheKey\n    ): List<ViewData<U>>? {\n        // It is a bit tricky to get details on the view to be preloaded, since the view doesn't necessarily exist at the time of preload.\n        // This approach looks at currently bound views and tries to get one who's cache key is the same as what we need.\n        // This should mostly work, since RecyclerViews are generally the same type of views shown repeatedly.\n        // If a model is only shown sporadically we may never be able to get data about it with this approach, which we could address in the future.\n\n        val holderMatch = adapter.boundViewHoldersInternal().find {\n            val boundModel = it.model\n            if (boundModel::class == epoxyModel::class) {\n                @Suppress(\"UNCHECKED_CAST\")\n                // We need the view sizes, but viewholders can be bound without actually being laid out on screen yet\n                ViewCompat.isAttachedToWindow(it.itemView) &&\n                    ViewCompat.isLaidOut(it.itemView) &&\n                    cacheKey(preloader, boundModel as T, it.adapterPosition) == cacheKey\n            } else {\n                false\n            }\n        }\n\n        val rootView = holderMatch?.itemView ?: return null\n\n        val boundObject = holderMatch.objectToBindInternal() // Allows usage of view holder models\n\n        val preloadableViews: List<View> = when {\n            preloader.preloadableViewIds.isNotEmpty() -> rootView.findViews(\n                preloader.preloadableViewIds,\n                epoxyModel\n            )\n            rootView is Preloadable -> rootView.viewsToPreload\n            boundObject is Preloadable -> boundObject.viewsToPreload\n            else -> emptyList()\n        }\n\n        if (preloadableViews.isEmpty()) {\n            errorHandler(rootView.context, EpoxyPreloadException(\"No preloadable views were found in ${epoxyModel.javaClass.simpleName}\"))\n        }\n\n        return preloadableViews\n            .flatMap { it.recursePreloadableViews() }\n            .mapNotNull { it.buildData(preloader, epoxyModel) }\n    }\n\n    /** Returns child views with the given view ids. */\n    private fun <T : EpoxyModel<*>> View.findViews(\n        viewIds: List<Int>,\n        epoxyModel: T\n    ): List<View> {\n        return viewIds.mapNotNull { id ->\n            findViewById<View>(id).apply {\n                if (this == null) errorHandler(context, EpoxyPreloadException(\"View with id $id in ${epoxyModel.javaClass.simpleName} could not be found.\"))\n            }\n        }\n    }\n\n    /** If a View with the [Preloadable] interface is used we want to get all of the preloadable views contained in that Preloadable instead. */\n    private fun <T : View> T.recursePreloadableViews(): List<View> {\n        return if (this is Preloadable) {\n            viewsToPreload.flatMap { it.recursePreloadableViews() }\n        } else {\n            listOf(this)\n        }\n    }\n\n    private fun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> View.buildData(\n        preloader: EpoxyModelPreloader<T, U, P>,\n        epoxyModel: T\n    ): ViewData<U>? {\n\n        // Glide's internal size determiner takes view dimensions and subtracts padding to get target size.\n        // TODO: We could support size overrides by allowing the preloader to specify a size override callback\n        val width = width - paddingLeft - paddingRight\n        val height = height - paddingTop - paddingBottom\n\n        if (width <= 0 || height <= 0) {\n            // If no placeholder or aspect ratio is used then the view might be empty before its content loads\n            errorHandler(context, EpoxyPreloadException(\"${this.javaClass.simpleName} in ${epoxyModel.javaClass.simpleName} has zero size. A size must be set to allow preloading.\"))\n            return null\n        }\n\n        return ViewData(\n            id,\n            width,\n            height,\n            preloader.buildViewMetadata(this)\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/preload/PreloaderExtensions.kt",
    "content": "package com.airbnb.epoxy.preload\n\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.utils.isDebuggable\n\n/**\n * Helper to create and add an [EpoxyPreloader] to this RecyclerView.\n *\n * If you are using [com.airbnb.epoxy.EpoxyRecyclerView], prefer[com.airbnb.epoxy.EpoxyRecyclerView.addPreloader]\n * instead.\n *\n * @param maxPreloadDistance How many items to prefetch ahead of the last bound item\n * @param errorHandler Called when the preloader encounters an exception. By default this throws only\n * if the app is not in a debuggle model\n * @param preloader Describes how view content for the EpoxyModel should be preloaded\n * @param requestHolderFactory Should create and return a new [PreloadRequestHolder] each time it is invoked\n */\nfun <T : EpoxyModel<*>, U : ViewMetadata?, P : PreloadRequestHolder> RecyclerView.addEpoxyPreloader(\n    epoxyController: EpoxyController,\n    maxPreloadDistance: Int = 3,\n    errorHandler: PreloadErrorHandler = { context, err -> if (!context.isDebuggable) throw err },\n    preloader: EpoxyModelPreloader<T, U, P>,\n    requestHolderFactory: () -> P\n) {\n    EpoxyPreloader.with(\n        epoxyController,\n        requestHolderFactory,\n        errorHandler,\n        maxPreloadDistance,\n        preloader\n    ).let {\n        addOnScrollListener(it)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/stickyheader/StickyHeaderCallbacks.kt",
    "content": "package com.airbnb.epoxy.stickyheader\n\nimport android.view.View\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * Adds sticky headers capabilities to any [RecyclerView.Adapter]\n * combined with [StickyHeaderLinearLayoutManager].\n */\ninterface StickyHeaderCallbacks {\n\n    /**\n     * Return true if the view at the specified [position] needs to be sticky\n     * else false.\n     */\n    fun isStickyHeader(position: Int): Boolean\n\n    //region Optional callbacks\n\n    /**\n     * Callback to adjusts any necessary properties of the [stickyHeader] view\n     * that is being used as a sticky, eg. elevation.\n     * Default behaviour is no-op.\n     *\n     * [teardownStickyHeaderView] will be called sometime after this method\n     * and before any other calls to this method go through.\n     */\n    fun setupStickyHeaderView(stickyHeader: View) = Unit\n\n    /**\n     * Callback to revert any properties changed in [setupStickyHeaderView].\n     * Default behaviour is no-op.\n     *\n     * Called after [setupStickyHeaderView].\n     */\n    fun teardownStickyHeaderView(stickyHeader: View) = Unit\n\n    //endregion\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/stickyheader/StickyHeaderLinearLayoutManager.kt",
    "content": "package com.airbnb.epoxy.stickyheader\n\nimport android.content.Context\nimport android.graphics.PointF\nimport android.os.Build\nimport android.os.Parcelable\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.ViewTreeObserver\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.BaseEpoxyAdapter\nimport kotlinx.android.parcel.Parcelize\n\n/**\n * Adds sticky headers capabilities to your [RecyclerView.Adapter].\n * The adapter / controller must override [StickyHeaderCallbacks.isStickyHeader] to\n * indicate which items are sticky.\n *\n * Example usage:\n * ```\n *  class StickyHeaderController() : EpoxyController() {\n *      override fun isStickyHeader(position: Int) {\n *          // Write your logic to tell which item is sticky.\n *      }\n *  }\n * ```\n */\nclass StickyHeaderLinearLayoutManager @JvmOverloads constructor(\n    context: Context,\n    orientation: Int = RecyclerView.VERTICAL,\n    reverseLayout: Boolean = false\n) : LinearLayoutManager(context, orientation, reverseLayout) {\n\n    private var adapter: BaseEpoxyAdapter? = null\n\n    // Translation for header\n    private var translationX: Float = 0f\n    private var translationY: Float = 0f\n\n    // Header positions for the currently displayed list and their observer.\n    private val headerPositions = mutableListOf<Int>()\n    private val headerPositionsObserver = HeaderPositionsAdapterDataObserver()\n\n    // Sticky header's ViewHolder and dirty state.\n    private var stickyHeader: View? = null\n    private var stickyHeaderPosition = RecyclerView.NO_POSITION\n\n    // Save / Restore scroll state\n    private var scrollPosition = RecyclerView.NO_POSITION\n    private var scrollOffset = 0\n\n    override fun onAttachedToWindow(recyclerView: RecyclerView) {\n        super.onAttachedToWindow(recyclerView)\n        setAdapter(recyclerView.adapter)\n    }\n\n    override fun onAdapterChanged(oldAdapter: RecyclerView.Adapter<*>?, newAdapter: RecyclerView.Adapter<*>?) {\n        super.onAdapterChanged(oldAdapter, newAdapter)\n        setAdapter(newAdapter)\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    private fun setAdapter(newAdapter: RecyclerView.Adapter<*>?) {\n        adapter?.unregisterAdapterDataObserver(headerPositionsObserver)\n        if (newAdapter is BaseEpoxyAdapter) {\n            adapter = newAdapter\n            adapter?.registerAdapterDataObserver(headerPositionsObserver)\n            headerPositionsObserver.onChanged()\n        } else {\n            adapter = null\n            headerPositions.clear()\n        }\n    }\n\n    override fun onSaveInstanceState(): Parcelable? {\n        return super.onSaveInstanceState()?.let {\n            SavedState(\n                superState = it,\n                scrollPosition = scrollPosition,\n                scrollOffset = scrollOffset\n            )\n        }\n    }\n\n    override fun onRestoreInstanceState(state: Parcelable) {\n        (state as SavedState).let {\n            scrollPosition = it.scrollPosition\n            scrollOffset = it.scrollOffset\n            super.onRestoreInstanceState(it.superState)\n        }\n    }\n\n    override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State): Int {\n        val scrolled = restoreView { super.scrollVerticallyBy(dy, recycler, state) }\n        if (scrolled != 0) {\n            updateStickyHeader(recycler, false)\n        }\n        return scrolled\n    }\n\n    override fun scrollHorizontallyBy(dx: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State): Int {\n        val scrolled = restoreView { super.scrollHorizontallyBy(dx, recycler, state) }\n        if (scrolled != 0) {\n            updateStickyHeader(recycler, false)\n        }\n        return scrolled\n    }\n\n    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {\n        restoreView { super.onLayoutChildren(recycler, state) }\n        if (!state.isPreLayout) {\n            updateStickyHeader(recycler, true)\n        }\n    }\n\n    override fun scrollToPosition(position: Int) = scrollToPositionWithOffset(position, INVALID_OFFSET)\n\n    override fun scrollToPositionWithOffset(position: Int, offset: Int) = scrollToPositionWithOffset(position, offset, true)\n\n    private fun scrollToPositionWithOffset(position: Int, offset: Int, adjustForStickyHeader: Boolean) {\n        // Reset pending scroll.\n        setScrollState(RecyclerView.NO_POSITION, INVALID_OFFSET)\n\n        // Adjusting is disabled.\n        if (!adjustForStickyHeader) {\n            super.scrollToPositionWithOffset(position, offset)\n            return\n        }\n\n        // There is no header above or the position is a header.\n        val headerIndex = findHeaderIndexOrBefore(position)\n        if (headerIndex == -1 || findHeaderIndex(position) != -1) {\n            super.scrollToPositionWithOffset(position, offset)\n            return\n        }\n\n        // The position is right below a header, scroll to the header.\n        if (findHeaderIndex(position - 1) != -1) {\n            super.scrollToPositionWithOffset(position - 1, offset)\n            return\n        }\n\n        // Current sticky header is the same as at the position. Adjust the scroll offset and reset pending scroll.\n        if (stickyHeader != null && headerIndex == findHeaderIndex(stickyHeaderPosition)) {\n            val adjustedOffset = (if (offset != INVALID_OFFSET) offset else 0) + stickyHeader!!.height\n            super.scrollToPositionWithOffset(position, adjustedOffset)\n            return\n        }\n\n        // Remember this position and offset and scroll to it to trigger creating the sticky header.\n        setScrollState(position, offset)\n        super.scrollToPositionWithOffset(position, offset)\n    }\n\n    //region Computation\n    // Mainly [RecyclerView] functionality by removing sticky header from calculations\n\n    override fun computeVerticalScrollExtent(state: RecyclerView.State): Int = restoreView { super.computeVerticalScrollExtent(state) }\n\n    override fun computeVerticalScrollOffset(state: RecyclerView.State): Int = restoreView { super.computeVerticalScrollOffset(state) }\n\n    override fun computeVerticalScrollRange(state: RecyclerView.State): Int = restoreView { super.computeVerticalScrollRange(state) }\n\n    override fun computeHorizontalScrollExtent(state: RecyclerView.State): Int = restoreView { super.computeHorizontalScrollExtent(state) }\n\n    override fun computeHorizontalScrollOffset(state: RecyclerView.State): Int = restoreView { super.computeHorizontalScrollOffset(state) }\n\n    override fun computeHorizontalScrollRange(state: RecyclerView.State): Int = restoreView { super.computeHorizontalScrollRange(state) }\n\n    override fun computeScrollVectorForPosition(targetPosition: Int): PointF? = restoreView { super.computeScrollVectorForPosition(targetPosition) }\n\n    override fun onFocusSearchFailed(\n        focused: View,\n        focusDirection: Int,\n        recycler: RecyclerView.Recycler,\n        state: RecyclerView.State\n    ): View? = restoreView { super.onFocusSearchFailed(focused, focusDirection, recycler, state) }\n\n    /**\n     * Perform the [operation] without the sticky header view by\n     * detaching the view -> performing operation -> detaching the view.\n     */\n    private fun <T> restoreView(operation: () -> T): T {\n        stickyHeader?.let(this::detachView)\n        val result = operation()\n        stickyHeader?.let(this::attachView)\n        return result\n    }\n\n    //endregion\n\n    /**\n     * Offsets the vertical location of the sticky header relative to the its default position.\n     */\n    fun setStickyHeaderTranslationY(translationY: Float) {\n        this.translationY = translationY\n        requestLayout()\n    }\n\n    /**\n     * Offsets the horizontal location of the sticky header relative to the its default position.\n     */\n    fun setStickyHeaderTranslationX(translationX: Float) {\n        this.translationX = translationX\n        requestLayout()\n    }\n\n    /**\n     * Returns true if `view` is the current sticky header.\n     */\n    fun isStickyHeader(view: View): Boolean = view === stickyHeader\n\n    /**\n     * Updates the sticky header state (creation, binding, display), to be called whenever there's a layout or scroll\n     */\n    private fun updateStickyHeader(recycler: RecyclerView.Recycler, layout: Boolean) {\n        val headerCount = headerPositions.size\n        val childCount = childCount\n        if (headerCount > 0 && childCount > 0) {\n            // Find first valid child.\n            var anchorView: View? = null\n            var anchorIndex = -1\n            var anchorPos = -1\n            for (i in 0 until childCount) {\n                val child = getChildAt(i)\n                val params = child!!.layoutParams as RecyclerView.LayoutParams\n                if (isViewValidAnchor(child, params)) {\n                    anchorView = child\n                    anchorIndex = i\n                    anchorPos = params.viewAdapterPosition\n                    break\n                }\n            }\n            if (anchorView != null && anchorPos != -1) {\n                val headerIndex = findHeaderIndexOrBefore(anchorPos)\n                val headerPos = if (headerIndex != -1) headerPositions[headerIndex] else -1\n                val nextHeaderPos = if (headerCount > headerIndex + 1) headerPositions[headerIndex + 1] else -1\n\n                // Show sticky header if:\n                // - There's one to show;\n                // - It's on the edge or it's not the anchor view;\n                // - Isn't followed by another sticky header;\n                if (headerPos != -1 &&\n                    (headerPos != anchorPos || isViewOnBoundary(anchorView)) &&\n                    nextHeaderPos != headerPos + 1\n                ) {\n                    // 1. Ensure existing sticky header, if any, is of correct type.\n                    if (stickyHeader != null && getItemViewType(stickyHeader!!) != adapter?.getItemViewType(headerPos)) {\n                        // A sticky header was shown before but is not of the correct type. Scrap it.\n                        scrapStickyHeader(recycler)\n                    }\n\n                    // 2. Ensure sticky header is created, if absent, or bound, if being laid out or the position changed.\n                    if (stickyHeader == null) createStickyHeader(recycler, headerPos)\n                    // 3. Bind the sticky header\n                    if (layout || getPosition(stickyHeader!!) != headerPos) bindStickyHeader(recycler, stickyHeader!!, headerPos)\n\n                    // 4. Draw the sticky header using translation values which depend on orientation, direction and\n                    // position of the next header view.\n                    stickyHeader?.let {\n                        val nextHeaderView: View? = if (nextHeaderPos != -1) {\n                            val nextHeaderView = getChildAt(anchorIndex + (nextHeaderPos - anchorPos))\n                            // The header view itself is added to the RecyclerView. Discard it if it comes up.\n                            if (nextHeaderView === stickyHeader) null else nextHeaderView\n                        } else null\n                        it.translationX = getX(it, nextHeaderView)\n                        it.translationY = getY(it, nextHeaderView)\n                    }\n                    return\n                }\n            }\n        }\n\n        if (stickyHeader != null) {\n            scrapStickyHeader(recycler)\n        }\n    }\n\n    /**\n     * Creates [RecyclerView.ViewHolder] for [position], including measure / layout, and assigns it to\n     * [stickyHeader].\n     */\n    private fun createStickyHeader(recycler: RecyclerView.Recycler, position: Int) {\n        val stickyHeader = recycler.getViewForPosition(position)\n\n        // Setup sticky header if the adapter requires it.\n        adapter?.setupStickyHeaderView(stickyHeader)\n\n        // Add sticky header as a child view, to be detached / reattached whenever LinearLayoutManager#fill() is called,\n        // which happens on layout and scroll (see overrides).\n        addView(stickyHeader)\n        measureAndLayout(stickyHeader)\n\n        // Ignore sticky header, as it's fully managed by this LayoutManager.\n        ignoreView(stickyHeader)\n\n        this.stickyHeader = stickyHeader\n        this.stickyHeaderPosition = position\n    }\n\n    /**\n     * Binds the [stickyHeader] for the given [position].\n     */\n    private fun bindStickyHeader(recycler: RecyclerView.Recycler, stickyHeader: View, position: Int) {\n        // Bind the sticky header.\n        recycler.bindViewToPosition(stickyHeader, position)\n        stickyHeaderPosition = position\n        measureAndLayout(stickyHeader)\n\n        // If we have a pending scroll wait until the end of layout and scroll again.\n        if (scrollPosition != RecyclerView.NO_POSITION) {\n            stickyHeader.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {\n                override fun onGlobalLayout() {\n                    if (Build.VERSION.SDK_INT < 16) stickyHeader.viewTreeObserver.removeGlobalOnLayoutListener(this)\n                    else stickyHeader.viewTreeObserver.removeOnGlobalLayoutListener(this)\n                    if (scrollPosition != RecyclerView.NO_POSITION) {\n                        scrollToPositionWithOffset(scrollPosition, scrollOffset)\n                        setScrollState(RecyclerView.NO_POSITION, INVALID_OFFSET)\n                    }\n                }\n            })\n        }\n    }\n\n    /**\n     * Measures and lays out [stickyHeader].\n     */\n    private fun measureAndLayout(stickyHeader: View) {\n        measureChildWithMargins(stickyHeader, 0, 0)\n        when (orientation) {\n            VERTICAL -> stickyHeader.layout(paddingLeft, 0, width - paddingRight, stickyHeader.measuredHeight)\n            else -> stickyHeader.layout(0, paddingTop, stickyHeader.measuredWidth, height - paddingBottom)\n        }\n    }\n\n    /**\n     * Returns [stickyHeader] to the [RecyclerView]'s [RecyclerView.RecycledViewPool], assigning it\n     * to `null`.\n     *\n     * @param recycler If passed, the sticky header will be returned to the recycled view pool.\n     */\n    private fun scrapStickyHeader(recycler: RecyclerView.Recycler?) {\n        val stickyHeader = stickyHeader ?: return\n        this.stickyHeader = null\n        this.stickyHeaderPosition = RecyclerView.NO_POSITION\n\n        // Revert translation values.\n        stickyHeader.translationX = 0f\n        stickyHeader.translationY = 0f\n\n        // Teardown holder if the adapter requires it.\n        adapter?.teardownStickyHeaderView(stickyHeader)\n\n        // Stop ignoring sticky header so that it can be recycled.\n        stopIgnoringView(stickyHeader)\n\n        // Remove and recycle sticky header.\n        removeView(stickyHeader)\n        recycler?.recycleView(stickyHeader)\n    }\n\n    /**\n     * Returns true when `view` is a valid anchor, ie. the first view to be valid and visible.\n     */\n    private fun isViewValidAnchor(view: View, params: RecyclerView.LayoutParams): Boolean {\n        return when {\n            !params.isItemRemoved && !params.isViewInvalid -> when (orientation) {\n                VERTICAL -> when {\n                    reverseLayout -> view.top + view.translationY <= height + translationY\n                    else -> view.bottom - view.translationY >= translationY\n                }\n                else -> when {\n                    reverseLayout -> view.left + view.translationX <= width + translationX\n                    else -> view.right - view.translationX >= translationX\n                }\n            }\n            else -> false\n        }\n    }\n\n    /**\n     * Returns true when the `view` is at the edge of the parent [RecyclerView].\n     */\n    private fun isViewOnBoundary(view: View): Boolean {\n        return when (orientation) {\n            VERTICAL -> when {\n                reverseLayout -> view.bottom - view.translationY > height + translationY\n                else -> view.top + view.translationY < translationY\n            }\n            else -> when {\n                reverseLayout -> view.right - view.translationX > width + translationX\n                else -> view.left + view.translationX < translationX\n            }\n        }\n    }\n\n    /**\n     * Returns the position in the Y axis to position the header appropriately, depending on orientation, direction and\n     * [android.R.attr.clipToPadding].\n     */\n    private fun getY(headerView: View, nextHeaderView: View?): Float {\n        when (orientation) {\n            VERTICAL -> {\n                var y = translationY\n                if (reverseLayout) {\n                    y += (height - headerView.height).toFloat()\n                }\n                if (nextHeaderView != null) {\n                    val bottomMargin = (nextHeaderView.layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin ?: 0\n                    val topMargin = (nextHeaderView.layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin ?: 0\n                    y = when {\n                        reverseLayout -> (nextHeaderView.bottom + bottomMargin).toFloat().coerceAtLeast(y)\n                        else -> (nextHeaderView.top - topMargin - headerView.height).toFloat().coerceAtMost(y)\n                    }\n                }\n                return y\n            }\n            else -> return translationY\n        }\n    }\n\n    /**\n     * Returns the position in the X axis to position the header appropriately, depending on orientation, direction and\n     * [android.R.attr.clipToPadding].\n     */\n    private fun getX(headerView: View, nextHeaderView: View?): Float {\n        when (orientation) {\n            HORIZONTAL -> {\n                var x = translationX\n                if (reverseLayout) {\n                    x += (width - headerView.width).toFloat()\n                }\n                if (nextHeaderView != null) {\n                    val leftMargin = (nextHeaderView.layoutParams as? ViewGroup.MarginLayoutParams)?.leftMargin ?: 0\n                    val rightMargin = (nextHeaderView.layoutParams as? ViewGroup.MarginLayoutParams)?.rightMargin ?: 0\n                    x = when {\n                        reverseLayout -> (nextHeaderView.right + rightMargin).toFloat().coerceAtLeast(x)\n                        else -> (nextHeaderView.left - leftMargin - headerView.width).toFloat().coerceAtMost(x)\n                    }\n                }\n                return x\n            }\n            else -> return translationX\n        }\n    }\n\n    /**\n     * Finds the header index of `position` in `headerPositions`.\n     */\n    private fun findHeaderIndex(position: Int): Int {\n        var low = 0\n        var high = headerPositions.size - 1\n        while (low <= high) {\n            val middle = (low + high) / 2\n            when {\n                headerPositions[middle] > position -> high = middle - 1\n                headerPositions[middle] < position -> low = middle + 1\n                else -> return middle\n            }\n        }\n        return -1\n    }\n\n    /**\n     * Finds the header index of `position` or the one before it in `headerPositions`.\n     */\n    private fun findHeaderIndexOrBefore(position: Int): Int {\n        var low = 0\n        var high = headerPositions.size - 1\n        while (low <= high) {\n            val middle = (low + high) / 2\n            when {\n                headerPositions[middle] > position -> high = middle - 1\n                middle < headerPositions.size - 1 && headerPositions[middle + 1] <= position -> low = middle + 1\n                else -> return middle\n            }\n        }\n        return -1\n    }\n\n    /**\n     * Finds the header index of `position` or the one next to it in `headerPositions`.\n     */\n    private fun findHeaderIndexOrNext(position: Int): Int {\n        var low = 0\n        var high = headerPositions.size - 1\n        while (low <= high) {\n            val middle = (low + high) / 2\n            when {\n                middle > 0 && headerPositions[middle - 1] >= position -> high = middle - 1\n                headerPositions[middle] < position -> low = middle + 1\n                else -> return middle\n            }\n        }\n        return -1\n    }\n\n    private fun setScrollState(position: Int, offset: Int) {\n        scrollPosition = position\n        scrollOffset = offset\n    }\n\n    /**\n     * Save / restore existing [RecyclerView] state and\n     * scrolling position and offset.\n     */\n    @Parcelize\n    data class SavedState(\n        val superState: Parcelable,\n        val scrollPosition: Int,\n        val scrollOffset: Int\n    ) : Parcelable\n\n    /**\n     * Handles header positions while adapter changes occur.\n     *\n     * This is used in detriment of [RecyclerView.LayoutManager]'s callbacks to control when they're received.\n     */\n    private inner class HeaderPositionsAdapterDataObserver : RecyclerView.AdapterDataObserver() {\n        override fun onChanged() {\n            // There's no hint at what changed, so go through the adapter.\n            headerPositions.clear()\n            val itemCount = adapter?.itemCount ?: 0\n            for (i in 0 until itemCount) {\n                val isSticky = adapter?.isStickyHeader(i) ?: false\n                if (isSticky) {\n                    headerPositions.add(i)\n                }\n            }\n\n            // Remove sticky header immediately if the entry it represents has been removed. A layout will follow.\n            if (stickyHeader != null && !headerPositions.contains(stickyHeaderPosition)) {\n                scrapStickyHeader(null)\n            }\n        }\n\n        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n            // Shift headers below down.\n            val headerCount = headerPositions.size\n            if (headerCount > 0) {\n                var i = findHeaderIndexOrNext(positionStart)\n                while (i != -1 && i < headerCount) {\n                    headerPositions[i] = headerPositions[i] + itemCount\n                    i++\n                }\n            }\n\n            // Add new headers.\n            for (i in positionStart until positionStart + itemCount) {\n                val isSticky = adapter?.isStickyHeader(i) ?: false\n                if (isSticky) {\n                    val headerIndex = findHeaderIndexOrNext(i)\n                    if (headerIndex != -1) {\n                        headerPositions.add(headerIndex, i)\n                    } else {\n                        headerPositions.add(i)\n                    }\n                }\n            }\n        }\n\n        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {\n            var headerCount = headerPositions.size\n            if (headerCount > 0) {\n                // Remove headers.\n                for (i in positionStart + itemCount - 1 downTo positionStart) {\n                    val index = findHeaderIndex(i)\n                    if (index != -1) {\n                        headerPositions.removeAt(index)\n                        headerCount--\n                    }\n                }\n\n                // Remove sticky header immediately if the entry it represents has been removed. A layout will follow.\n                if (stickyHeader != null && !headerPositions.contains(stickyHeaderPosition)) {\n                    scrapStickyHeader(null)\n                }\n\n                // Shift headers below up.\n                var i = findHeaderIndexOrNext(positionStart + itemCount)\n                while (i != -1 && i < headerCount) {\n                    headerPositions[i] = headerPositions[i] - itemCount\n                    i++\n                }\n            }\n        }\n\n        override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n            // Shift moved headers by toPosition - fromPosition.\n            // Shift headers in-between by -itemCount (reverse if upwards).\n            val headerCount = headerPositions.size\n            if (headerCount > 0) {\n                if (fromPosition < toPosition) {\n                    var i = findHeaderIndexOrNext(fromPosition)\n                    while (i != -1 && i < headerCount) {\n                        val headerPos = headerPositions[i]\n                        if (headerPos >= fromPosition && headerPos < fromPosition + itemCount) {\n                            headerPositions[i] = headerPos - (toPosition - fromPosition)\n                            sortHeaderAtIndex(i)\n                        } else if (headerPos >= fromPosition + itemCount && headerPos <= toPosition) {\n                            headerPositions[i] = headerPos - itemCount\n                            sortHeaderAtIndex(i)\n                        } else {\n                            break\n                        }\n                        i++\n                    }\n                } else {\n                    var i = findHeaderIndexOrNext(toPosition)\n                    loop@ while (i != -1 && i < headerCount) {\n                        val headerPos = headerPositions[i]\n                        when {\n                            headerPos >= fromPosition && headerPos < fromPosition + itemCount -> {\n                                headerPositions[i] = headerPos + (toPosition - fromPosition)\n                                sortHeaderAtIndex(i)\n                            }\n                            headerPos in toPosition..fromPosition -> {\n                                headerPositions[i] = headerPos + itemCount\n                                sortHeaderAtIndex(i)\n                            }\n                            else -> break@loop\n                        }\n                        i++\n                    }\n                }\n            }\n        }\n\n        private fun sortHeaderAtIndex(index: Int) {\n            val headerPos = headerPositions.removeAt(index)\n            val headerIndex = findHeaderIndexOrNext(headerPos)\n            if (headerIndex != -1) {\n                headerPositions.add(headerIndex, headerPos)\n            } else {\n                headerPositions.add(headerPos)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/main/java/com/airbnb/epoxy/utils/utils.kt",
    "content": "package com.airbnb.epoxy.utils\n\nimport android.content.Context\nimport android.content.pm.ApplicationInfo\n\n@PublishedApi\ninternal val Context.isDebuggable: Boolean\n    get() = (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0\n"
  },
  {
    "path": "epoxy-adapter/src/main/res/layout/view_holder_empty_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Space xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"0dp\"\n    android:layout_height=\"0dp\" />\n"
  },
  {
    "path": "epoxy-adapter/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"EpoxyRecyclerView\">\n        <attr name=\"itemSpacing\" format=\"dimension\" />\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "epoxy-adapter/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"view_model_state_saving_id\" type=\"id\" />\n    <item name=\"epoxy_touch_helper_selection_status\" type=\"id\" />\n    <item name=\"epoxy_saved_view_style\" type=\"id\" />\n    <item name=\"epoxy_recycler_view_child_initial_size_id\" type=\"id\" />\n    <item name=\"epoxy_model_group_child_container\" type=\"id\" />\n    <item name=\"epoxy_visibility_tracker\" type=\"id\" />\n</resources>"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/DiffPayloadTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.ArgumentMatcher;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\nimport static com.airbnb.epoxy.DiffPayload.getModelFromPayload;\nimport static junit.framework.Assert.assertEquals;\nimport static junit.framework.Assert.assertNull;\nimport static org.mockito.ArgumentMatchers.argThat;\nimport static org.mockito.ArgumentMatchers.eq;\nimport static org.mockito.Mockito.spy;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\n\n@RunWith(RobolectricTestRunner.class)\npublic class DiffPayloadTest {\n\n  private final List<EpoxyModel<?>> models = new ArrayList<>();\n  private BaseEpoxyAdapter adapter;\n  private AdapterDataObserver observer;\n\n  @Before\n  public void before() {\n    adapter = new BaseEpoxyAdapter() {\n\n      @Override\n      List<EpoxyModel<?>> getCurrentModels() {\n        return models;\n      }\n    };\n\n    observer = spy(new AdapterDataObserver() {\n      @Override\n      public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {\n\n      }\n    });\n\n    adapter.registerAdapterDataObserver(observer);\n  }\n\n  @Test\n  public void payloadsDisabled() {\n    DiffHelper diffHelper = new DiffHelper(adapter, false);\n\n    TestModel firstModel = new TestModel();\n    models.add(firstModel);\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeInserted(0, 1);\n\n    TestModel updatedFirstModel = firstModel.clone().incrementValue();\n    models.clear();\n    models.add(updatedFirstModel);\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeChanged(0, 1, null);\n\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void noPayloadsForNoChanges() {\n    DiffHelper diffHelper = new DiffHelper(adapter, true);\n\n    TestModel firstModel = new TestModel();\n    models.add(firstModel);\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeInserted(0, 1);\n\n    models.clear();\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeRemoved(0, 1);\n\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void singlePayload() {\n    DiffHelper diffHelper = new DiffHelper(adapter, true);\n\n    TestModel firstModel = new TestModel();\n    models.add(firstModel);\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeInserted(0, 1);\n\n    models.clear();\n    TestModel changedFirstModel = firstModel.clone().incrementValue();\n\n    this.models.add(changedFirstModel);\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeChanged(eq(0), eq(1), argThat(new DiffPayloadMatcher(firstModel)));\n\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void batchPayload() {\n    DiffHelper diffHelper = new DiffHelper(adapter, true);\n\n    TestModel firstModel = new TestModel();\n    TestModel secondModel = new TestModel();\n    models.add(firstModel);\n    models.add(secondModel);\n\n    diffHelper.notifyModelChanges();\n\n    TestModel changedFirstModel = firstModel.clone().incrementValue();\n    TestModel changedSecondModel = secondModel.clone().incrementValue();\n    models.clear();\n    models.add(changedFirstModel);\n    models.add(changedSecondModel);\n\n    diffHelper.notifyModelChanges();\n    verify(observer)\n        .onItemRangeChanged(eq(0), eq(2), argThat(new DiffPayloadMatcher(firstModel, secondModel)));\n  }\n\n  @Test\n  public void multiplePayloads() {\n    DiffHelper diffHelper = new DiffHelper(adapter, true);\n\n    TestModel firstModel = new TestModel();\n    TestModel secondModel = new TestModel();\n    TestModel thirdModel = new TestModel();\n    models.add(firstModel);\n    models.add(thirdModel);\n\n    diffHelper.notifyModelChanges();\n\n    TestModel changedFirstModel = firstModel.clone().incrementValue();\n    TestModel changedThirdModel = thirdModel.clone().incrementValue();\n    models.clear();\n    models.add(changedFirstModel);\n    models.add(secondModel);\n    models.add(changedThirdModel);\n\n    diffHelper.notifyModelChanges();\n    verify(observer).onItemRangeChanged(eq(0), eq(1), argThat(new DiffPayloadMatcher(firstModel)));\n    verify(observer).onItemRangeChanged(eq(2), eq(1), argThat(new DiffPayloadMatcher(thirdModel)));\n  }\n\n  @Test\n  public void getSingleModelFromPayload() {\n    TestModel model = new TestModel();\n    List<Object> payloads = payloadsWithChangedModels(model);\n    EpoxyModel<?> modelFromPayload = getModelFromPayload(payloads, model.id());\n\n    assertEquals(model, modelFromPayload);\n  }\n\n  @Test\n  public void returnsNullWhenNoModelFoundInPayload() {\n    TestModel model = new TestModel();\n    List<Object> payloads = payloadsWithChangedModels(model);\n    EpoxyModel<?> modelFromPayload = getModelFromPayload(payloads, model.id() - 1);\n\n    assertNull(modelFromPayload);\n  }\n\n  @Test\n  public void returnsNullForEmptyPayload() {\n    List<Object> payloads = new ArrayList<>();\n    EpoxyModel<?> modelFromPayload = getModelFromPayload(payloads, 2);\n\n    assertNull(modelFromPayload);\n  }\n\n  @Test\n  public void getMultipleModelsFromPayload() {\n    TestModel model1 = new TestModel();\n    TestModel model2 = new TestModel();\n    List<Object> payloads = payloadsWithChangedModels(model1, model2);\n\n    EpoxyModel<?> modelFromPayload1 = getModelFromPayload(payloads, model1.id());\n    EpoxyModel<?> modelFromPayload2 = getModelFromPayload(payloads, model2.id());\n\n    assertEquals(model1, modelFromPayload1);\n    assertEquals(model2, modelFromPayload2);\n  }\n\n  @Test\n  public void getSingleModelsFromMultipleDiffPayloads() {\n    TestModel model1 = new TestModel();\n    DiffPayload diffPayload1 = diffPayloadWithModels(model1);\n\n    TestModel model2 = new TestModel();\n    DiffPayload diffPayload2 = diffPayloadWithModels(model2);\n\n    List<Object> payloads = payloadsWithDiffPayloads(diffPayload1, diffPayload2);\n\n    EpoxyModel<?> modelFromPayload1 = getModelFromPayload(payloads, model1.id());\n    EpoxyModel<?> modelFromPayload2 = getModelFromPayload(payloads, model2.id());\n\n    assertEquals(model1, modelFromPayload1);\n    assertEquals(model2, modelFromPayload2);\n  }\n\n  @Test\n  public void getMultipleModelsFromMultipleDiffPayloads() {\n    TestModel model1Payload1 = new TestModel(1);\n    TestModel model2Payload1 = new TestModel(2);\n    DiffPayload diffPayload1 = diffPayloadWithModels(model1Payload1, model2Payload1);\n\n    TestModel model1Payload2 = new TestModel(3);\n    TestModel model2Payload2 = new TestModel(4);\n    DiffPayload diffPayload2 = diffPayloadWithModels(model1Payload2, model2Payload2);\n\n    List<Object> payloads = payloadsWithDiffPayloads(diffPayload1, diffPayload2);\n\n    EpoxyModel<?> model1FromPayload1 = getModelFromPayload(payloads, model1Payload1.id());\n    EpoxyModel<?> model2FromPayload1 = getModelFromPayload(payloads, model2Payload1.id());\n    EpoxyModel<?> model1FromPayload2 = getModelFromPayload(payloads, model1Payload2.id());\n    EpoxyModel<?> model2FromPayload2 = getModelFromPayload(payloads, model2Payload2.id());\n\n    assertEquals(model1Payload1, model1FromPayload1);\n    assertEquals(model2Payload1, model2FromPayload1);\n    assertEquals(model1Payload2, model1FromPayload2);\n    assertEquals(model2Payload2, model2FromPayload2);\n  }\n\n  static class DiffPayloadMatcher implements ArgumentMatcher<DiffPayload> {\n\n    private final DiffPayload expectedPayload;\n\n    DiffPayloadMatcher(EpoxyModel<?>... changedModels) {\n      List<EpoxyModel<?>> epoxyModels = Arrays.asList(changedModels);\n      expectedPayload = new DiffPayload(epoxyModels);\n    }\n\n    @Override\n    public boolean matches(DiffPayload argument) {\n      return expectedPayload.equalsForTesting(argument);\n    }\n  }\n\n  static DiffPayload diffPayloadWithModels(EpoxyModel<?>... models) {\n    List<EpoxyModel<?>> epoxyModels = Arrays.asList(models);\n    return new DiffPayload(epoxyModels);\n  }\n\n  static List<Object> payloadsWithDiffPayloads(DiffPayload... diffPayloads) {\n    List<DiffPayload> payloads = Arrays.asList(diffPayloads);\n    return new ArrayList<Object>(payloads);\n  }\n\n  static List<Object> payloadsWithChangedModels(EpoxyModel<?>... models) {\n    return payloadsWithDiffPayloads(diffPayloadWithModels(models));\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/DifferCorrectnessTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.google.common.collect.Collections2;\n\nimport junit.framework.Assert;\n\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Random;\n\nimport static com.airbnb.epoxy.ModelTestUtils.addModels;\nimport static com.airbnb.epoxy.ModelTestUtils.changeValues;\nimport static com.airbnb.epoxy.ModelTestUtils.convertToTestModels;\nimport static com.airbnb.epoxy.ModelTestUtils.remove;\nimport static com.airbnb.epoxy.ModelTestUtils.removeModelsAfterPosition;\nimport static junit.framework.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\npublic class DifferCorrectnessTest {\n  private static final boolean SHOW_LOGS = false;\n  /**\n   * If true, will log the time taken on the diff and skip the validation since that takes a long\n   * time for big change sets.\n   */\n  private static final boolean SPEED_RUN = false;\n  private final TestObserver testObserver = new TestObserver(SHOW_LOGS);\n  private final TestAdapter testAdapter = new TestAdapter();\n  private final List<EpoxyModel<?>> models = testAdapter.models;\n  private static long totalDiffMillis = 0;\n  private static long totalDiffOperations = 0;\n  private static long totalDiffs = 0;\n\n  @BeforeClass\n  public static void beforeClass() {\n    totalDiffMillis = 0;\n    totalDiffOperations = 0;\n    totalDiffs = 0;\n  }\n\n  @AfterClass\n  public static void afterClass() {\n    if (SPEED_RUN) {\n      System.out.println(\"Total time for all diffs (ms): \" + totalDiffMillis);\n    } else {\n      System.out.println(\"Total operations for diffs: \" + totalDiffOperations);\n\n      double avgOperations = ((double) totalDiffOperations / totalDiffs);\n      System.out.println(\"Average operations per diff: \" + avgOperations);\n    }\n  }\n\n  @Before\n  public void setUp() {\n    if (!SPEED_RUN) {\n      testAdapter.registerAdapterDataObserver(testObserver);\n    }\n  }\n\n  @Test\n  public void noChange() {\n    diffAndValidateWithOpCount(0);\n  }\n\n  @Test\n  public void simpleUpdate() {\n    addModels(models);\n    diffAndValidate();\n\n    changeValues(models);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void updateStart() {\n    addModels(models);\n    diffAndValidate();\n\n    changeValues(models, 0, models.size() / 2);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void updateMiddle() {\n    addModels(models);\n    diffAndValidate();\n\n    changeValues(models, models.size() / 3, models.size() * 2 / 3);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void updateEnd() {\n    addModels(models);\n    diffAndValidate();\n\n    changeValues(models, models.size() / 2, models.size());\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void shuffle() {\n    // Tries all permutations of item shuffles, with various list sizes. Also randomizes\n    // item values so that the diff must deal with both item updates and movements\n    for (int i = 0; i < 9; i++) {\n      List<EpoxyModel<?>> originalModels = new ArrayList<>();\n      addModels(i, originalModels);\n      int permutationNumber = 0;\n      for (List<EpoxyModel<?>> permutedModels : Collections2.permutations(originalModels)) {\n        permutationNumber++;\n\n        // Resetting to the original models each time, otherwise each subsequent permutation is\n        // only a small difference\n        models.clear();\n        models.addAll(originalModels);\n        diffAndValidate();\n\n        models.clear();\n        models.addAll(permutedModels);\n        changeValues(models);\n\n        log(\"\\n\\n***** Permutation \" + permutationNumber + \" - List Size: \" + i + \" ****** \\n\");\n        log(\"old models:\\n\" + models);\n        log(\"\\n\");\n        log(\"new models:\\n\" + models);\n        log(\"\\n\");\n\n        diffAndValidate();\n      }\n    }\n  }\n\n  @Test\n  public void swapEnds() {\n    addModels(models);\n    diffAndValidate();\n\n    EpoxyModel<?> firstModel = models.remove(0);\n    EpoxyModel<?> lastModel = models.remove(models.size() - 1);\n    models.add(0, lastModel);\n    models.add(firstModel);\n\n    diffAndValidateWithOpCount(2);\n  }\n\n  @Test\n  public void moveFrontToEnd() {\n    addModels(models);\n    diffAndValidate();\n\n    EpoxyModel<?> firstModel = models.remove(0);\n    models.add(firstModel);\n\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void moveEndToFront() {\n    addModels(models);\n    diffAndValidate();\n\n    EpoxyModel<?> lastModel = models.remove(models.size() - 1);\n    models.add(0, lastModel);\n\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void moveEndToFrontAndChangeValues() {\n    addModels(models);\n    diffAndValidate();\n\n    EpoxyModel<?> lastModel = models.remove(models.size() - 1);\n    models.add(0, lastModel);\n    changeValues(models);\n\n    diffAndValidateWithOpCount(2);\n  }\n\n  @Test\n  public void swapHalf() {\n    addModels(models);\n    diffAndValidate();\n\n    List<EpoxyModel<?>> firstHalf = models.subList(0, models.size() / 2);\n    ArrayList<EpoxyModel<?>> firstHalfCopy = new ArrayList<>(firstHalf);\n    firstHalf.clear();\n    models.addAll(firstHalfCopy);\n\n    diffAndValidateWithOpCount(firstHalfCopy.size());\n  }\n\n  @Test\n  public void reverse() {\n    addModels(models);\n    diffAndValidate();\n\n    Collections.reverse(models);\n    diffAndValidate();\n  }\n\n  @Test\n  public void removeAll() {\n    addModels(models);\n    diffAndValidate();\n\n    models.clear();\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void removeEnd() {\n    addModels(models);\n    diffAndValidate();\n\n    int half = models.size() / 2;\n    ModelTestUtils.remove(models, half, half);\n\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void removeMiddle() {\n    addModels(models);\n    diffAndValidate();\n\n    int third = models.size() / 3;\n    ModelTestUtils.remove(models, third, third);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void removeStart() {\n    addModels(models);\n    diffAndValidate();\n\n    int half = models.size() / 2;\n    ModelTestUtils.remove(models, 0, half);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void multipleRemovals() {\n    addModels(models);\n    diffAndValidate();\n\n    int size = models.size();\n    int tenth = size / 10;\n    // Remove a tenth of the models at the end, middle, and start\n    ModelTestUtils.removeModelsAfterPosition(models, size - tenth);\n    ModelTestUtils.remove(models, size / 2, tenth);\n    ModelTestUtils.remove(models, 0, tenth);\n\n    diffAndValidateWithOpCount(3);\n  }\n\n  @Test\n  public void simpleAdd() {\n    addModels(models);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void addToStart() {\n    addModels(models);\n    diffAndValidate();\n\n    addModels(models, 0);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void addToMiddle() {\n    addModels(models);\n    diffAndValidate();\n\n    addModels(models, models.size() / 2);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void addToEnd() {\n    addModels(models);\n    diffAndValidate();\n\n    addModels(models);\n    diffAndValidateWithOpCount(1);\n  }\n\n  @Test\n  public void multipleInsertions() {\n    addModels(models);\n    diffAndValidate();\n\n    addModels(models, 0);\n    addModels(models, models.size() * 2 / 3);\n    addModels(models);\n\n    diffAndValidateWithOpCount(3);\n  }\n\n  @Test\n  public void moveTwoInFrontOfInsertion() {\n    addModels(4, models);\n    diffAndValidate();\n\n    addModels(1, models, 0);\n\n    EpoxyModel<?> lastModel = models.remove(models.size() - 1);\n    models.add(0, lastModel);\n\n    lastModel = models.remove(models.size() - 1);\n    models.add(0, lastModel);\n\n    diffAndValidate();\n  }\n\n  @Test\n  public void randomCombinations() {\n    int maxBatchSize = 3;\n    int maxModelCount = 10;\n    int maxSeed = 100000;\n\n    // This modifies the models list in a random way many times, with different size lists.\n    for (int modelCount = 1; modelCount < maxModelCount; modelCount++) {\n      for (int randomSeed = 0; randomSeed < maxSeed; randomSeed++) {\n        log(\"\\n\\n*** Combination seed \" + randomSeed + \" Model Count: \" + modelCount + \" *** \\n\");\n\n        // We keep the list from the previous loop and keep modifying it. This allows us to test\n        // that state is maintained properly between diffs. We just make sure the list size\n        // says the same by adding or removing if necessary\n        int currentModelCount = models.size();\n        if (currentModelCount < modelCount) {\n          addModels(modelCount - currentModelCount, models);\n        } else if (currentModelCount > modelCount) {\n          removeModelsAfterPosition(models, modelCount);\n        }\n        diffAndValidate();\n\n        modifyModelsRandomly(models, maxBatchSize, new Random(randomSeed));\n        log(\"\\nResulting diff: \\n\");\n        diffAndValidate();\n      }\n    }\n  }\n\n  private void modifyModelsRandomly(List<EpoxyModel<?>> models, int maxBatchSize, Random random) {\n    for (int i = 0; i < models.size(); i++) {\n      int batchSize = randInt(1, maxBatchSize, random);\n      switch (random.nextInt(4)) {\n        case 0:\n          // insert\n          log(\"Inserting \" + batchSize + \" at \" + i);\n          addModels(batchSize, models, i);\n          i += batchSize;\n          break;\n        case 1:\n          // remove\n          int numAvailableToRemove = models.size() - i;\n          batchSize = numAvailableToRemove < batchSize ? numAvailableToRemove : batchSize;\n\n          log(\"Removing \" + batchSize + \" at \" + i);\n          remove(models, i, batchSize);\n          break;\n        case 2:\n          // change\n          int numAvailableToChange = models.size() - i;\n          batchSize = numAvailableToChange < batchSize ? numAvailableToChange : batchSize;\n\n          log(\"Changing \" + batchSize + \" at \" + i);\n          changeValues(models, i, batchSize);\n          break;\n        case 3:\n          // move\n          int targetPosition = random.nextInt(models.size());\n          EpoxyModel<?> currentItem = models.remove(i);\n\n          models.add(targetPosition, currentItem);\n          log(\"Moving \" + i + \" to \" + targetPosition);\n          break;\n        default:\n          throw new IllegalStateException(\"unhandled)\");\n      }\n    }\n  }\n\n  private void diffAndValidate() {\n    diffAndValidateWithOpCount(-1);\n  }\n\n  private void diffAndValidateWithOpCount(int expectedOperationCount) {\n    testObserver.operationCount = 0;\n\n    long start = System.currentTimeMillis();\n    testAdapter.notifyModelsChanged();\n    long end = System.currentTimeMillis();\n    totalDiffMillis += (end - start);\n    totalDiffOperations += testObserver.operationCount;\n    totalDiffs++;\n\n    if (!SPEED_RUN) {\n      if (expectedOperationCount != -1) {\n        assertEquals(\"Operation count is incorrect\", expectedOperationCount,\n            testObserver.operationCount);\n      }\n\n      List<TestModel> newModels = convertToTestModels(models);\n      checkDiff(testObserver.initialModels, testObserver.modelsAfterDiffing, newModels);\n      testObserver.setUpForNextDiff(newModels);\n    }\n  }\n\n  private static int randInt(int min, int max, Random rand) {\n    // nextInt is normally exclusive of the top value,\n    // so add 1 to make it inclusive\n    return rand.nextInt((max - min) + 1) + min;\n  }\n\n  private void log(String text) {\n    log(text, false);\n  }\n\n  private void log(String text, boolean forceShow) {\n    if (forceShow || SHOW_LOGS) {\n      System.out.println(text);\n    }\n  }\n\n  private void checkDiff(List<TestModel> modelsBeforeDiff, List<TestModel> modelsAfterDiff,\n      List<TestModel> actualModels) {\n    assertEquals(\"Diff produces list of different size.\", actualModels.size(),\n        modelsAfterDiff.size());\n\n    for (int i = 0; i < modelsAfterDiff.size(); i++) {\n      TestModel model = modelsAfterDiff.get(i);\n      final TestModel expected = actualModels.get(i);\n\n      if (model == InsertedModel.INSTANCE) {\n        // If the item at this index is new then it shouldn't exist in the original list\n        for (TestModel oldModel : modelsBeforeDiff) {\n          Assert.assertNotSame(\"The inserted model should not exist in the original list\",\n              oldModel.id(), expected.id());\n        }\n      } else {\n        assertEquals(\"Models at same index should have same id\", expected.id(), model.id());\n\n        if (model.updated) {\n          // If there was a change operation then the item hashcodes should be different\n          Assert\n              .assertNotSame(\"Incorrectly updated an item.\", model.hashCode(), expected.hashCode());\n        } else {\n          assertEquals(\"Models should have same hashcode when not updated\",\n              expected.hashCode(), model.hashCode());\n        }\n\n        // Clear state so the model can be used again in another diff\n        model.updated = false;\n      }\n    }\n  }\n}"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/DifferNotifyTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.List;\n\nimport static com.airbnb.epoxy.ModelTestUtils.addModels;\nimport static com.airbnb.epoxy.ModelTestUtils.changeValue;\nimport static com.airbnb.epoxy.ModelTestUtils.remove;\nimport static junit.framework.Assert.assertEquals;\n\n/**\n * Tests that changes to the models via notify calls besides\n * {@link EpoxyAdapter#notifyModelsChanged()}\n * will properly update the model state maintained by the differ.\n */\n@RunWith(RobolectricTestRunner.class)\npublic class DifferNotifyTest {\n  private static final int INITIAL_MODEL_COUNT = 20;\n\n  private static final boolean SHOW_LOGS = false;\n  private final TestObserver testObserver = new TestObserver(SHOW_LOGS);\n  private final TestAdapter adapter = new TestAdapter();\n  private final List<EpoxyModel<?>> models = adapter.models;\n\n  @Test(expected = UnsupportedOperationException.class)\n  public void notifyChange() {\n    adapter.notifyDataSetChanged();\n  }\n\n  @Test\n  public void notifyAddedToEmpty() {\n    addModels(models);\n    adapter.notifyItemRangeInserted(0, models.size());\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyAddedToStart() {\n    addInitialModels();\n\n    addModels(models, 0);\n    adapter.notifyItemRangeInserted(0, models.size() - INITIAL_MODEL_COUNT);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyAddedToEnd() {\n    addInitialModels();\n\n    addModels(models, INITIAL_MODEL_COUNT);\n    adapter.notifyItemRangeInserted(INITIAL_MODEL_COUNT, models.size() - INITIAL_MODEL_COUNT);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyAddedToMiddle() {\n    addInitialModels();\n\n    addModels(models, INITIAL_MODEL_COUNT / 2);\n    adapter.notifyItemRangeInserted(INITIAL_MODEL_COUNT / 2, models.size() - INITIAL_MODEL_COUNT);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyRemoveAll() {\n    addInitialModels();\n\n    models.clear();\n    adapter.notifyItemRangeRemoved(0, INITIAL_MODEL_COUNT);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyRemoveStart() {\n    addInitialModels();\n\n    remove(models, 0, INITIAL_MODEL_COUNT / 2);\n    adapter.notifyItemRangeRemoved(0, INITIAL_MODEL_COUNT / 2);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyRemoveMiddle() {\n    addInitialModels();\n\n    remove(models, INITIAL_MODEL_COUNT / 3, INITIAL_MODEL_COUNT / 3);\n    adapter.notifyItemRangeRemoved(INITIAL_MODEL_COUNT / 3, INITIAL_MODEL_COUNT / 3);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyRemoveEnd() {\n    addInitialModels();\n\n    remove(models, INITIAL_MODEL_COUNT / 2, INITIAL_MODEL_COUNT / 2);\n    adapter.notifyItemRangeRemoved(INITIAL_MODEL_COUNT / 2, INITIAL_MODEL_COUNT / 2);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyFrontMovedToEnd() {\n    addInitialModels();\n\n    EpoxyModel<?> modelToMove = models.remove(0);\n    models.add(modelToMove);\n    adapter.notifyItemMoved(0, INITIAL_MODEL_COUNT - 1);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyEndMovedToFront() {\n    addInitialModels();\n\n    EpoxyModel<?> modelToMove = models.remove(INITIAL_MODEL_COUNT - 1);\n    models.add(0, modelToMove);\n    adapter.notifyItemMoved(INITIAL_MODEL_COUNT - 1, 0);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyMiddleMovedToEnd() {\n    addInitialModels();\n\n    EpoxyModel<?> modelToMove = models.remove(INITIAL_MODEL_COUNT / 2);\n    models.add(modelToMove);\n    adapter.notifyItemMoved(INITIAL_MODEL_COUNT / 2, INITIAL_MODEL_COUNT - 1);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyMiddleMovedToFront() {\n    addInitialModels();\n\n    EpoxyModel<?> modelToMove = models.remove(INITIAL_MODEL_COUNT / 2);\n    models.add(0, modelToMove);\n    adapter.notifyItemMoved(INITIAL_MODEL_COUNT / 2, 0);\n    assertCorrectness();\n  }\n\n  @Test\n  public void notifyValuesUpdated() {\n    addInitialModels();\n\n    int numModelsUpdated = 0;\n    for (int i = INITIAL_MODEL_COUNT / 3; i < INITIAL_MODEL_COUNT * 2 / 3; i++) {\n      changeValue(models.get(i));\n      numModelsUpdated++;\n    }\n\n    adapter.notifyItemRangeChanged(INITIAL_MODEL_COUNT / 3, numModelsUpdated);\n    assertCorrectness();\n  }\n\n  private void addInitialModels() {\n    addModels(INITIAL_MODEL_COUNT, models);\n    adapter.notifyModelsChanged();\n  }\n\n  private void assertCorrectness() {\n    testObserver.operationCount = 0;\n\n    adapter.registerAdapterDataObserver(testObserver);\n    adapter.notifyModelsChanged();\n    adapter.unregisterAdapterDataObserver(testObserver);\n\n    assertEquals(\"Should not have any operations\", 0, testObserver.operationCount);\n  }\n}"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyAdapterTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport junit.framework.Assert;\n\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.ExpectedException;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.MockitoAnnotations;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport static junit.framework.TestCase.assertFalse;\nimport static junit.framework.TestCase.assertTrue;\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(RobolectricTestRunner.class)\npublic class EpoxyAdapterTest {\n\n  @Rule public ExpectedException thrown = ExpectedException.none();\n  private final TestAdapter testAdapter = new TestAdapter();\n  private final TestObserver differObserver = new TestObserver();\n  @Mock RecyclerView.AdapterDataObserver observer;\n\n  @Before\n  public void setup() {\n    MockitoAnnotations.initMocks(this);\n    testAdapter.registerAdapterDataObserver(observer);\n  }\n\n  @Test\n  public void testAddModel() {\n    testAdapter.addModel(new TestModel());\n    verify(observer).onItemRangeInserted(0, 1);\n    assertEquals(1, testAdapter.models.size());\n\n    testAdapter.addModel(new TestModel());\n    verify(observer).onItemRangeInserted(1, 1);\n    assertEquals(2, testAdapter.models.size());\n    checkDifferState();\n  }\n\n  @Test\n  public void testAddModels() {\n    List<TestModel> list = new ArrayList<>();\n    list.add(new TestModel());\n    list.add(new TestModel());\n\n    testAdapter.addModels(list);\n    verify(observer).onItemRangeInserted(0, 2);\n    assertEquals(2, testAdapter.models.size());\n\n    List<TestModel> list2 = new ArrayList<>();\n    list2.add(new TestModel());\n    list2.add(new TestModel());\n    testAdapter.addModels(list2);\n    verify(observer).onItemRangeInserted(2, 2);\n    assertEquals(4, testAdapter.models.size());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testAddModelsVarArgs() {\n    testAdapter.addModels(new TestModel(), new TestModel());\n    verify(observer).onItemRangeInserted(0, 2);\n    assertEquals(2, testAdapter.models.size());\n\n    testAdapter.addModels(new TestModel(), new TestModel());\n    verify(observer).onItemRangeInserted(2, 2);\n    assertEquals(4, testAdapter.models.size());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testNotifyModelChanged() {\n    TestModel testModel = new TestModel();\n    testAdapter.addModels(testModel);\n    testAdapter.notifyModelChanged(testModel);\n    verify(observer).onItemRangeChanged(0, 1, null);\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testNotifyModelChangedWithPayload() {\n    Object payload = new Object();\n    TestModel testModel = new TestModel();\n    testAdapter.addModels(testModel);\n    testAdapter.notifyModelChanged(testModel, payload);\n    verify(observer).onItemRangeChanged(0, 1, payload);\n\n    checkDifferState();\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void testInsertModelBeforeThrowsForInvalidModel() {\n    testAdapter.insertModelBefore(new TestModel(), new TestModel());\n  }\n\n  @Test()\n  public void testInsertModelBefore() {\n    TestModel firstModel = new TestModel();\n    testAdapter.addModels(firstModel);\n    testAdapter.insertModelBefore(new TestModel(), firstModel);\n\n    verify(observer, times(2)).onItemRangeInserted(0, 1);\n    assertEquals(2, testAdapter.models.size());\n    assertEquals(firstModel, testAdapter.models.get(1));\n\n    checkDifferState();\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void testInsertModelAfterThrowsForInvalidModel() {\n    testAdapter.insertModelAfter(new TestModel(), new TestModel());\n  }\n\n  @Test()\n  public void testInsertModelAfter() {\n    TestModel firstModel = new TestModel();\n    testAdapter.addModels(firstModel);\n    testAdapter.insertModelAfter(new TestModel(), firstModel);\n\n    verify(observer).onItemRangeInserted(1, 1);\n    assertEquals(2, testAdapter.models.size());\n    assertEquals(firstModel, testAdapter.models.get(0));\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testRemoveModels() {\n    TestModel testModel = new TestModel();\n    testAdapter.addModels(testModel);\n\n    testAdapter.removeModel(testModel);\n    verify(observer).onItemRangeRemoved(0, 1);\n    assertEquals(0, testAdapter.models.size());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testRemoveAllModels() {\n    for (int i = 0; i < 10; i++) {\n      TestModel model = new TestModel();\n      testAdapter.addModels(model);\n    }\n\n    testAdapter.removeAllModels();\n    verify(observer).onItemRangeRemoved(0, 10);\n    assertEquals(0, testAdapter.models.size());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testRemoveAllAfterModels() {\n    List<TestModel> models = new ArrayList<>();\n    for (int i = 0; i < 10; i++) {\n      TestModel model = new TestModel();\n      models.add(model);\n      testAdapter.addModels(model);\n    }\n\n    testAdapter.removeAllAfterModel(models.get(5));\n    verify(observer).onItemRangeRemoved(6, 4);\n    assertEquals(models.subList(0, 6), testAdapter.models);\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModel() {\n    TestModel testModel = new TestModel();\n    testModel.hide();\n    testAdapter.addModels(testModel);\n\n    testAdapter.showModel(testModel);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    assertTrue(testModel.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModels() {\n    TestModel testModel1 = new TestModel();\n    testModel1.hide();\n\n    TestModel testModel2 = new TestModel();\n    testModel2.hide();\n\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(testAdapter.models);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertTrue(testModel1.isShown());\n    assertTrue(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelsVarArgs() {\n    TestModel testModel1 = new TestModel();\n    testModel1.hide();\n\n    TestModel testModel2 = new TestModel();\n    testModel2.hide();\n\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(testModel1, testModel2);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertTrue(testModel1.isShown());\n    assertTrue(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelsConditionalTrue() {\n    TestModel testModel1 = new TestModel();\n    testModel1.hide();\n\n    TestModel testModel2 = new TestModel();\n    testModel2.hide();\n\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(testAdapter.models, true);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertTrue(testModel1.isShown());\n    assertTrue(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelsVarArgsConditionalTrue() {\n    TestModel testModel1 = new TestModel();\n    testModel1.hide();\n\n    TestModel testModel2 = new TestModel();\n    testModel2.hide();\n\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(true, testModel1, testModel2);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertTrue(testModel1.isShown());\n    assertTrue(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelsConditionalFalse() {\n    TestModel testModel1 = new TestModel();\n    TestModel testModel2 = new TestModel();\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(testAdapter.models, false);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertFalse(testModel1.isShown());\n    assertFalse(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelsVarArgsConditionalFalse() {\n    TestModel testModel1 = new TestModel();\n    TestModel testModel2 = new TestModel();\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.showModels(false, testModel1, testModel2);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertFalse(testModel1.isShown());\n    assertFalse(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testShowModelNoopIfAlreadyShown() {\n    TestModel testModel = new TestModel();\n    testAdapter.addModels(testModel);\n\n    testAdapter.showModel(testModel);\n    verify(observer, times(0)).onItemRangeChanged(0, 1, null);\n    assertTrue(testModel.isShown());\n  }\n\n  @Test\n  public void testHideModel() {\n    TestModel testModel = new TestModel();\n    testAdapter.addModels(testModel);\n\n    testAdapter.hideModel(testModel);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    assertFalse(testModel.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testHideModels() {\n    TestModel testModel1 = new TestModel();\n    TestModel testModel2 = new TestModel();\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.hideModels(testAdapter.models);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertFalse(testModel1.isShown());\n    assertFalse(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testHideModelsVarArgs() {\n    TestModel testModel1 = new TestModel();\n    TestModel testModel2 = new TestModel();\n    testAdapter.addModels(testModel1, testModel2);\n\n    testAdapter.hideModels(testModel1, testModel2);\n    verify(observer).onItemRangeChanged(0, 1, null);\n    verify(observer).onItemRangeChanged(1, 1, null);\n    assertFalse(testModel1.isShown());\n    assertFalse(testModel2.isShown());\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testHideAllAfterModel() {\n    List<TestModel> models = new ArrayList<>();\n    int modelCount = 10;\n    for (int i = 0; i < modelCount; i++) {\n      TestModel model = new TestModel();\n      models.add(model);\n      testAdapter.addModels(model);\n    }\n\n    int hideIndex = 5;\n    testAdapter.hideAllAfterModel(models.get(hideIndex));\n    for (int i = hideIndex + 1; i < modelCount; i++) {\n      verify(observer).onItemRangeChanged(i, 1, null);\n    }\n\n    for (int i = 0; i < modelCount; i++) {\n      assertEquals(i <= hideIndex, models.get(i).isShown());\n    }\n\n    checkDifferState();\n  }\n\n  @Test\n  public void testThrowIfChangeModelIdAfterNotify() {\n    TestModel testModel = new TestModel();\n    testModel.id(100);\n\n    testAdapter.addModel(testModel);\n\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Cannot change a model's id after it has been added to the adapter\");\n    testModel.id(200);\n  }\n\n  @Test\n  public void testAllowSetSameModelIdAfterNotify() {\n    TestModel testModel = new TestModel();\n    testModel.id(100);\n\n    testAdapter.addModel(testModel);\n    testModel.id(100);\n  }\n\n  @Test\n  public void testThrowIfChangeModelIdAfterDiff() {\n    TestModel testModel = new TestModel();\n    testModel.id(100);\n\n    testAdapter.models.add(testModel);\n    testAdapter.notifyModelsChanged();\n\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Cannot change a model's id after it has been added to the adapter\");\n    testModel.id(200);\n  }\n\n  /** Make sure that the differ is in a correct state, and then running it produces no changes. */\n  private void checkDifferState() {\n    differObserver.operationCount = 0;\n\n    testAdapter.registerAdapterDataObserver(differObserver);\n    testAdapter.notifyModelsChanged();\n    testAdapter.unregisterAdapterDataObserver(differObserver);\n\n    Assert.assertEquals(\"Should not have any operations\", 0, differObserver.operationCount);\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyControllerTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.EpoxyController.Interceptor;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\nimport static junit.framework.Assert.assertFalse;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\n\n@RunWith(RobolectricTestRunner.class)\npublic class EpoxyControllerTest {\n\n  List<EpoxyModel<?>> savedModels;\n  boolean noExceptionsDuringBasicBuildModels = true;\n\n  @Test\n  public void basicBuildModels() {\n    AdapterDataObserver observer = mock(AdapterDataObserver.class);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n\n      @Override\n      protected void onExceptionSwallowed(RuntimeException exception) {\n        noExceptionsDuringBasicBuildModels = false;\n      }\n    };\n\n    controller.getAdapter().registerAdapterDataObserver(observer);\n    controller.requestModelBuild();\n\n    assertTrue(noExceptionsDuringBasicBuildModels);\n    assertEquals(1, controller.getAdapter().getItemCount());\n    verify(observer).onItemRangeInserted(0, 1);\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test(expected = IllegalEpoxyUsage.class)\n  public void addingSameModelTwiceThrows() {\n    final CarouselModel_ model = new CarouselModel_();\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void filterDuplicates() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .id(1)\n            .addTo(this);\n\n        new TestModel()\n            .id(1)\n            .addTo(this);\n      }\n    };\n\n    controller.setFilterDuplicates(true);\n    controller.requestModelBuild();\n\n    assertEquals(1, controller.getAdapter().getItemCount());\n  }\n\n  boolean exceptionSwallowed;\n\n  @Test\n  public void exceptionSwallowedWhenDuplicateFiltered() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .id(1)\n            .addTo(this);\n\n        new TestModel()\n            .id(1)\n            .addTo(this);\n      }\n\n      @Override\n      protected void onExceptionSwallowed(RuntimeException exception) {\n        exceptionSwallowed = true;\n      }\n    };\n\n    controller.setFilterDuplicates(true);\n    controller.requestModelBuild();\n\n    assertTrue(exceptionSwallowed);\n  }\n\n  boolean interceptorCalled;\n\n  @Test\n  public void interceptorRunsAfterBuildModels() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        assertEquals(1, models.size());\n        interceptorCalled = true;\n      }\n    });\n\n    controller.requestModelBuild();\n\n    assertTrue(interceptorCalled);\n    assertEquals(1, controller.getAdapter().getItemCount());\n  }\n\n  @Test\n  public void interceptorCanAddModels() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        models.add(new TestModel());\n      }\n    });\n\n    controller.requestModelBuild();\n\n    assertEquals(2, controller.getAdapter().getItemCount());\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void savedModelsCannotBeAddedToLater() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        savedModels = models;\n      }\n    });\n\n    controller.requestModelBuild();\n\n    savedModels.add(new TestModel());\n  }\n\n  @Test\n  public void interceptorCanModifyModels() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        TestModel model = ((TestModel) models.get(0));\n        model.value(model.value() + 1);\n      }\n    });\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void interceptorsRunInOrderAdded() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        assertEquals(1, models.size());\n        models.add(new TestModel());\n      }\n    });\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        assertEquals(2, models.size());\n        models.add(new TestModel());\n      }\n    });\n\n    controller.requestModelBuild();\n\n    assertEquals(3, controller.getAdapter().getItemCount());\n  }\n\n  @Test\n  public void moveModel() {\n    AdapterDataObserver observer = mock(AdapterDataObserver.class);\n    final List<TestModel> testModels = new ArrayList<>();\n    testModels.add(new TestModel(1));\n    testModels.add(new TestModel(2));\n    testModels.add(new TestModel(3));\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(testModels);\n      }\n    };\n\n    EpoxyControllerAdapter adapter = controller.getAdapter();\n    adapter.registerAdapterDataObserver(observer);\n    controller.requestModelBuild();\n\n    verify(observer).onItemRangeInserted(0, 3);\n\n    testModels.add(0, testModels.remove(1));\n\n    controller.moveModel(1, 0);\n    verify(observer).onItemRangeMoved(1, 0, 1);\n\n    assertEquals(testModels, adapter.getCurrentModels());\n\n    controller.requestModelBuild();\n    assertEquals(testModels, adapter.getCurrentModels());\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void moveModelOtherWay() {\n    AdapterDataObserver observer = mock(AdapterDataObserver.class);\n    final List<TestModel> testModels = new ArrayList<>();\n    testModels.add(new TestModel(1));\n    testModels.add(new TestModel(2));\n    testModels.add(new TestModel(3));\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(testModels);\n      }\n    };\n\n    EpoxyControllerAdapter adapter = controller.getAdapter();\n    adapter.registerAdapterDataObserver(observer);\n    controller.requestModelBuild();\n\n    verify(observer).onItemRangeInserted(0, 3);\n\n    testModels.add(2, testModels.remove(1));\n\n    controller.moveModel(1, 2);\n    verify(observer).onItemRangeMoved(1, 2, 1);\n\n    assertEquals(testModels, adapter.getCurrentModels());\n\n    controller.requestModelBuild();\n    assertEquals(testModels, adapter.getCurrentModels());\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void multipleMoves() {\n    AdapterDataObserver observer = mock(AdapterDataObserver.class);\n    final List<TestModel> testModels = new ArrayList<>();\n    testModels.add(new TestModel(1));\n    testModels.add(new TestModel(2));\n    testModels.add(new TestModel(3));\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(testModels);\n      }\n    };\n\n    EpoxyControllerAdapter adapter = controller.getAdapter();\n    adapter.registerAdapterDataObserver(observer);\n    controller.requestModelBuild();\n\n    testModels.add(0, testModels.remove(1));\n    controller.moveModel(1, 0);\n    verify(observer).onItemRangeMoved(1, 0, 1);\n\n    testModels.add(2, testModels.remove(1));\n    controller.moveModel(1, 2);\n    verify(observer).onItemRangeMoved(1, 2, 1);\n\n    assertEquals(testModels, adapter.getCurrentModels());\n    controller.requestModelBuild();\n    assertEquals(testModels, adapter.getCurrentModels());\n  }\n\n  @Test\n  public void testDuplicateFilteringDisabledByDefault() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n\n      }\n    };\n\n    assertFalse(controller.isDuplicateFilteringEnabled());\n  }\n\n  @Test\n  public void testDuplicateFilteringCanBeToggled() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n\n      }\n    };\n\n    assertFalse(controller.isDuplicateFilteringEnabled());\n\n    controller.setFilterDuplicates(true);\n    assertTrue(controller.isDuplicateFilteringEnabled());\n\n    controller.setFilterDuplicates(false);\n    assertFalse(controller.isDuplicateFilteringEnabled());\n  }\n\n  @Test\n  public void testGlobalDuplicateFilteringDefault() {\n    EpoxyController.setGlobalDuplicateFilteringDefault(true);\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n\n      }\n    };\n\n    assertTrue(controller.isDuplicateFilteringEnabled());\n\n    controller.setFilterDuplicates(false);\n    assertFalse(controller.isDuplicateFilteringEnabled());\n\n    controller.setFilterDuplicates(true);\n    assertTrue(controller.isDuplicateFilteringEnabled());\n\n    // Reset static field for future tests\n    EpoxyController.setGlobalDuplicateFilteringDefault(false);\n  }\n\n  @Test\n  public void testDebugLoggingCanBeToggled() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n\n      }\n    };\n\n    assertFalse(controller.isDebugLoggingEnabled());\n\n    controller.setDebugLoggingEnabled(true);\n    assertTrue(controller.isDebugLoggingEnabled());\n\n    controller.setDebugLoggingEnabled(false);\n    assertFalse(controller.isDebugLoggingEnabled());\n  }\n\n  @Test\n  public void testGlobalDebugLoggingDefault() {\n    EpoxyController.setGlobalDebugLoggingEnabled(true);\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n\n      }\n    };\n\n    assertTrue(controller.isDebugLoggingEnabled());\n\n    controller.setDebugLoggingEnabled(false);\n    assertFalse(controller.isDebugLoggingEnabled());\n\n    controller.setDebugLoggingEnabled(true);\n    assertTrue(controller.isDebugLoggingEnabled());\n\n    // Reset static field for future tests\n    EpoxyController.setGlobalDebugLoggingEnabled(false);\n  }\n\n  @Test\n  public void testModelBuildListener() {\n    OnModelBuildFinishedListener observer = mock(OnModelBuildFinishedListener.class);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addModelBuildListener(observer);\n    controller.requestModelBuild();\n\n    verify(observer).onModelBuildFinished(any(DiffResult.class));\n  }\n\n  @Test\n  public void testRemoveModelBuildListener() {\n    OnModelBuildFinishedListener observer = mock(OnModelBuildFinishedListener.class);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    controller.addModelBuildListener(observer);\n    controller.removeModelBuildListener(observer);\n    controller.requestModelBuild();\n\n    verify(observer, never()).onModelBuildFinished(any(DiffResult.class));\n  }\n\n  @Test\n  public void testDiffInProgress() {\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        assertTrue(this.hasPendingModelBuild());\n\n        new TestModel()\n            .addTo(this);\n      }\n    };\n\n    assertFalse(controller.hasPendingModelBuild());\n    controller.requestModelBuild();\n    // Model build should happen synchronously in tests\n    assertFalse(controller.hasPendingModelBuild());\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyModelGroupTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.ViewStub\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport android.widget.Space\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.test.core.app.ApplicationProvider\nimport org.junit.After\nimport org.junit.Assert.assertEquals\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.ParameterizedRobolectricTestRunner\nimport org.robolectric.annotation.Config\nimport org.robolectric.annotation.LooperMode\n\n@Config(sdk = [21])\n@RunWith(ParameterizedRobolectricTestRunner::class)\n@LooperMode(LooperMode.Mode.LEGACY)\nclass EpoxyModelGroupTest(val useViewStubs: Boolean) {\n\n    private lateinit var recyclerView: RecyclerView\n    private var topLevelHolder: EpoxyViewHolder? = null\n\n    private val modelGroupHolder get() = topLevelHolder!!.objectToBind() as ModelGroupHolder\n\n    @Before\n    fun init() {\n        recyclerView = RecyclerView(ApplicationProvider.getApplicationContext())\n        topLevelHolder?.unbind()\n        topLevelHolder = null\n    }\n\n    @After\n    fun unbind() {\n        topLevelHolder!!.unbind()\n        assertEquals(0, modelGroupHolder.viewHolders.size)\n    }\n\n    private fun bind(modelGroup: EpoxyModelGroup, previousGroup: EpoxyModelGroup? = null) {\n        if (topLevelHolder == null) {\n            topLevelHolder =\n                EpoxyViewHolder(recyclerView, modelGroup.buildView(recyclerView), false)\n        }\n        topLevelHolder!!.bind(modelGroup, previousGroup, emptyList(), 0)\n    }\n\n    private fun assertModelsBound(modelGroup: EpoxyModelGroup) {\n        assertEquals(modelGroupHolder.viewHolders.size, modelGroup.models.size)\n        modelGroupHolder.viewHolders.forEachIndexed { index, viewHolder ->\n            assertEquals(\"Model at index $index\", viewHolder.model, modelGroup.models[index])\n        }\n    }\n\n    @Test\n    fun bindLinearLayout() {\n        createFrameLayoutGroup(3).let {\n            bind(it)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun bind_Unbind_Rebind_LinearLayoutWithLessModels() {\n        val firstGroup = createFrameLayoutGroup(3)\n        bind(firstGroup)\n        unbind()\n\n        createSpaceGroup(2).let {\n            bind(it, firstGroup)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun bind_Unbind_Rebind_LinearLayoutWithMoreModels() {\n        val firstGroup = createFrameLayoutGroup(3)\n        bind(firstGroup)\n        unbind()\n        createSpaceGroup(4).let {\n            bind(it, firstGroup)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun rebind_LinearLayoutWithSameViewTypes() {\n        val firstGroup = createFrameLayoutGroup(3)\n        bind(firstGroup)\n        createFrameLayoutGroup(4).let {\n            bind(it, firstGroup)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun rebind_LinearLayoutWithMoreModels() {\n        val firstGroup = createFrameLayoutGroup(3)\n        bind(firstGroup)\n        createSpaceGroup(4).let {\n            bind(it, firstGroup)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun rebind_LinearLayoutWithLessModels() {\n        val firstGroup = createFrameLayoutGroup(3)\n        bind(firstGroup)\n        createSpaceGroup(2).let {\n            bind(it, firstGroup)\n            assertModelsBound(it)\n        }\n    }\n\n    @Test\n    fun viewholdersAreRecycled() {\n        bind(createFrameLayoutGroup(3))\n        val firstHolders = modelGroupHolder.viewHolders.toSet()\n\n        unbind()\n\n        bind(createFrameLayoutGroup(3))\n        val secondHolders = modelGroupHolder.viewHolders.toSet()\n\n        assertEquals(firstHolders, secondHolders)\n    }\n\n    @Test\n    fun viewStubsOutOfOrder() {\n        val models = (0 until 4).map { NestedModelFrameLayout().id(it) }\n\n        val modelGroup = object : EpoxyModelGroup(0, models) {\n            public override fun buildView(parent: ViewGroup): View {\n                return LinearLayout(parent.context).apply {\n\n                    addView(\n                        ViewStub(parent.context).apply {\n                            inflatedId = 0\n                        }\n                    )\n\n                    addView(\n                        LinearLayout(parent.context).apply {\n                            addView(\n                                ViewStub(parent.context).apply {\n                                    inflatedId = 1\n                                }\n                            )\n\n                            addView(Space(parent.context))\n\n                            addView(\n                                ViewStub(parent.context).apply {\n                                    inflatedId = 2\n                                }\n                            )\n                        }\n                    )\n\n                    addView(\n                        ViewStub(parent.context).apply {\n                            inflatedId = 3\n                        }\n                    )\n                }\n            }\n        }\n\n        bind(modelGroup)\n\n        modelGroupHolder.viewHolders.forEachIndexed { index, viewholder ->\n\n            val view = viewholder.itemView\n            assertEquals(index, view.id)\n\n            val indexInsideParentView = (view.parent as ViewGroup).indexOfChild(view)\n            when (view.id) {\n                0 -> assertEquals(0, indexInsideParentView)\n                1 -> assertEquals(0, indexInsideParentView)\n                2 -> assertEquals(2, indexInsideParentView)\n                3 -> assertEquals(2, indexInsideParentView)\n            }\n        }\n    }\n\n    private fun createFrameLayoutGroup(modelCount: Int): EpoxyModelGroup {\n        val models = (0 until modelCount).map { NestedModelFrameLayout().id(it) }\n        return if (useViewStubs) ViewStubsGroupModel(models) else LinerLayoutGroupModel(models)\n    }\n\n    private fun createSpaceGroup(modelCount: Int): EpoxyModelGroup {\n        val models = (0 until modelCount).map { NestedModelSpace().id(it) }\n        return if (useViewStubs) ViewStubsGroupModel(models) else LinerLayoutGroupModel(models)\n    }\n\n    companion object {\n        @JvmStatic\n        @ParameterizedRobolectricTestRunner.Parameters(name = \"Use viewstubs: {0}\")\n        fun useViewStubsParameters() = listOf(\n            arrayOf(true),\n            arrayOf(false)\n        )\n    }\n}\n\nprivate class LinerLayoutGroupModel(models: List<EpoxyModel<*>>) : EpoxyModelGroup(0, models) {\n    public override fun buildView(parent: ViewGroup): View {\n        return LinearLayout(parent.context)\n    }\n}\n\nprivate class ViewStubsGroupModel(models: List<EpoxyModel<*>>) : EpoxyModelGroup(0, models) {\n    public override fun buildView(parent: ViewGroup): View {\n        fun LinearLayout.addStubLayer(): LinearLayout {\n            addView(ViewStub(parent.context))\n\n            LinearLayout(parent.context).let {\n                addView(it)\n                return it\n            }\n        }\n\n        return (0 until models.size).fold(LinearLayout(parent.context)) { linearLayout, _ -> linearLayout.addStubLayer() }\n    }\n}\n\nprivate class NestedModelFrameLayout : EpoxyModelWithView<FrameLayout>() {\n    override fun buildView(parent: ViewGroup): FrameLayout {\n        return FrameLayout(parent.context)\n    }\n}\n\nprivate class NestedModelSpace : EpoxyModelWithView<Space>() {\n    override fun buildView(parent: ViewGroup): Space {\n        return Space(parent.context)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyRecyclerViewTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport androidx.test.core.app.ApplicationProvider\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\nimport org.robolectric.annotation.LooperMode\n\n@Config(sdk = [21])\n@RunWith(RobolectricTestRunner::class)\n@LooperMode(LooperMode.Mode.LEGACY)\nclass EpoxyRecyclerViewTest {\n\n    private class TestModel : EpoxyModel<View>() {\n        override fun getDefaultLayout(): Int = 0\n    }\n\n    @Test\n    fun withModels() {\n        val epoxyRecyclerView = EpoxyRecyclerView(ApplicationProvider.getApplicationContext())\n\n        var modelsToBuild = 1\n        epoxyRecyclerView.withModels {\n            repeat(modelsToBuild) {\n                TestModel().id(it).addTo(this)\n            }\n        }\n\n        // Initial call should build models\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n\n        // Can rebuild models with requestModelBuild\n        modelsToBuild = 4\n        epoxyRecyclerView.requestModelBuild()\n        assertEquals(4, epoxyRecyclerView.adapter?.itemCount)\n\n        // Setting a different callback should override previous one\n        epoxyRecyclerView.withModels {\n            TestModel().id(1).addTo(this)\n        }\n\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n\n        // requestModelBuild uses new callback\n        epoxyRecyclerView.requestModelBuild()\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n    }\n\n    @Test\n    fun buildModelsWith() {\n        val epoxyRecyclerView = EpoxyRecyclerView(ApplicationProvider.getApplicationContext())\n\n        var modelsToBuild = 1\n        epoxyRecyclerView.buildModelsWith(object : EpoxyRecyclerView.ModelBuilderCallback {\n            override fun buildModels(controller: EpoxyController) {\n                repeat(modelsToBuild) {\n                    TestModel().id(it).addTo(controller)\n                }\n            }\n        })\n\n        // Initial call should build models\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n\n        // Can rebuild models with requestModelBuild\n        modelsToBuild = 4\n        epoxyRecyclerView.requestModelBuild()\n        assertEquals(4, epoxyRecyclerView.adapter?.itemCount)\n\n        // Setting a different callback should override previous one\n        epoxyRecyclerView.buildModelsWith(object : EpoxyRecyclerView.ModelBuilderCallback {\n            override fun buildModels(controller: EpoxyController) {\n                TestModel().id(1).addTo(controller)\n            }\n        })\n\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n\n        // requestModelBuild uses new callback\n        epoxyRecyclerView.requestModelBuild()\n        assertEquals(1, epoxyRecyclerView.adapter?.itemCount)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyViewHolderTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.view.ViewParent\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.mockito.Mock\nimport org.mockito.Mockito.inOrder\nimport org.mockito.MockitoAnnotations\nimport org.robolectric.RobolectricTestRunner\n\n@RunWith(RobolectricTestRunner::class)\nclass EpoxyViewHolderTest {\n    private lateinit var epoxyViewHolder: EpoxyViewHolder\n\n    @Mock\n    lateinit var viewParent: ViewParent\n\n    @Mock\n    lateinit var view: View\n\n    @Mock\n    lateinit var model: TestModel\n\n    @Mock\n    lateinit var previousModel: TestModel\n\n    @Before\n    fun setup() {\n        MockitoAnnotations.openMocks(this)\n        epoxyViewHolder = EpoxyViewHolder(viewParent, view, false)\n    }\n\n    @Test\n    fun testBindCallsPreBindWithPrevious() {\n        epoxyViewHolder.bind(model, previousModel, emptyList(), 0)\n        val inOrder = inOrder(model)\n        inOrder.verify(model).preBind(view, previousModel)\n        inOrder.verify(model).bind(view, previousModel)\n    }\n\n    @Test\n    fun testBindCallsPreBind() {\n        epoxyViewHolder.bind(model, null, emptyList(), 0)\n        val inOrder = inOrder(model)\n        inOrder.verify(model).preBind(view, null)\n        inOrder.verify(model).bind(view)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyVisibilityTrackerNestedTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.util.Log\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.EpoxyVisibilityTracker.Companion.DEBUG_LOG\nimport com.airbnb.epoxy.VisibilityState.INVISIBLE\nimport com.airbnb.epoxy.VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\nimport com.airbnb.epoxy.VisibilityState.PARTIAL_IMPRESSION_VISIBLE\nimport com.airbnb.epoxy.VisibilityState.VISIBLE\nimport org.junit.After\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.Robolectric\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\nimport org.robolectric.shadows.ShadowLog\n\nprivate typealias AssertHelper = EpoxyVisibilityTrackerTest.AssertHelper\nprivate typealias TrackerTestModel = EpoxyVisibilityTrackerTest.TrackerTestModel\n\n/**\n * This class test the EpoxyVisibilityTracker by using a RecyclerView that scroll vertically. The\n * view port height is provided by Robolectric.\n *\n * We are just controlling how many items are displayed with VISIBLE_ITEMS constant.\n *\n * In order to control the RecyclerView's height we are using theses qualifiers:\n * - `mdpi` for density factor 1\n * - `h831dp` where : 831 = 56 (ToolBar) + 775 (RecyclerView)\n */\n@Config(sdk = [21], qualifiers = \"h831dp-mdpi\")\n@RunWith(RobolectricTestRunner::class)\nclass EpoxyVisibilityTrackerNestedTest {\n    companion object {\n        private const val TAG = \"EpoxyVisibilityTrackerNestedTest\"\n        /**\n         * Visibility ratio for horizontal carousel\n         */\n        private const val ONE_AND_HALF_VISIBLE = 1.5f\n\n        private fun log(message: String) {\n            if (DEBUG_LOG) {\n                Log.d(TAG, message)\n            }\n        }\n\n        private var ids = 0\n    }\n\n    private lateinit var activity: Activity\n    private lateinit var recyclerView: RecyclerView\n    private lateinit var epoxyController: TypedEpoxyController<List<List<AssertHelper>>>\n    private var viewportHeight: Int = 0\n    private var itemHeight: Int = 0\n    private var itemWidth: Int = 0\n    private val epoxyVisibilityTracker = EpoxyVisibilityTracker()\n    /**\n     * For nested visibility what we want is to scroll the parent recycler view and see of the\n     * nested recycler view get visibility updates.\n     */\n    @Test\n    fun testScrollBy() {\n        if (true) return\n        val testHelper = buildTestData(\n            10,\n            10,\n            EpoxyVisibilityTrackerTest.TWO_AND_HALF_VISIBLE,\n            ONE_AND_HALF_VISIBLE\n        )\n        // At this point we have the 1st and 2nd item visible\n        // The 3rd item is 50% visible\n        // Now scroll to the end\n        for (to in 0..testHelper.size) {\n            var str = \"visible : \"\n            testHelper.forEachIndexed { y, helpers ->\n                if (helpers[0].visible) {\n                    str = \"$str[$y ${helpers[0].visibleHeight}] \"\n                }\n            }\n            log(str)\n            (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(to, 10)\n        }\n        // Verify visibility event. We will do a pass on every items and assert visiblity for the\n        // first and second items in the carousel.\n        testHelper.forEachIndexed { y, helpers ->\n            helpers.forEachIndexed { x, helper ->\n\n                when {\n\n                    // From 0 to 6 nothing should be visible but they should have been visible\n                    // during the scroll\n\n                    y < 7 && x == 0 -> {\n                        with(helper) {\n                            assert(\n                                visibleHeight = 0,\n                                percentVisibleHeight = 0.0f,\n                                percentVisibleWidth = 0.0f,\n                                visible = false,\n                                partialImpression = false,\n                                fullImpression = false,\n                                visitedStates = EpoxyVisibilityTrackerTest.ALL_STATES\n                            )\n                        }\n                    }\n                    y < 7 && x == 1 -> {\n                        with(helper) {\n                            assert(\n                                visibleHeight = 0,\n                                percentVisibleHeight = 0.0f,\n                                percentVisibleWidth = 0.0f,\n                                visible = false,\n                                partialImpression = false,\n                                fullImpression = false,\n                                visitedStates = intArrayOf(\n                                    VISIBLE,\n                                    PARTIAL_IMPRESSION_VISIBLE,\n                                    PARTIAL_IMPRESSION_INVISIBLE,\n                                    INVISIBLE\n                                )\n                            )\n                        }\n                    }\n\n                    // Items at row 7 should be partially visible\n\n                    y == 7 && x == 0 -> {\n                        with(helper) {\n                            assert(\n                                visibleHeight = 50,\n                                visibleWidth = 100,\n                                visible = true,\n                                partialImpression = true,\n                                fullImpression = false,\n                                visitedStates = intArrayOf(\n                                    VISIBLE,\n                                    PARTIAL_IMPRESSION_VISIBLE\n                                )\n                            )\n                        }\n                    }\n                    y == 7 && x == 1 -> {\n                        with(helper) {\n                            assert(\n                                visibleHeight = 50,\n                                visibleWidth = 50,\n                                visible = true,\n                                partialImpression = true,\n                                fullImpression = false,\n                                visitedStates = intArrayOf(\n                                    VISIBLE,\n                                    PARTIAL_IMPRESSION_VISIBLE\n                                )\n                            )\n                        }\n                    }\n\n                    // Items at row 8 and 9 should be entirely visible (on height)\n\n                    y > 7 && x == 0 -> {\n                        with(helper) {\n                            assert(\n                                percentVisibleHeight = 100.0f,\n                                percentVisibleWidth = 100.0f,\n                                visible = false,\n                                partialImpression = true,\n                                fullImpression = true,\n                                visitedStates = EpoxyVisibilityTrackerTest.ALL_STATES\n                            )\n                        }\n                    }\n                    y > 7 && x == 1 -> {\n                        with(helper) {\n                            assert(\n                                percentVisibleHeight = 100.0f,\n                                percentVisibleWidth = 50.0f,\n                                visible = false,\n                                partialImpression = true,\n                                fullImpression = false,\n                                visitedStates = intArrayOf(\n                                    VISIBLE,\n                                    PARTIAL_IMPRESSION_VISIBLE\n                                )\n                            )\n                        }\n                    }\n                }\n                log(\"$y : $x valid\")\n            }\n        }\n    }\n\n    /**\n     * Attach an EpoxyController on the RecyclerView\n     */\n    private fun buildTestData(\n        verticalSampleSize: Int,\n        horizontalSampleSize: Int,\n        verticalVisibleItemsOnScreen: Float,\n        horizontalVisibleItemsOnScreen: Float\n    ): List<List<AssertHelper>> {\n        // Compute individual item height\n        itemHeight = (recyclerView.measuredHeight / verticalVisibleItemsOnScreen).toInt()\n        itemWidth = (recyclerView.measuredWidth / horizontalVisibleItemsOnScreen).toInt()\n        // Build a test sample of sampleSize items\n        val helpers = mutableListOf<List<AssertHelper>>().apply {\n            for (i in 0 until verticalSampleSize) {\n                add(\n                    mutableListOf<AssertHelper>().apply {\n                        for (j in 0 until horizontalSampleSize) {\n                            add(AssertHelper(ids++))\n                        }\n                    }\n                )\n            }\n        }\n        log(helpers.ids())\n        epoxyController.setData(helpers)\n        return helpers\n    }\n\n    /**\n     * Setup a RecyclerView and compute item height so we have 3.5 items on screen\n     */\n    @Before\n    fun setup() {\n        Robolectric.setupActivity(Activity::class.java).apply {\n            setContentView(\n                EpoxyRecyclerView(this).apply {\n                    epoxyVisibilityTracker.attach(this)\n                    recyclerView = this\n                    // Plug an epoxy controller\n                    epoxyController = object : TypedEpoxyController<List<List<AssertHelper>>>() {\n                        override fun buildModels(data: List<List<AssertHelper>>?) {\n                            data?.forEachIndexed { index, helpers ->\n                                val models = mutableListOf<EpoxyModel<*>>()\n                                helpers.forEach { helper ->\n                                    models.add(\n                                        TrackerTestModel(\n                                            itemPosition = index,\n                                            itemHeight = itemHeight,\n                                            itemWidth = itemWidth,\n                                            helper = helper\n                                        ).id(\"$index-${helper.id}\")\n                                    )\n                                }\n                                add(\n                                    CarouselModel_()\n                                        .id(index)\n                                        .paddingDp(0)\n                                        .models(models)\n                                )\n                            }\n                        }\n                    }\n                    recyclerView.adapter = epoxyController.adapter\n                }\n            )\n            viewportHeight = recyclerView.measuredHeight\n            activity = this\n        }\n        ShadowLog.stream = System.out\n    }\n\n    @After\n    fun tearDown() {\n        epoxyVisibilityTracker.detach(recyclerView)\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/EpoxyVisibilityTrackerTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.util.Log\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.TextView\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.EpoxyVisibilityTracker.Companion.DEBUG_LOG\nimport com.airbnb.epoxy.VisibilityState.FOCUSED_VISIBLE\nimport com.airbnb.epoxy.VisibilityState.FULL_IMPRESSION_VISIBLE\nimport com.airbnb.epoxy.VisibilityState.INVISIBLE\nimport com.airbnb.epoxy.VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\nimport com.airbnb.epoxy.VisibilityState.PARTIAL_IMPRESSION_VISIBLE\nimport com.airbnb.epoxy.VisibilityState.UNFOCUSED_VISIBLE\nimport com.airbnb.epoxy.VisibilityState.VISIBLE\nimport org.junit.After\nimport org.junit.Assert\nimport org.junit.Before\nimport org.junit.Ignore\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.Robolectric\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\nimport org.robolectric.annotation.LooperMode\nimport org.robolectric.shadows.ShadowLog\n\n/**\n * This class test the EpoxyVisibilityTracker by using a RecyclerView that scroll vertically. The\n * view port height is provided by Robolectric.\n *\n * We are just controlling how many items are displayed with VISIBLE_ITEMS constant.\n *\n * In order to control the RecyclerView's height we are using theses qualifiers:\n * - `mdpi` for density factor 1\n * - `h831dp` where : 831 = 56 (ToolBar) + 775 (RecyclerView)\n */\n@Config(sdk = [21], qualifiers = \"h831dp-mdpi\")\n@RunWith(RobolectricTestRunner::class)\n@LooperMode(LooperMode.Mode.LEGACY)\nclass EpoxyVisibilityTrackerTest {\n\n    companion object {\n\n        private const val TAG = \"EpoxyVisibilityTrackerTest\"\n\n        /**\n         * Make sure the RecyclerView display:\n         * - 2 full items\n         * - 50% of the next item.\n         */\n        internal const val TWO_AND_HALF_VISIBLE = 2.5f\n\n        internal val ALL_STATES = intArrayOf(\n            VISIBLE,\n            INVISIBLE,\n            FOCUSED_VISIBLE,\n            UNFOCUSED_VISIBLE,\n            PARTIAL_IMPRESSION_VISIBLE,\n            PARTIAL_IMPRESSION_INVISIBLE,\n            FULL_IMPRESSION_VISIBLE\n        )\n\n        /**\n         * Tolerance used for robolectric ui assertions when comparing data in pixels\n         */\n        private const val TOLERANCE_PIXELS = 1\n\n        private fun log(message: String) {\n            if (DEBUG_LOG) {\n                Log.d(TAG, message)\n            }\n        }\n\n        private var ids = 0\n    }\n\n    private lateinit var activity: Activity\n    private lateinit var recyclerView: RecyclerView\n    private lateinit var epoxyController: TypedEpoxyController<List<AssertHelper>>\n    private var viewportHeight: Int = 0\n    private var itemHeight: Int = 0\n\n    private val epoxyVisibilityTracker = EpoxyVisibilityTracker()\n\n    /**\n     * Test visibility events when loading a recycler view\n     */\n    @Test\n    fun testDataAttachedToRecyclerView() {\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n\n        val firstHalfVisibleItem = 2\n        val firstInvisibleItem = firstHalfVisibleItem + 1\n\n        // Verify visibility event\n        testHelper.forEachIndexed { index, helper ->\n            when {\n\n                index in 0 until firstHalfVisibleItem -> {\n\n                    // Item expected to be 100% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight,\n                            percentVisibleHeight = 100.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = true,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                FOCUSED_VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index == firstHalfVisibleItem -> {\n\n                    // Item expected to be 50% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight / 2,\n                            percentVisibleHeight = 50.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index in firstInvisibleItem..9 -> {\n\n                    // Item expected not to be visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf()\n                        )\n                    }\n                }\n\n                else -> throw IllegalStateException(\"index should not be bigger than 9\")\n            }\n\n            log(\"$index valid\")\n        }\n    }\n\n    /**\n     * Test visibility events when loading a recycler view but without any partial visible states\n     */\n    @Test\n    fun testDataAttachedToRecyclerView_WithoutPartial() {\n        // disable partial visibility states\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = null\n\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n\n        val firstHalfVisibleItem = 2\n        val firstInvisibleItem = firstHalfVisibleItem + 1\n\n        // Verify visibility event\n        testHelper.forEachIndexed { index, helper ->\n            when {\n\n                index in 0 until firstHalfVisibleItem -> {\n\n                    // Item expected to be 100% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight,\n                            percentVisibleHeight = 100.0f,\n                            visible = true,\n                            partialImpression = false,\n                            fullImpression = true,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                FOCUSED_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index == firstHalfVisibleItem -> {\n\n                    // Item expected to be 50% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight / 2,\n                            percentVisibleHeight = 50.0f,\n                            visible = true,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index in firstInvisibleItem..9 -> {\n\n                    // Item expected not to be visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf()\n                        )\n                    }\n                }\n\n                else -> throw IllegalStateException(\"index should not be bigger than 9\")\n            }\n\n            log(\"$index valid\")\n        }\n    }\n\n    /**\n     * Test partial visibility events when loading a recycler view\n     */\n    @Test\n    fun testDataAttachedToRecyclerView_OneElementJustBelowPartialThreshold() {\n        val testHelper = buildTestData(2, 1.49f)\n\n        val firstAlmostPartiallyVisibleItem = 1\n\n        // Verify visibility event\n        testHelper.forEachIndexed { index, helper ->\n            when {\n\n                index in 0 until firstAlmostPartiallyVisibleItem -> {\n\n                    // Item expected to be 100% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight,\n                            percentVisibleHeight = 100.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = true,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                FOCUSED_VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index == firstAlmostPartiallyVisibleItem -> {\n\n                    // Item expected to be 49% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = (itemHeight * 0.49).toInt(),\n                            percentVisibleHeight = 49.0f,\n                            visible = true,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                else -> throw IllegalStateException(\"index should not be bigger than 9\")\n            }\n\n            log(\"$index valid\")\n        }\n    }\n\n    /**\n     * Test visibility events when adding data to a recycler view (item inserted from adapter)\n     */\n    @Test\n    fun testInsertData() {\n\n        // Build initial list\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n        val secondFullyVisibleItemBeforeInsert = testHelper[1]\n        val halfVisibleItemBeforeInsert = testHelper[2]\n\n        // Insert in visible area\n        val position = 1\n        val inserted = insertAt(testHelper, position)\n\n        with(testHelper[position]) {\n            assert(\n                id = inserted.id,\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(secondFullyVisibleItemBeforeInsert) {\n            assert(\n                visibleHeight = itemHeight / 2,\n                percentVisibleHeight = 50.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    UNFOCUSED_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(halfVisibleItemBeforeInsert) {\n            assert(\n                visibleHeight = 0,\n                percentVisibleHeight = 0.0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    PARTIAL_IMPRESSION_INVISIBLE,\n                    INVISIBLE\n                )\n            )\n        }\n    }\n\n    /**\n     * Test visibility events when removing data from a recycler view (item removed from adapter)\n     */\n    @Test\n    @Ignore // test started failing with robolectric upgrade :/\n    fun testDeleteData() {\n\n        // Build initial list\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n        val halfVisibleItemBeforeDelete = testHelper[2]\n        val firstNonVisibleItemBeforeDelete = testHelper[3]\n\n        // Delete from visible area\n        val position = 1\n        val deleted = deleteAt(testHelper, position)\n\n        with(deleted) {\n            assert(\n                visibleHeight = 0,\n                percentVisibleHeight = 0.0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = ALL_STATES\n            )\n        }\n\n        with(halfVisibleItemBeforeDelete) {\n            assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(firstNonVisibleItemBeforeDelete) {\n            assert(\n                visibleHeight = itemHeight / 2,\n                percentVisibleHeight = 50.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    /**\n     * Test visibility events when moving data from a recycler view (item moved within adapter)\n     *\n     * This test is a bit more complex so we will add more data in the sample size so we can test\n     * moving a range.\n     *\n     * What is done :\n     * - build a test adapter with a larger sample : 100 items (20 items per screen)\n     * - make sure first item is in focus\n     * - move the 2 first items to the position 14\n     * - make sure recycler view is still displaying the focused item (scrolled to ~14)\n     * - make sure the 3rd item is not visible\n     */\n    @Test\n    fun testMoveDataUp() {\n\n        val llm = recyclerView.layoutManager as LinearLayoutManager\n\n        // Build initial list\n        val itemsPerScreen = 20\n        val testHelper = buildTestData(100, itemsPerScreen.toFloat())\n\n        // First item should be visible and in focus\n        Assert.assertEquals(0, llm.findFirstCompletelyVisibleItemPosition())\n        Assert.assertEquals(20, llm.findLastVisibleItemPosition())\n\n        // Move the 2 first items to the position 24\n        val moved1 = testHelper[0]\n        val moved2 = testHelper[1]\n        val item3 = testHelper[2]\n        moveTwoItems(testHelper, from = 0, to = 14)\n\n        // Because we moved the item in focus (item 0) and the layout manager will maintain the\n        // focus the recycler view should scroll to end\n\n        Assert.assertEquals(14, llm.findFirstVisibleItemPosition())\n        Assert.assertEquals(\n            14 + itemsPerScreen - 1,\n            llm.findLastCompletelyVisibleItemPosition()\n        )\n\n        with(moved1) {\n            // moved 1 should still be in focus so still 100% visible\n            assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(moved2) {\n            // moved 2 should still be in focus so still 100% visible\n            assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(item3) {\n            // the item after moved2 should not be visible now\n            assert(\n                visibleHeight = 0,\n                percentVisibleHeight = 0.0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = ALL_STATES\n            )\n        }\n    }\n\n    /**\n     * Same kind of test than `testMoveDataUp()` but we move from 24 to 0.\n     */\n    @Test\n    fun testMoveDataDown() {\n\n        val llm = recyclerView.layoutManager as LinearLayoutManager\n\n        // Build initial list\n        val itemsPerScreen = 20\n        val testHelper = buildTestData(100, itemsPerScreen.toFloat())\n\n        // Scroll to item 24, sharp\n        (recyclerView.layoutManager as LinearLayoutManager)\n            .scrollToPositionWithOffset(24, 0)\n\n        // First item should be visible and in focus\n        Assert.assertEquals(24, llm.findFirstCompletelyVisibleItemPosition())\n        Assert.assertEquals(44, llm.findLastVisibleItemPosition())\n\n        // Move the 2 first items to the position 24\n        val moved1 = testHelper[24]\n        val moved2 = testHelper[25]\n        val item3 = testHelper[26]\n        moveTwoItems(testHelper, from = 24, to = 0)\n\n        // Because we moved the item in focus (item 0) and the layout manager will maintain the\n        // focus the recycler view should scroll to end\n\n        Assert.assertEquals(0, llm.findFirstVisibleItemPosition())\n        Assert.assertEquals(19, llm.findLastCompletelyVisibleItemPosition())\n\n        with(moved1) {\n            // moved 1 should still be in focus so still 100% visible\n            assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(moved2) {\n            // moved 2 should still be in focus so still 100% visible\n            assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100.0f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VISIBLE,\n                    FOCUSED_VISIBLE,\n                    PARTIAL_IMPRESSION_VISIBLE,\n                    FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n\n        with(item3) {\n            // the item after moved2 should not be visible now\n            assert(\n                visibleHeight = 0,\n                percentVisibleHeight = 0.0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = ALL_STATES\n            )\n        }\n    }\n\n    /**\n     * Test visibility events using scrollToPosition on the recycler view\n     */\n    @Test\n    fun testScrollBy() {\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n\n        // At this point we have the 1st and 2nd item visible\n        // The 3rd item is 50% visible\n\n        // Now scroll to the end\n        for (to in 0..testHelper.size) {\n            (recyclerView.layoutManager as LinearLayoutManager)\n                .scrollToPositionWithOffset(to, 10)\n        }\n\n        // Verify visibility event\n        testHelper.forEachIndexed { index, helper ->\n            when {\n\n                index in 0..1 -> {\n\n                    // Item expected not to be visible but should have visited all states\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = ALL_STATES\n                        )\n                    }\n                }\n\n                index == 2 -> {\n\n                    // This item was only half visible, it was never fully visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = ALL_STATES\n                        )\n                    }\n                }\n\n                index in 3..6 -> {\n\n                    // Theses items were never rendered\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = ALL_STATES\n                        )\n                    }\n                }\n\n                index == 7 -> {\n\n                    // Item expected to be 50% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight / 2,\n                            percentVisibleHeight = 50.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                FOCUSED_VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE,\n                                UNFOCUSED_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index in 8..9 -> {\n\n                    // Item expected to be 100% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight,\n                            percentVisibleHeight = 100.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = true,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                FOCUSED_VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n                else -> throw IllegalStateException(\"index should not be bigger than 9\")\n            }\n\n            log(\"$index valid\")\n        }\n    }\n\n    /**\n     * Test visibility events using scrollToPosition on the recycler view\n     */\n    @Test\n    fun testScrollToPosition() {\n        val testHelper = buildTestData(10, TWO_AND_HALF_VISIBLE)\n\n        // At this point we have the 1st and 2nd item visible\n        // The 3rd item is 50% visible\n\n        // Now scroll to the end\n        val scrollToPosition = testHelper.size - 1\n        log(\"scrollToPosition=$scrollToPosition\")\n        recyclerView.scrollToPosition(scrollToPosition)\n\n        // Verify visibility event\n        testHelper.forEachIndexed { index, helper ->\n            when {\n\n                index in 0..1 -> {\n\n                    // Item expected not to be visible but should have visited all states\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FOCUSED_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE,\n                                UNFOCUSED_VISIBLE,\n                                PARTIAL_IMPRESSION_INVISIBLE,\n                                INVISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index == 2 -> {\n\n                    // This item was only half visible, it was never fully visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                PARTIAL_IMPRESSION_INVISIBLE,\n                                INVISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index in 3..6 -> {\n\n                    // Theses items were never rendered\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = 0,\n                            percentVisibleHeight = 0.0f,\n                            visible = false,\n                            partialImpression = false,\n                            fullImpression = false,\n                            visitedStates = intArrayOf()\n                        )\n                    }\n                }\n\n                index == 7 -> {\n\n                    // Item expected to be 50% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight / 2,\n                            percentVisibleHeight = 50.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = false,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n\n                index in 8..9 -> {\n\n                    // Item expected to be 100% visible\n\n                    with(helper) {\n                        assert(\n                            visibleHeight = itemHeight,\n                            percentVisibleHeight = 100.0f,\n                            visible = true,\n                            partialImpression = true,\n                            fullImpression = true,\n                            visitedStates = intArrayOf(\n                                VISIBLE,\n                                PARTIAL_IMPRESSION_VISIBLE,\n                                FOCUSED_VISIBLE,\n                                FULL_IMPRESSION_VISIBLE\n                            )\n                        )\n                    }\n                }\n                else -> throw IllegalStateException(\"index should not be bigger than 9\")\n            }\n\n            log(\"$index valid\")\n        }\n    }\n\n    /**\n     * Attach an EpoxyController on the RecyclerView\n     */\n    private fun buildTestData(\n        sampleSize: Int,\n        visibleItemsOnScreen: Float\n    ): MutableList<AssertHelper> {\n        // Compute individual item height\n        itemHeight = (recyclerView.measuredHeight / visibleItemsOnScreen).toInt()\n        // Build a test sample of sampleSize items\n        val helpers = mutableListOf<AssertHelper>().apply {\n            for (index in 0 until sampleSize) add(AssertHelper(ids++))\n        }\n        log(helpers.ids())\n        epoxyController.setData(helpers)\n        return helpers\n    }\n\n    private fun insertAt(helpers: MutableList<AssertHelper>, position: Int): AssertHelper {\n        log(\"insert at $position\")\n        val helper = AssertHelper(ids++)\n        helpers.add(position, helper)\n        log(helpers.ids())\n        epoxyController.setData(helpers)\n        return helper\n    }\n\n    private fun deleteAt(helpers: MutableList<AssertHelper>, position: Int): AssertHelper {\n        log(\"delete at $position\")\n        val helper = helpers.removeAt(position)\n        log(helpers.ids())\n        epoxyController.setData(helpers)\n        return helper\n    }\n\n    private fun moveTwoItems(helpers: MutableList<AssertHelper>, from: Int, to: Int) {\n        log(\"move at $from -> $to\")\n        val helper1 = helpers.removeAt(from)\n        val helper2 = helpers.removeAt(from)\n        helpers.add(to, helper2)\n        helpers.add(to, helper1)\n        log(helpers.ids())\n        epoxyController.setData(helpers)\n    }\n\n    /**\n     * Setup a RecyclerView and compute item height so we have 3.5 items on screen\n     */\n    @Before\n    fun setup() {\n        Robolectric.setupActivity(Activity::class.java).apply {\n            setContentView(\n                EpoxyRecyclerView(this).apply {\n                    epoxyVisibilityTracker.partialImpressionThresholdPercentage = 50\n                    epoxyVisibilityTracker.attach(this)\n                    recyclerView = this\n                    // Plug an epoxy controller\n                    epoxyController = object : TypedEpoxyController<List<AssertHelper>>() {\n                        override fun buildModels(data: List<AssertHelper>?) {\n                            data?.forEachIndexed { index, helper ->\n                                add(\n                                    TrackerTestModel(\n                                        itemPosition = index,\n                                        itemHeight = itemHeight,\n                                        helper = helper\n                                    ).id(helper.id)\n                                )\n                            }\n                        }\n                    }\n                    recyclerView.adapter = epoxyController.adapter\n                }\n            )\n            viewportHeight = recyclerView.measuredHeight\n            activity = this\n        }\n        ShadowLog.stream = System.out\n    }\n\n    @After\n    fun tearDown() {\n        epoxyVisibilityTracker.detach(recyclerView)\n    }\n\n    /**\n     * Epoxy model used for test\n     */\n    internal class TrackerTestModel(\n        private val itemPosition: Int,\n        private val itemHeight: Int,\n        private val itemWidth: Int = FrameLayout.LayoutParams.MATCH_PARENT,\n        private val helper: AssertHelper\n    ) : EpoxyModelWithView<View>() {\n\n        override fun buildView(parent: ViewGroup): View {\n            log(\"buildView[$itemPosition](id=${helper.id})\")\n            return TextView(parent.context).apply {\n                // Force height\n                layoutParams = RecyclerView.LayoutParams(itemWidth, itemHeight)\n            }\n        }\n\n        override fun onVisibilityChanged(ph: Float, pw: Float, vh: Int, vw: Int, view: View) {\n            helper.percentVisibleHeight = ph\n            helper.percentVisibleWidth = pw\n            helper.visibleHeight = vh\n            helper.visibleWidth = vw\n            if (ph.toInt() != 100) helper.fullImpression = false\n        }\n\n        override fun onVisibilityStateChanged(state: Int, view: View) {\n            log(\"onVisibilityStateChanged[$itemPosition](id=${helper.id})=${state.description()}\")\n            helper.visitedStates.add(state)\n            when (state) {\n                VISIBLE, INVISIBLE ->\n                    helper.visible = state == VISIBLE\n                FOCUSED_VISIBLE, UNFOCUSED_VISIBLE ->\n                    helper.focused = state == FOCUSED_VISIBLE\n                PARTIAL_IMPRESSION_VISIBLE, PARTIAL_IMPRESSION_INVISIBLE ->\n                    helper.partialImpression = state == PARTIAL_IMPRESSION_VISIBLE\n                FULL_IMPRESSION_VISIBLE ->\n                    helper.fullImpression = state == FULL_IMPRESSION_VISIBLE\n            }\n        }\n    }\n\n    /**\n     * Helper for asserting visibility\n     */\n    internal class AssertHelper(val id: Int) {\n\n        var created = false\n        var visitedStates = mutableListOf<Int>()\n        var visibleHeight = 0\n        var visibleWidth = 0\n        var percentVisibleHeight = 0.0f\n        var percentVisibleWidth = 0.0f\n        var visible = false\n        var focused = false\n        var partialImpression = false\n        var fullImpression = false\n\n        fun assert(\n            id: Int? = null,\n            visibleHeight: Int? = null,\n            visibleWidth: Int? = null,\n            percentVisibleHeight: Float? = null,\n            percentVisibleWidth: Float? = null,\n            visible: Boolean? = null,\n            partialImpression: Boolean? = null,\n            fullImpression: Boolean? = null,\n            visitedStates: IntArray? = null\n        ) {\n            id?.let {\n                Assert.assertEquals(\n                    \"id expected $it got ${this.id}\",\n                    it,\n                    this.id\n                )\n            }\n            visibleHeight?.let {\n                // assert using tolerance, see TOLERANCE_PIXELS\n                log(\"assert visibleHeight, got $it, expected ${this.visibleHeight}\")\n                Assert.assertTrue(\n                    \"visibleHeight expected ${it}px got ${this.visibleHeight}px\",\n                    Math.abs(it - this.visibleHeight) <= TOLERANCE_PIXELS\n                )\n            }\n            visibleWidth?.let {\n                // assert using tolerance, see TOLERANCE_PIXELS\n                log(\"assert visibleWidth, got $it, expected ${this.visibleWidth}\")\n                Assert.assertTrue(\n                    \"visibleWidth expected ${it}px got ${this.visibleWidth}px\",\n                    Math.abs(it - this.visibleWidth) <= TOLERANCE_PIXELS\n                )\n            }\n            percentVisibleHeight?.let {\n                Assert.assertEquals(\n                    \"percentVisibleHeight expected $it got ${this.percentVisibleHeight}\",\n                    it,\n                    this.percentVisibleHeight,\n                    0.05f\n                )\n            }\n            percentVisibleWidth?.let {\n                Assert.assertEquals(\n                    \"percentVisibleWidth expected $it got ${this.percentVisibleWidth}\",\n                    it,\n                    this.percentVisibleWidth,\n                    0.05f\n                )\n            }\n            visible?.let {\n                Assert.assertEquals(\n                    \"visible expected $it got ${this.visible}\",\n                    it,\n                    this.visible\n                )\n            }\n            partialImpression?.let {\n                Assert.assertEquals(\n                    \"partialImpression expected $it got ${this.partialImpression}\",\n                    it,\n                    this.partialImpression\n                )\n            }\n            fullImpression?.let {\n                Assert.assertEquals(\n                    \"fullImpression expected $it got ${this.fullImpression}\",\n                    it,\n                    this.fullImpression\n                )\n            }\n            visitedStates?.let { assertVisited(it) }\n        }\n\n        private fun assertVisited(states: IntArray) {\n            val expectedStates = mutableListOf<Int>()\n            states.forEach { expectedStates.add(it) }\n            for (state in expectedStates) {\n                if (!visitedStates.contains(state)) {\n                    Assert.fail(\n                        \"Expected visited ${expectedStates.description()}, \" +\n                            \"got ${visitedStates.description()}\"\n                    )\n                }\n            }\n            for (state in ALL_STATES) {\n                if (!expectedStates.contains(state) && visitedStates.contains(state)) {\n                    Assert.fail(\n                        \"Expected ${state.description()} not visited, \" +\n                            \"got ${visitedStates.description()}\"\n                    )\n                }\n            }\n        }\n    }\n}\n\ninternal fun <E> List<E>.ids(): String {\n    val builder = StringBuilder(\"[\")\n    forEachIndexed { index, element ->\n        (element as? EpoxyVisibilityTrackerTest.AssertHelper)?.let {\n            builder.append(it.id)\n        }\n        builder.append(if (index < size - 1) \",\" else \"]\")\n    }\n    return builder.toString()\n}\n\n/**\n * List of Int to VisibilityState constant names.\n */\nprivate fun List<Int>.description(): String {\n    val builder = StringBuilder(\"[\")\n    forEachIndexed { index, state ->\n        builder.append(state.description())\n        builder.append(if (index < size - 1) \",\" else \"\")\n    }\n    builder.append(\"]\")\n    return builder.toString()\n}\n\n/**\n * Int to VisibilityState constant name.\n */\nprivate fun Int.description(): String {\n    return when (this) {\n        VISIBLE -> \"VISIBLE\"\n        INVISIBLE -> \"INVISIBLE\"\n        FOCUSED_VISIBLE -> \"FOCUSED_VISIBLE\"\n        UNFOCUSED_VISIBLE -> \"UNFOCUSED_VISIBLE\"\n        PARTIAL_IMPRESSION_VISIBLE -> \"PARTIAL_IMPRESSION_VISIBLE\"\n        PARTIAL_IMPRESSION_INVISIBLE -> \"PARTIAL_IMPRESSION_INVISIBLE\"\n        FULL_IMPRESSION_VISIBLE -> \"FULL_IMPRESSION_VISIBLE\"\n        else -> throw IllegalStateException(\"Please declare new state here\")\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/InsertedModel.java",
    "content": "package com.airbnb.epoxy;\n\nclass InsertedModel extends TestModel {\n  static final InsertedModel INSTANCE = new InsertedModel();\n\n  @Override\n  public int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/ModelListTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport static junit.framework.TestCase.assertFalse;\nimport static junit.framework.TestCase.assertTrue;\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\n\n@RunWith(RobolectricTestRunner.class)\npublic class ModelListTest {\n\n  private final ModelList.ModelListObserver observer = mock(ModelList.ModelListObserver.class);\n  private final ModelList modelList = new ModelList();\n\n  @Before\n  public void before() {\n    modelList.add(new TestModel());\n    modelList.add(new TestModel());\n    modelList.add(new TestModel());\n\n    modelList.setObserver(observer);\n  }\n\n  @Test\n  public void testSet() {\n    modelList.set(0, new TestModel());\n\n    verify(observer).onItemRangeRemoved(0, 1);\n    verify(observer).onItemRangeInserted(0, 1);\n  }\n\n  @Test\n  public void testSetSameIdDoesntNotify() {\n    EpoxyModel<?> newModelWithSameId = new TestModel();\n    newModelWithSameId.id(modelList.get(0).id());\n\n    modelList.set(0, newModelWithSameId);\n    verifyNoMoreInteractions(observer);\n    assertEquals(newModelWithSameId, modelList.get(0));\n  }\n\n  @Test\n  public void testAdd() {\n    modelList.add(new TestModel());\n    modelList.add(new TestModel());\n\n    verify(observer).onItemRangeInserted(3, 1);\n    verify(observer).onItemRangeInserted(4, 1);\n  }\n\n  @Test\n  public void testAddAtIndex() {\n    modelList.add(0, new TestModel());\n    modelList.add(2, new TestModel());\n\n    verify(observer).onItemRangeInserted(0, 1);\n    verify(observer).onItemRangeInserted(2, 1);\n  }\n\n  @Test\n  public void testAddAll() {\n    List<EpoxyModel<?>> newModels = new ArrayList<>();\n    newModels.add(new TestModel());\n    newModels.add(new TestModel());\n\n    modelList.addAll(newModels);\n    verify(observer).onItemRangeInserted(3, 2);\n  }\n\n  @Test\n  public void testAddAllAtIndex() {\n    List<EpoxyModel<?>> newModels = new ArrayList<>();\n    newModels.add(new TestModel());\n    newModels.add(new TestModel());\n\n    modelList.addAll(0, newModels);\n    verify(observer).onItemRangeInserted(0, 2);\n  }\n\n  @Test\n  public void testRemoveIndex() {\n    EpoxyModel<?> removedModel = modelList.remove(0);\n    assertFalse(modelList.contains(removedModel));\n\n    assertEquals(2, modelList.size());\n    verify(observer).onItemRangeRemoved(0, 1);\n  }\n\n  @Test\n  public void testRemoveObject() {\n    EpoxyModel<?> model = modelList.get(0);\n    boolean model1Removed = modelList.remove(model);\n\n    assertEquals(2, modelList.size());\n    assertTrue(model1Removed);\n    assertFalse(modelList.contains(model));\n\n    verify(observer).onItemRangeRemoved(0, 1);\n  }\n\n  @Test\n  public void testRemoveObjectNotAdded() {\n    boolean removed = modelList.remove(new TestModel());\n    assertFalse(removed);\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void testClear() {\n    modelList.clear();\n    verify(observer).onItemRangeRemoved(0, 3);\n  }\n\n  @Test\n  public void testClearWhenAlreadyEmpty() {\n    modelList.clear();\n    modelList.clear();\n    verify(observer).onItemRangeRemoved(0, 3);\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void testSublistClear() {\n    modelList.subList(0, 2).clear();\n    verify(observer).onItemRangeRemoved(0, 2);\n  }\n\n  @Test\n  public void testNoClearWhenEmpty() {\n    modelList.clear();\n    modelList.clear();\n    verify(observer).onItemRangeRemoved(0, 3);\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void testRemoveRange() {\n    modelList.removeRange(0, 2);\n    assertEquals(1, modelList.size());\n    verify(observer).onItemRangeRemoved(0, 2);\n  }\n\n  @Test\n  public void testRemoveEmptyRange() {\n    modelList.removeRange(1, 1);\n    verifyNoMoreInteractions(observer);\n  }\n\n  @Test\n  public void testIteratorRemove() {\n    Iterator<EpoxyModel<?>> iterator = modelList.iterator();\n    iterator.next();\n    iterator.remove();\n\n    verify(observer).onItemRangeRemoved(0, 1);\n  }\n\n  @Test\n  public void testRemoveAll() {\n    List<EpoxyModel<?>> modelsToRemove = new ArrayList<>();\n    modelsToRemove.add(modelList.get(0));\n    modelsToRemove.add(modelList.get(1));\n\n    modelList.removeAll(modelsToRemove);\n    verify(observer, times(2)).onItemRangeRemoved(0, 1);\n  }\n\n  @Test\n  public void testRetainAll() {\n    List<EpoxyModel<?>> modelsToRetain = new ArrayList<>();\n    modelsToRetain.add(modelList.get(0));\n\n    modelList.retainAll(modelsToRetain);\n    verify(observer, times(2)).onItemRangeRemoved(1, 1);\n  }\n}"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/ModelTestUtils.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass ModelTestUtils {\n  private static final int DEFAULT_NUM_MODELS = 20;\n\n  static void changeValues(List models) {\n    changeValues(models, 0, models.size());\n  }\n\n  static void changeValues(List models, int start, int count) {\n    for (int i = start; i < count; i++) {\n      models.set(i, ((TestModel) models.get(i)).clone().randomizeValue());\n    }\n  }\n\n  static void changeValue(EpoxyModel<?> model) {\n    ((TestModel) model).randomizeValue();\n  }\n\n  static void remove(List models, int start, int count) {\n    models.subList(start, start + count).clear();\n  }\n\n  static void removeModelsAfterPosition(List models, int start) {\n    remove(models, start, models.size() - start);\n  }\n\n  static void addModels(List list) {\n    addModels(DEFAULT_NUM_MODELS, list);\n  }\n\n  static void addModels(int count, List list) {\n    addModels(count, list, list.size());\n  }\n\n  static void addModels(List list, int index) {\n    addModels(DEFAULT_NUM_MODELS, list, index);\n  }\n\n  static void addModels(int count, List list, int index) {\n    List<TestModel> modelsToAdd = new ArrayList<>(count);\n    for (int i = 0; i < count; i++) {\n      modelsToAdd.add(new TestModel());\n    }\n\n    list.addAll(index, modelsToAdd);\n  }\n\n  static List<EpoxyModel<?>> convertToGenericModels(List<TestModel> list) {\n    List<EpoxyModel<?>> result = new ArrayList<>(list.size());\n    for (TestModel testModel : list) {\n      result.add(testModel);\n    }\n    return result;\n  }\n\n  static List<TestModel> convertToTestModels(List<EpoxyModel<?>> list) {\n    List<TestModel> result = new ArrayList<>(list.size());\n    for (EpoxyModel<?> model : list) {\n      result.add((TestModel) model);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/TestAdapter.java",
    "content": "package com.airbnb.epoxy;\n\nclass TestAdapter extends EpoxyAdapter {\n\n  TestAdapter() {\n    enableDiffing();\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/TestModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport java.util.Random;\n\npublic class TestModel extends EpoxyModel<View> {\n  private static final Random RANDOM = new Random(10);\n  boolean updated;\n  private int value;\n\n  public TestModel() {\n    // Uses a random id to make sure the algorithm doesn't have different behavior for\n    // consecutive or varied ids\n    super(RANDOM.nextLong());\n    randomizeValue();\n  }\n\n  public TestModel(long id) {\n    super(id);\n    randomizeValue();\n  }\n\n  TestModel randomizeValue() {\n    value = RANDOM.nextInt();\n    return this;\n  }\n\n  @Override\n  public int getDefaultLayout() {\n    return 0;\n  }\n\n  TestModel value(int value) {\n    this.value = value;\n    return this;\n  }\n\n  TestModel incrementValue() {\n    this.value++;\n    return this;\n  }\n\n  int value() {\n    return value;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n\n    TestModel testModel = (TestModel) o;\n\n    return value == testModel.value;\n  }\n\n  @Override\n  public int hashCode() {\n    int result = super.hashCode();\n    result = 31 * result + value;\n    return result;\n  }\n\n  public TestModel clone() {\n    TestModel clone = new TestModel()\n        .value(value);\n\n    return (TestModel) clone.id(id())\n        .layout(getLayout());\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/TestObserver.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\nclass TestObserver extends RecyclerView.AdapterDataObserver\n{\n  List<TestModel> modelsAfterDiffing = new ArrayList<>();\n  List<TestModel> initialModels = new ArrayList<>();\n  int operationCount = 0;\n  private boolean showLogs;\n\n  TestObserver(boolean showLogs) {\n    this.showLogs = showLogs;\n  }\n\n  TestObserver() {\n    this(false);\n  }\n\n  void setUpForNextDiff(List<TestModel> models) {\n    initialModels = new ArrayList<>(models);\n    modelsAfterDiffing = new ArrayList<>(models);\n  }\n\n  @Override\n  public void onItemRangeChanged(int positionStart, int itemCount) {\n    if (showLogs) {\n      System.out.println(\"Item range changed. Start: \" + positionStart + \" Count: \" + itemCount);\n    }\n    for (int i = positionStart; i < positionStart + itemCount; i++) {\n      modelsAfterDiffing.get(i).updated = true;\n    }\n    operationCount++;\n  }\n\n  @Override\n  public void onItemRangeInserted(int positionStart, int itemCount) {\n    if (showLogs) {\n      System.out.println(\"Item range inserted. Start: \" + positionStart + \" Count: \" + itemCount);\n    }\n    List<TestModel> modelsToAdd = new ArrayList<>(itemCount);\n    for (int i = 0; i < itemCount; i++) {\n      modelsToAdd.add(InsertedModel.INSTANCE);\n    }\n\n    modelsAfterDiffing.addAll(positionStart, modelsToAdd);\n    operationCount++;\n  }\n\n  @Override\n  public void onItemRangeRemoved(int positionStart, int itemCount) {\n    if (showLogs) {\n      System.out.println(\"Item range removed. Start: \" + positionStart + \" Count: \" + itemCount);\n    }\n    modelsAfterDiffing.subList(positionStart, positionStart + itemCount).clear();\n    operationCount++;\n  }\n\n  @Override\n  public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\n    if (showLogs) {\n      System.out.println(\"Item moved. From: \" + fromPosition + \" To: \" + toPosition);\n    }\n    TestModel itemToMove = modelsAfterDiffing.remove(fromPosition);\n    modelsAfterDiffing.add(toPosition, itemToMove);\n    operationCount++;\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/TypedEpoxyControllerTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\nimport org.robolectric.annotation.LooperMode;\nimport org.robolectric.annotation.LooperMode.Mode;\n\nimport static junit.framework.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(Mode.LEGACY)\npublic class TypedEpoxyControllerTest {\n\n  static class TestTypedController extends TypedEpoxyController<String> {\n    int numTimesBuiltModels = 0;\n\n    @Override\n    protected void buildModels(String data) {\n      assertEquals(\"data\", data);\n      numTimesBuiltModels++;\n    }\n  }\n\n  @Test\n  public void setData() {\n    TestTypedController controller = new TestTypedController();\n\n    controller.setData(\"data\");\n    controller.setData(\"data\");\n\n    controller.cancelPendingModelBuild();\n\n    controller.setData(\"data\");\n    controller.setData(\"data\");\n\n    assertEquals(4, controller.numTimesBuiltModels);\n  }\n}"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/UnboundedViewPoolTests.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.test.core.app.ApplicationProvider\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertNotNull\nimport org.junit.Assert.assertNull\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\n\n@RunWith(RobolectricTestRunner::class)\nclass UnboundedViewPoolTests {\n\n    private val testAdapter = RvAdapter()\n\n    @Test\n    fun `correctly stores different viewHolders`() {\n        UnboundedViewPool().run {\n            addAndAssert(123, 10)\n            addAndAssert(321, 5)\n        }\n    }\n\n    private fun UnboundedViewPool.addAndAssert(expectedId: Int, expectedCount: Int) {\n        repeat(expectedCount) {\n            putRecycledView(createViewHolder(expectedId))\n        }\n        assertEquals(expectedCount, getRecycledViewCount(expectedId))\n    }\n\n    @Test\n    fun `correctly removes from pool`() {\n        UnboundedViewPool().run {\n            val expectedId = 548\n            putRecycledView(createViewHolder(expectedId))\n            assertNotNull(getRecycledView(expectedId))\n            assertNull(getRecycledView(expectedId))\n        }\n    }\n\n    @Test\n    fun `correctly clears pool`() {\n        UnboundedViewPool().run {\n            val expectedId = 10\n            addAndAssert(expectedId, 10)\n            clear()\n            assertNull(getRecycledView(expectedId))\n            assertEquals(0, getRecycledViewCount(expectedId))\n        }\n    }\n\n    private fun createViewHolder(id: Int) =\n        testAdapter.createViewHolder(FrameLayout(ApplicationProvider.getApplicationContext()), id)\n\n    /**\n     * Creating adapter is needed because it is setting viewType to viewHolder internally\n     * during creation of new viewHolder\n     */\n    private class RvAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {\n        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =\n            EpoxyViewHolder(parent, View(parent.context), false)\n\n        override fun getItemCount() = 0\n\n        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {}\n    }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/UpdateOpHelperTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\npublic class UpdateOpHelperTest {\n\n  private final UpdateOpHelper helper = new UpdateOpHelper();\n\n  @Test\n  public void insertionBatch() {\n    helper.add(0); // New batch\n    helper.add(1); // Add at the end\n    helper.add(0); // Add at the start\n    helper.add(1); // Add in the middle\n\n    assertEquals(1, helper.getNumInsertionBatches());\n    assertEquals(4, helper.getNumInsertions());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(1, opList.size());\n    assertEquals(0, opList.get(0).positionStart);\n    assertEquals(4, opList.get(0).itemCount);\n\n    assertEquals(0, helper.getNumRemovalBatches());\n    assertEquals(0, helper.getNumRemovals());\n    assertEquals(0, helper.getNumMoves());\n  }\n\n  @Test\n  public void insertionMultipleBatches() {\n    helper.add(1); // New batch\n    helper.add(3); // New batch\n    helper.add(1); // New batch\n    helper.add(0); // New batch\n\n    assertEquals(4, helper.getNumInsertionBatches());\n    assertEquals(4, helper.getNumInsertions());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(4, opList.size());\n\n    assertEquals(1, opList.get(0).positionStart);\n    assertEquals(1, opList.get(0).itemCount);\n\n    assertEquals(3, opList.get(1).positionStart);\n    assertEquals(1, opList.get(1).itemCount);\n\n    assertEquals(1, opList.get(2).positionStart);\n    assertEquals(1, opList.get(2).itemCount);\n\n    assertEquals(0, opList.get(3).positionStart);\n    assertEquals(1, opList.get(3).itemCount);\n  }\n\n  @Test\n  public void insertionBatchRanges() {\n    helper.add(1, 2);\n    helper.add(1, 1);\n    helper.add(4, 1);\n\n    assertEquals(1, helper.getNumInsertionBatches());\n    assertEquals(4, helper.getNumInsertions());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(1, opList.size());\n    assertEquals(1, opList.get(0).positionStart);\n    assertEquals(4, opList.get(0).itemCount);\n  }\n\n  @Test\n  public void removeBatch() {\n    helper.remove(3); // New batch\n    helper.remove(3); // Remove at the end\n    helper.remove(2); // Remove at the start\n\n    assertEquals(1, helper.getNumRemovalBatches());\n    assertEquals(3, helper.getNumRemovals());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(1, opList.size());\n    assertEquals(2, opList.get(0).positionStart);\n    assertEquals(3, opList.get(0).itemCount);\n\n    assertEquals(0, helper.getNumInsertionBatches());\n    assertEquals(0, helper.getNumInsertions());\n    assertEquals(0, helper.getNumMoves());\n  }\n\n  @Test\n  public void removeMultipleBatches() {\n    helper.remove(3);\n    helper.remove(4);\n    helper.remove(2);\n\n    assertEquals(3, helper.getNumRemovalBatches());\n    assertEquals(3, helper.getNumRemovals());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(3, opList.size());\n\n    assertEquals(3, opList.get(0).positionStart);\n    assertEquals(1, opList.get(0).itemCount);\n\n    assertEquals(4, opList.get(1).positionStart);\n    assertEquals(1, opList.get(1).itemCount);\n\n    assertEquals(2, opList.get(2).positionStart);\n    assertEquals(1, opList.get(2).itemCount);\n  }\n\n  @Test\n  public void removeBatchRange() {\n    helper.remove(3, 2);\n    helper.remove(3, 2);\n    helper.remove(0, 3);\n\n    assertEquals(1, helper.getNumRemovalBatches());\n    assertEquals(7, helper.getNumRemovals());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(1, opList.size());\n    assertEquals(0, opList.get(0).positionStart);\n    assertEquals(7, opList.get(0).itemCount);\n  }\n\n  @Test\n  public void update() {\n    helper.update(1); // New Batch\n    helper.update(0); // Update at start of batch\n    helper.update(2); // Update at end of batch\n    helper.update(0); // Update same item as before (shouldn't be added to batch length)\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(1, opList.size());\n\n    assertEquals(0, opList.get(0).positionStart);\n    assertEquals(3, opList.get(0).itemCount);\n\n    assertEquals(0, helper.getNumInsertionBatches());\n    assertEquals(0, helper.getNumInsertions());\n    assertEquals(0, helper.getNumRemovalBatches());\n    assertEquals(0, helper.getNumRemovals());\n    assertEquals(0, helper.getNumMoves());\n  }\n\n  @Test\n  public void updateMultipleBatches() {\n    helper.update(3);\n    helper.update(5);\n    helper.update(3);\n    helper.update(0);\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(4, opList.size());\n\n    assertEquals(3, opList.get(0).positionStart);\n    assertEquals(1, opList.get(0).itemCount);\n\n    assertEquals(5, opList.get(1).positionStart);\n    assertEquals(1, opList.get(1).itemCount);\n\n    assertEquals(3, opList.get(2).positionStart);\n    assertEquals(1, opList.get(2).itemCount);\n\n    assertEquals(0, opList.get(3).positionStart);\n    assertEquals(1, opList.get(3).itemCount);\n\n    assertEquals(0, helper.getNumInsertionBatches());\n    assertEquals(0, helper.getNumInsertions());\n    assertEquals(0, helper.getNumRemovalBatches());\n    assertEquals(0, helper.getNumRemovals());\n    assertEquals(0, helper.getNumMoves());\n  }\n\n  @Test\n  public void moves() {\n    helper.move(0, 3);\n    helper.move(0, 4);\n\n    assertEquals(2, helper.getNumMoves());\n\n    assertEquals(0, helper.getNumInsertionBatches());\n    assertEquals(0, helper.getNumInsertions());\n    assertEquals(0, helper.getNumRemovalBatches());\n    assertEquals(0, helper.getNumRemovals());\n\n    List<UpdateOp> opList = helper.opList;\n    assertEquals(2, opList.size());\n\n    assertEquals(0, opList.get(0).positionStart);\n    assertEquals(3, opList.get(0).itemCount);\n\n    assertEquals(0, opList.get(0).positionStart);\n    assertEquals(3, opList.get(0).itemCount);\n  }\n}"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/ViewTypeManagerIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.FrameLayout;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\n\nimport androidx.annotation.NonNull;\nimport androidx.test.core.app.ApplicationProvider;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.spy;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(RobolectricTestRunner.class)\npublic class ViewTypeManagerIntegrationTest {\n\n  @Before\n  public void resetViewTypeMap() {\n    new ViewTypeManager().resetMapForTesting();\n  }\n\n  static class TestModel extends EpoxyModelWithView<View> {\n    @Override\n    public View buildView(@NonNull ViewGroup parent) {\n      return new FrameLayout(ApplicationProvider.getApplicationContext());\n    }\n  }\n\n  static class ModelWithViewType extends TestModel {\n\n    @Override\n    protected int getViewType() {\n      return 1;\n    }\n  }\n\n  static class ModelWithViewType2 extends TestModel {\n\n    @Override\n    protected int getViewType() {\n      return 2;\n    }\n  }\n\n  @Test\n  public void modelWithLayout() {\n    SimpleEpoxyAdapter adapter = new SimpleEpoxyAdapter();\n    adapter.addModel(new ModelWithViewType());\n    adapter.addModel(new ModelWithViewType2());\n\n    // The view type should be the value declared in the model\n    assertEquals(1, adapter.getItemViewType(0));\n    assertEquals(2, adapter.getItemViewType(1));\n  }\n\n  static class ModelWithoutViewType extends TestModel {}\n\n  static class ModelWithoutViewType2 extends TestModel {}\n\n  static class ModelWithoutViewType3 extends TestModel {}\n\n  @Test\n  public void modelsWithoutLayoutHaveViewTypesGenerated() {\n    SimpleEpoxyAdapter adapter = new SimpleEpoxyAdapter();\n\n    adapter.addModel(new ModelWithoutViewType());\n    adapter.addModel(new ModelWithoutViewType2());\n    adapter.addModel(new ModelWithoutViewType3());\n\n    adapter.addModel(new ModelWithoutViewType());\n    adapter.addModel(new ModelWithoutViewType2());\n    adapter.addModel(new ModelWithoutViewType3());\n\n    // Models with view type 0 should have a view type generated for them\n    assertEquals(-1, adapter.getItemViewType(0));\n    assertEquals(-2, adapter.getItemViewType(1));\n    assertEquals(-3, adapter.getItemViewType(2));\n    // Models of same class should share the same generated view type\n    assertEquals(-1, adapter.getItemViewType(3));\n    assertEquals(-2, adapter.getItemViewType(4));\n    assertEquals(-3, adapter.getItemViewType(5));\n  }\n\n  @Test\n  public void fastModelLookupOfLastModel() {\n    SimpleEpoxyAdapter adapter = spy(new SimpleEpoxyAdapter());\n    TestModel modelToAdd = spy(new ModelWithoutViewType());\n    adapter.addModel(modelToAdd);\n\n    int itemViewType = adapter.getItemViewType(0);\n\n    adapter.onCreateViewHolder(null, itemViewType);\n\n    // onExceptionSwallowed is called if the fast model look up failed\n    verify(adapter, never()).onExceptionSwallowed(any(RuntimeException.class));\n    verify(modelToAdd).buildView(null);\n  }\n\n  @Test\n  public void fallbackLookupOfUnknownModel() {\n    SimpleEpoxyAdapter adapter = spy(new SimpleEpoxyAdapter());\n    TestModel modelToAdd = spy(new ModelWithViewType());\n    adapter.addModel(modelToAdd);\n\n    // If we pass a view type that hasn't been looked up recently it should fallback to searching\n    // through all models to find a match.\n    adapter.onCreateViewHolder(null, 1);\n\n    // onExceptionSwallowed is called when the fast model look up fails\n    verify(adapter).onExceptionSwallowed(any(RuntimeException.class));\n    verify(modelToAdd).buildView(null);\n  }\n\n  @Test\n  public void viewTypesSharedAcrossAdapters() {\n    SimpleEpoxyAdapter adapter1 = new SimpleEpoxyAdapter();\n    SimpleEpoxyAdapter adapter2 = new SimpleEpoxyAdapter();\n\n    adapter1.addModel(new ModelWithoutViewType());\n    adapter1.addModel(new ModelWithoutViewType2());\n\n    adapter2.addModel(new ModelWithoutViewType());\n    adapter2.addModel(new ModelWithoutViewType2());\n\n    assertEquals(adapter1.getItemViewType(0), adapter2.getItemViewType(0));\n    assertEquals(adapter1.getItemViewType(1), adapter2.getItemViewType(1));\n  }\n}\n"
  },
  {
    "path": "epoxy-adapter/src/test/java/com/airbnb/epoxy/test/CarouselTest.java",
    "content": "package com.airbnb.epoxy.test;\n\nimport android.content.Context;\n\nimport com.airbnb.epoxy.Carousel;\nimport com.airbnb.epoxy.Carousel.SnapHelperFactory;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.Config;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.LinearSnapHelper;\nimport androidx.recyclerview.widget.SnapHelper;\n\n@RunWith(RobolectricTestRunner.class)\npublic class CarouselTest {\n\n  @Test\n  public void testOverrideGlobalSnapHelper() {\n    Carousel.setDefaultGlobalSnapHelperFactory(new SnapHelperFactory() {\n      @NonNull\n      @Override\n      public SnapHelper buildSnapHelper(Context context) {\n        return new LinearSnapHelper();\n      }\n    });\n  }\n\n  @Test\n  public void testODisableGlobalSnapHelper() {\n    Carousel.setDefaultGlobalSnapHelperFactory(null);\n  }\n}\n"
  },
  {
    "path": "epoxy-annotations/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-annotations/build.gradle",
    "content": "apply plugin: 'java'\napply plugin: 'org.jetbrains.kotlin.jvm'\napply from: '../publishing.gradle'\n\nkotlin {\n  jvmToolchain(8)\n}\n\ndependencies {\n  implementation rootProject.deps.androidAnnotations\n  // Allow us to use android support library annotations (@LayoutRes) in this project.\n  // Since this isn't an android module normally we couldn't access them otherwise.\n  compileOnly rootProject.deps.androidRuntime\n}\n"
  },
  {
    "path": "epoxy-annotations/gradle.properties",
    "content": "POM_NAME=Epoxy annotations\nPOM_ARTIFACT_ID=epoxy-annotations\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/AfterPropsSet.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This can be used to annotate methods inside classes with a {@link com.airbnb.epoxy.ModelView}\n * annotation. Methods with this annotation will be called after a view instance  is bound to a\n * model and all model props have been set. This is useful if you need to wait until multiple props\n * are set before doing certain initialization.\n * <p>\n * Methods with this annotation will be called after both the initial bind when the view comes on\n * screen, and after partial binds when an onscreen view is updated.\n */\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface AfterPropsSet {\n}\n\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/AutoModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Used to annotate model fields in an EpoxyController. Model fields annotated with this should not\n * be assigned a value directly; a model will automatically be created for them. A stable ID will\n * also be generated and assigned to the model. This ID will be the same across all instances of the\n * adapter, so it can be used for saving state of a model.\n */\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface AutoModel {\n\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/CallbackProp.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * A convenient replacement for {@link ModelProp} when the prop represents a callback or listener.\n * <p>\n * This is the same as using {@link ModelProp} with the options {@link\n * com.airbnb.epoxy.ModelProp.Option#NullOnRecycle} and\n * {@link com.airbnb.epoxy.ModelProp.Option#DoNotHash}\n * <p>\n * This can only be used on setters who's parameter is marked as nullable. The prop will be set to\n * null when the view is recycled to ensure that the listener is not leaked.\n * <p>\n * Be aware that since this applies the option {@link com.airbnb.epoxy.ModelProp.Option#DoNotHash}\n * changing the value of the listener will not trigger an update to the view.\n */\n@Target({ElementType.METHOD, ElementType.FIELD})\n@Retention(RetentionPolicy.CLASS)\npublic @interface CallbackProp {\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/EpoxyAttribute.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Used to annotate fields on EpoxyModel classes in order to generate a subclass of that model with\n * getters, setters, equals, and hashcode for the annotated fields.\n */\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface EpoxyAttribute {\n  /**\n   * Options that can be included on the attribute to affect how the model's generated class is\n   * created.\n   */\n  enum Option {\n    /**\n     * A getter is generated for this attribute by default. Add this option to prevent a getter from\n     * being generated.\n     */\n    NoGetter,\n    /**\n     * A setter is generated for this attribute by default. Add this option to prevent a setter from\n     * being generated.\n     */\n    NoSetter,\n    /**\n     * By default every attribute's hashCode and equals method is called when determining the\n     * model's state. This option can be used to exclude an attribute's hashCode/equals from\n     * contributing to the state.\n     * <p>\n     * This is useful for objects that may change without actually changing the model's state. A\n     * common case is an anonymous click listener that gets recreated with every bind call.\n     * <p>\n     * When this is used, the attribute will affect the model state solely based on whether it is\n     * null or non null.\n     * <p>\n     * A good rule of thumb for whether to use this on an attribute is, \"If this is the only\n     * attribute that changed do I still need to rebind and update the view?\" If the answer if no\n     * then you can use this to prevent the rebind.\n     */\n    DoNotHash,\n    /**\n     * This is meant to be used in conjunction with {@link PackageEpoxyConfig#requireHashCode()}.\n     * When that is enabled every attribute must implement hashCode/equals. However, there are some\n     * valid cases where the attribute type does not implement hashCode/equals, but it should still\n     * be hashed at runtime and contribute to the model's state. Use this option on an attribute in\n     * that case to tell the processor to let it pass the hashCode/equals validation.\n     * <p>\n     * An example case is AutoValue classes, where the generated class correctly implements\n     * hashCode/equals at runtime.\n     * <p>\n     * If you use this it is your responsibility to ensure that the object assigned to the attribute\n     * at runtime correctly implements hashCode/equals. If you don't want the attribute to\n     * contribute to model state you should use {@link Option#DoNotHash} instead.\n     */\n    IgnoreRequireHashCode,\n    /**\n     * This attribute is used in {@link Object#toString()} implementation by default.\n     * Add this option to prevent this attribute being used in {@link Object#toString()}.\n     */\n    DoNotUseInToString\n  }\n\n  /** Specify any {@link Option} values that should be used when generating the model class. */\n  Option[] value() default {};\n\n  /**\n   * Whether or not to include this attribute in equals and hashCode calculations.\n   * <p>\n   * It may be useful to disable this for objects that get recreated without the underlying data\n   * changing such as a click listener that gets created inline in every bind call.\n   *\n   * @deprecated Use {@link Option#DoNotHash} instead.\n   */\n  @Deprecated\n  boolean hash() default true;\n\n  /**\n   * Whether or not to generate setter for this attribute.\n   * <p>\n   * It may be useful to disable this for attribute which can be immutable and doesn't require\n   * setter.\n   *\n   * @deprecated Use {@link Option#NoSetter} instead.\n   */\n  @Deprecated\n  boolean setter() default true;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/EpoxyBuildScope.kt",
    "content": "package com.airbnb.epoxy\n\n/**\n * Used to mark Epoxy model building DSLs so that when using generated kotlin extension functions\n * for building models you cannot incorrectly nest models and also don't see cluttered, incorrect\n * code completion suggestions.\n */\n@DslMarker\nannotation class EpoxyBuildScope\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/EpoxyDataBindingLayouts.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport androidx.annotation.LayoutRes;\n\n/**\n * Used to specify a list of databinding layout resources that you want EpoxyModels generated for.\n * The models will be generated in the same package as this annotation. Every layout must be a valid\n * databinding layout. The name of the generated model will be based on the layout resource name.\n * <p>\n * The layouts must not specify a custom databinding class name or package via the\n * class=\"com.example.CustomClassName\" override in the layout xml.\n * <p>\n * Alternatively you can use {@link EpoxyDataBindingPattern} to avoid explicitly declaring each\n * layout.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface EpoxyDataBindingLayouts {\n  /** A list of databinding layout resources that should have EpoxyModel's generated for them. */\n  @LayoutRes int[] value();\n\n  /**\n     * If true, any variable whose type does not implement equals and hashcode will have the\n   * {@link EpoxyAttribute.Option#DoNotHash} behavior applied to them automatically.\n   * <p>\n   * This is generally helpful for listeners - other variables should almost always implement\n   * equals and hashcode.\n   * <p>\n   * For details on the nuances of this, see https://github.com/airbnb/epoxy/wiki/DoNotHash\n   */\n  boolean enableDoNotHash() default true;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/EpoxyDataBindingPattern.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Used to specify a naming pattern for the databinding layouts that you want models generated for.\n * Use this instead of {@link EpoxyDataBindingLayouts} to avoid having to explicitly list every\n * databinding layout.\n * <p>\n * The layouts must not specify a custom databinding class name or package via the\n * class=\"com.example.CustomClassName\" override in the layout xml.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface EpoxyDataBindingPattern {\n  /**\n   * The R class used in this module (eg \"com.example.app.R.class\"). This is needed so Epoxy can\n   * look up layout files.\n   */\n  Class<?> rClass();\n  /**\n   * A string prefix that your databinding layouts start with. Epoxy will generate a model for each\n   * databinding layout whose name starts with this.\n   * <p>\n   * For example, if you set this prefix to \"view_holder\" and you have a \"view_holder_header.xml\"\n   * databinding layout, Epoxy will generate a HeaderBindingModel_ class for that layout.\n   */\n  String layoutPrefix();\n\n  /**\n   * If true, any variable whose type does not implement equals and hashcode will have the\n   * {@link EpoxyAttribute.Option#DoNotHash} behavior applied to them automatically.\n   * <p>\n   * This is generally helpful for listeners - other variables should almost always implement\n   * equals and hashcode.\n   * <p>\n   * For details on the nuances of this, see https://github.com/airbnb/epoxy/wiki/DoNotHash\n   */\n  boolean enableDoNotHash() default true;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/EpoxyModelClass.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport androidx.annotation.LayoutRes;\n\n/**\n * Used to annotate EpoxyModel classes in order to generate a subclass of that model with getters,\n * setters, equals, and hashcode for the annotated fields, as well as other helper methods and\n * boilerplate reduction.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface EpoxyModelClass {\n  /**\n   * A layout resource that should be used as the default layout for the model. If you set this you\n   * don't have to implement `getDefaultLayout`; it will be generated for you.\n   */\n  @LayoutRes int layout() default 0;\n\n  /**\n   * If true, any layout file name that has {@link #layout()} as a prefix will be included as a\n   * method on the generated model.\n   * <p>\n   * For example, if the layout is \"R.layout.my_view\" then any layouts in the form of\n   * \"R.layout.my_view_*\" will result in a generated method like \"with*Layout\" that will apply that\n   * other layout instead of the default.\n   */\n  boolean useLayoutOverloads() default false;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/ModelProp.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Used in conjunction with {@link ModelView} to automatically generate EpoxyModels from custom\n * views - https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations\n * <p>\n * This annotation should be used on setter methods within a custom view class. Setters annotated\n * with this will have a corresponding field on the generated model.\n * <p>\n * Alternatively, if your setter has no side effects, you can use this annotation on a field to have\n * Epoxy set that field directly and avoid the boiler plate of a setter.\n * <p>\n * For convenience you can use {@link TextProp} instead for props representing text.\n * <p>\n * Similarly you can use {@link CallbackProp} for props representing listeners or callbacks.\n * <p>\n * Alternatively, the {@link #options()} parameter can be used to configure a prop.\n */\n@Target({ElementType.METHOD, ElementType.FIELD})\n@Retention(RetentionPolicy.CLASS)\npublic @interface ModelProp {\n\n  enum Option {\n    /**\n     * By default every prop's hashCode and equals method is called when determining the\n     * model's state. This option can be used to exclude an prop's hashCode/equals from\n     * contributing to the state.\n     * <p>\n     * This is useful for props that may change without actually changing the model's state. A\n     * common case is an anonymous click listener that gets recreated with every bind call.\n     * <p>\n     * When this is used, the prop will affect the model state solely based on whether it is\n     * null or non null.\n     * <p>\n     * A good rule of thumb for whether to use this on an prop is, \"If this is the only\n     * prop that changed do I still need to rebind and update the view?\" If the answer if no\n     * then you can use this to prevent the rebind.\n     */\n    DoNotHash,\n    /**\n     * This is meant to be used in conjunction with {@link PackageEpoxyConfig#requireHashCode()}.\n     * When that is enabled every prop must implement hashCode/equals. However, there are some\n     * valid cases where the prop type does not implement hashCode/equals, but it should still\n     * be hashed at runtime and contribute to the model's state. Use this option on an prop in\n     * that case to tell the processor to let it pass the hashCode/equals validation.\n     * <p>\n     * An example case is AutoValue classes, where the generated class correctly implements\n     * hashCode/equals at runtime.\n     * <p>\n     * If you use this it is your responsibility to ensure that the object assigned to the prop\n     * at runtime correctly implements hashCode/equals. If you don't want the prop to\n     * contribute to model state you should use {@link Option#DoNotHash} instead.\n     */\n    IgnoreRequireHashCode,\n    /**\n     * Setters with a type of {@link CharSequence} can add this option to have {@link\n     * androidx.annotation.StringRes} and {@link androidx.annotation.PluralsRes}\n     * overload methods generated on the model, so users can set the string via a resource.\n     */\n    GenerateStringOverloads,\n    /**\n     * Setters with a param annotated with @Nullable can use this to have null set when the view is\n     * recycled.\n     */\n    NullOnRecycle\n  }\n\n  /** Specify any {@link Option} values that should be used when generating the model class. */\n  Option[] options() default {};\n\n  /**\n   * The same as {@link #options()}, but this allows the shortcut of setting an option eg\n   * \"@ModelProp(DoNotHash)\".\n   */\n  Option[] value() default {};\n\n  /**\n   * The name of the constant field that should be used as the default value for this prop. The\n   * default value will be used if the prop value isn't set on the model.\n   * <p>\n   * For example, you would define a constant in your view class like <code>static final int\n   * DEFAULT_NUM_LINES = 3</code>, and then set this parameter to \"DEFAULT_NUM_LINES\" so that the\n   * annotation processor knows what constant to reference.\n   * <p>\n   * The name of the constant must be used instead of referencing the constant directly since\n   * objects are not valid annotation parameters.\n   */\n  String defaultValue() default \"\";\n\n  /**\n   * Specify an optional group name. Multiple props with the same group name will only allow one of\n   * the props to be set on the view.\n   * <p>\n   * https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations#prop-groups\n   */\n  String group() default \"\";\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/ModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport androidx.annotation.LayoutRes;\n\n/**\n * An annotation on custom view classes to automatically generate an EpoxyModel for that view. Used\n * in conjunction with {@link ModelProp}\n * <p>\n * See https://github.com/airbnb/epoxy/wiki/Generating-Models-from-View-Annotations\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface ModelView {\n\n  /**\n   * Use with {@link #autoLayout()} to declare what layout parameters should be used to size your\n   * view when it is added to a RecyclerView. This maps to the LayoutParams options {@code\n   * layout_width} and {@code layout_height}. If you want to set the LayoutParams manually, you can\n   * use {@link Size#MANUAL} and set the params in the View's constructor when it is initialized (a\n   * runtime exception will be thrown if layout params are not set during view instantiation when\n   * MANUAL is used).\n   */\n  enum Size {\n    NONE,\n    MANUAL,\n    WRAP_WIDTH_WRAP_HEIGHT,\n    WRAP_WIDTH_MATCH_HEIGHT,\n    MATCH_WIDTH_WRAP_HEIGHT,\n    MATCH_WIDTH_MATCH_HEIGHT\n  }\n\n  /**\n   * If set to an option besides {@link Size#NONE} Epoxy will create an instance of this view\n   * programmatically at runtime instead of inflating the view from xml. This is an alternative to\n   * using {@link #defaultLayout()}, and is a good option if you just need to specify layout\n   * parameters on your view with no other styling.\n   * <p>\n   * The size option you choose will define which layout parameters Epoxy uses at runtime when\n   * creating the view.\n   */\n  Size autoLayout() default Size.NONE;\n\n  /**\n   * The layout file to use in the generated model to inflate the view. This is required unless a\n   * default pattern is set via {@link PackageModelViewConfig} or {@link #autoLayout()} is used.\n   * <p>\n   * Overrides any default set in {@link PackageModelViewConfig}\n   */\n  @LayoutRes int defaultLayout() default 0;\n  /**\n   * An optional EpoxyModel subclass to use as the base class of the generated view. A default can\n   * also be set with {@link PackageModelViewConfig}\n   * <p>\n   * * Overrides any default set in {@link PackageModelViewConfig}\n   */\n  Class<?> baseModelClass() default Void.class;\n  /**\n   * Whether the model should save view state when unbound.\n   * <p>\n   * see: EpoxyModel#shouldSaveViewState\n   */\n  boolean saveViewState() default false;\n  /**\n   * True to have the generated model take up the total available span count. False to instead use a\n   * span count of 1. If you need to programmatically determine your model's span size you can use\n   * the spanSizeCallback method on EpoxyModel.\n   */\n  boolean fullSpan() default true;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/OnViewRecycled.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This can be used to annotate methods inside classes with a {@link com.airbnb.epoxy.ModelView}\n * annotation. Methods with this annotation will be called when the view is recycled by the\n * RecyclerView.\n */\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface OnViewRecycled {\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/OnVisibilityChanged.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This can be used to annotate methods inside classes with a {@link ModelView} annotation. Methods\n * with this annotation will be called when visibility part of the view change.\n * <p>\n * Annotated methods should follow this signature :\n * `@OnVisibilityChanged\n *  public void method(\n *    float percentVisibleHeight, float percentVisibleWidth: Float,\n *    int visibleHeight, int visibleWidth\n *  )`\n * <p>\n * The equivalent methods on the model is com.airbnb.epoxy.EpoxyModel#onVisibilityChanged\n * <p>\n * See also: OnModelVisibilityChangedListener\n */\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface OnVisibilityChanged {\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/OnVisibilityStateChanged.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This can be used to annotate methods inside classes with a {@link ModelView} annotation. Methods\n * with this annotation will be called when the visibility state is changed.\n * <p>\n * Annotated methods should follow this signature :\n * `@OnVisibilityStateChanged\n * public void method(@Visibility int state)`\n * <p>\n * Possible States are declared in com.airbnb.epoxy.VisibilityState.\n * <p>\n * The equivalent methods on the model is\n * com.airbnb.epoxy.EpoxyModel#onVisibilityStateChanged\n * <p>\n * See also: OnModelVisibilityStateChangedListener\n */\n@SuppressWarnings(\"JavadocReference\")\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface OnVisibilityStateChanged {\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageEpoxyConfig.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Use this annotation on any class or interface in your package to specify default behavior for the Epoxy\n * annotation processor for that package. You can only have one instance of this annotation per\n * package.\n * <p>\n * If an instance of this annotation is not found in a package then the default values are used.\n * <p>\n * See https://github.com/airbnb/epoxy/wiki/Configuration for more details on these options.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface PackageEpoxyConfig {\n  boolean REQUIRE_HASHCODE_DEFAULT = false;\n  boolean REQUIRE_ABSTRACT_MODELS_DEFAULT = false;\n  boolean IMPLICITLY_ADD_AUTO_MODELS_DEFAULT = false;\n  /**\n   * If true, all fields marked with {@link com.airbnb.epoxy.EpoxyAttribute} must have a type that\n   * implements hashCode and equals (besides the default Object implementation), or the attribute\n   * must set DoNotHash as an option.\n   * <p>\n   * Setting this to true is useful for ensuring that all model attributes correctly implement\n   * hashCode and equals, or use DoNotHash (eg for click listeners). It is a common mistake to miss\n   * these, which leads to invalid model state and incorrect diffing.\n   * <p>\n   * The check is done at compile time and compilation will fail if a hashCode validation fails.\n   * <p>\n   * Since it is done at compile time this can only check the direct type of the field. Interfaces\n   * or classes will pass the check if they either have an abstract hashCode/equals method (since it\n   * is assumed that the object at runtime will implement it) or their class hierarchy must have an\n   * implementation of hashCode/equals besides the default Object implementation.\n   * <p>\n   * If an attribute is an Iterable or Array then the type of object in that collection must\n   * implement hashCode/equals.\n   */\n  boolean requireHashCode() default REQUIRE_HASHCODE_DEFAULT;\n\n  /**\n   * If true, all classes that contains {@link com.airbnb.epoxy.EpoxyAttribute} or {@link\n   * com.airbnb.epoxy.EpoxyModelClass} annotations in your project must be abstract. Otherwise\n   * compilation will fail.\n   * <p>\n   * Forcing models to be abstract can prevent the mistake of using the original model class instead\n   * of the generated class.\n   */\n  boolean requireAbstractModels() default REQUIRE_ABSTRACT_MODELS_DEFAULT;\n\n  /**\n   * If true, models in an EpoxyController that use the {@link AutoModel} annotation don't need to\n   * be explicitly added to the controller with \".addTo\". Instead, they will be added automatically\n   * after they are modified.\n   * <p>\n   * For more details, see the wiki:\n   * https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#implicit-adding\n   */\n  boolean implicitlyAddAutoModels() default IMPLICITLY_ADD_AUTO_MODELS_DEFAULT;\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageModelViewConfig.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Settings that apply to all views annotated with {@link com.airbnb.epoxy.ModelView} in this\n * package. Also applies to subpackages, unless other package config values are set in those sub\n * packages.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.CLASS)\npublic @interface PackageModelViewConfig {\n  /**\n   * The R class used in this module (eg \"com.example.app.R.class\"). This is needed so Epoxy can\n   * look up layout files.\n   */\n  Class<?> rClass();\n  /**\n   * A default layout pattern to be used for specifying layouts for generated models. If this is set\n   * then a layout can be omitted from a view's {@link com.airbnb.epoxy.ModelView} annotation.\n   * <p>\n   * The \"%s\" placeholder represents the view's name in snack case. For example, the default value\n   * will use a layout resource of \"R.layout.my_view\" for the MyView class. If the layout name is\n   * changed to \"view_holder_%s\" then the layout used would be \"R.layout.view_holder_my_view\".\n   */\n  String defaultLayoutPattern() default \"%s\";\n\n  /** An optional EpoxyModel subclass that generated models should extend. */\n  Class<?> defaultBaseModelClass() default Void.class;\n\n  /**\n   * If true, any layout file name that has a view's default layout as a prefix will be included as\n   * a method on the generated model for that view.\n   * <p>\n   * For example, if the layout is \"R.layout.my_view\" then any layouts in the form of\n   * \"R.layout.my_view_*\" will result in a generated method like \"with*Layout\" that will apply that\n   * other layout instead of the default.\n   */\n  boolean useLayoutOverloads() default false;\n\n  /**\n   * Suffix, which will be appended to generated model's names. \"Model_\" is a default value.\n   */\n  String generatedModelSuffix() default \"Model_\";\n\n  /**\n   * Controls whether \"builder\" setter functions that returns the model type will be duplicated\n   * from super model classes with the function return type updated to use the generated model name.\n   * This helps make all setters (such as id(...) ) return the same generated model so they can be\n   * chained in a builder pattern. This is mainly intended for Java usage and is generally\n   * unnecessary when using models in kotlin, especially if the generated kotlin model\n   * build extension functions are used. Disabling this can greatly reduce the number of\n   * methods generated on models.\n   *\n   * Default is false. This may also be set project wide with an annotation processor option.\n   */\n  Option disableGenerateBuilderOverloads() default Option.Default;\n\n  /**\n   * Controls whether getter functions (that return the value of each attribute) are generated\n   * on models.\n   *\n   * Disabling this can greatly reduce the number of methods generated on models.\n   *\n   * Default is false. This may also be set project wide with an annotation processor option.\n   */\n  Option disableGenerateGetters() default Option.Default;\n\n  /**\n   * Controls whether the \"reset\" function (that clears all attribute values) are generated\n   * on models. This function is generally legacy and is not recommended to be used with the modern\n   * immutable model approach of EpoxyControllers.\n   *\n   * Disabling this reduces the amount of generated code.\n   *\n   * Default is false. This may also be set project wide with an annotation processor option.\n   */\n  Option disableGenerateReset() default Option.Default;\n\n  /**\n   * Enable or Disable an option, or inherit the default.\n   */\n  enum Option {\n    Default,\n    Enabled,\n    Disabled\n  }\n}\n"
  },
  {
    "path": "epoxy-annotations/src/main/java/com/airbnb/epoxy/TextProp.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport androidx.annotation.StringRes;\n\n/**\n * A convenient replacement for {@link ModelProp} when the prop represents text.\n * <p>\n * This can only be used when the setter parameter is a {@link CharSequence}\n * <p>\n * This is the same as using {@link ModelProp} with the option {@link\n * com.airbnb.epoxy.ModelProp.Option#GenerateStringOverloads}\n */\n@Target({ElementType.METHOD, ElementType.FIELD})\n@Retention(RetentionPolicy.CLASS)\npublic @interface TextProp {\n\n  @StringRes int defaultRes() default 0;\n}\n"
  },
  {
    "path": "epoxy-compose/.gitignore",
    "content": "/build"
  },
  {
    "path": "epoxy-compose/build.gradle",
    "content": "plugins {\n  id 'com.android.library'\n  id 'kotlin-android'\n  id 'org.jetbrains.kotlin.plugin.compose'\n}\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxy'\n\n  defaultConfig {\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.COMPOSE_MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n\n    consumerProguardFiles \"consumer-rules.pro\"\n  }\n\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n    }\n  }\n  buildFeatures {\n    compose true\n  }\n}\n\nkotlin {\n  jvmToolchain(8)\n}\n\ndependencies {\n  api project(':epoxy-annotations')\n  api project(':epoxy-adapter')\n\n  implementation rootProject.deps.composeUi\n  implementation rootProject.deps.activityCompose\n  implementation rootProject.deps.androidCoreKtx\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidDesignLibrary\n  implementation rootProject.deps.androidLifecycleRuntimeKtx\n}\n"
  },
  {
    "path": "epoxy-compose/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "epoxy-compose/gradle.properties",
    "content": "POM_NAME=Epoxy Compose Interop \nPOM_ARTIFACT_ID=epoxy-compose\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-compose/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "epoxy-compose/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest />"
  },
  {
    "path": "epoxy-compose/src/main/java/com/airbnb/epoxy/ComposeInterop.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.util.SparseArray\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.ComposeView\nimport androidx.compose.ui.viewinterop.AndroidView\n\n/**\n * An epoxy viewModel that can inflate a Composable function\n * The keys parameter is responsible for recomposition of the composable function in epoxy.\n * Make sure the class of the object passed in as keys, have equals implemented, that is\n * their equality can be checked.\n *\n * However if your composeFunction relies on mutableState to describe your UI,\n * then passing in key as parameter is not needed.\n *\n * @param keys              variable number of arguments that are responsible for\n * @param composeFunction   The composable function to display in epoxy\n */\nclass ComposeEpoxyModel(\n    vararg val keys: Any,\n    private val composeFunction: @Composable () -> Unit,\n) : EpoxyModelWithView<ComposeView>() {\n\n    private val keyedTags by lazy { SparseArray<Any>(2) }\n\n    /**\n     * add tag to this epoxy model\n     */\n    fun addTag(key: Int, tag: Any) {\n        keyedTags.put(key, tag)\n    }\n\n    fun tag(key: Int): Any? {\n        return keyedTags.get(key)\n    }\n\n    override fun buildView(parent: ViewGroup): ComposeView = ComposeView(parent.context)\n\n    override fun bind(view: ComposeView) {\n        super.bind(view)\n        view.setContent(composeFunction)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (other === this) return true\n        if (other !is ComposeEpoxyModel) return false\n\n        return keys.contentEquals(other.keys)\n    }\n\n    override fun hashCode(): Int {\n        var code = super.hashCode()\n\n        keys.forEach {\n            code = 31 * code + it.hashCode()\n        }\n\n        return code\n    }\n}\n\nfun ModelCollector.composableInterop(\n    id: String,\n    vararg keys: Any,\n    composeFunction: @Composable () -> Unit\n) {\n    // Note this is done to avoid ART bug in Android 12 (background https://issuetracker.google.com/issues/197818595 and\n    // https://github.com/airbnb/epoxy/issues/1199).\n    // The main objective is to have the creation of the ComposeEpoxyModel the setting of the id and the adding to the\n    // controller in the same method.\n    // Note that even this manual inlining might be spoiled by R8 outlining which, if enabled might outline the creation\n    // of the ComposeEpoxyModel and setting of the id to a separate method.\n    val composeEpoxyModel = ComposeEpoxyModel(*keys, composeFunction = composeFunction)\n    composeEpoxyModel.id(id)\n    add(composeEpoxyModel)\n}\n\n/**\n * [composeEpoxyModel] can be used directly in cases where more control over the epoxy model\n * is needed. Eg. When the epoxy model needs to be modified before it's added.\n */\n@Deprecated(\n    message = \"Use composeEpoxyModel with modelAction lambda instead to avoid crash on Android 12\",\n    replaceWith = ReplaceWith(\n        expression = \"composeEpoxyModel(id, *keys, modelAction = modelAction, composeFunction = composeFunction)\",\n        imports = [\"com.airbnb.epoxy.composeEpoxyModel\"]\n    )\n)\nfun composeEpoxyModel(\n    id: String,\n    vararg keys: Any,\n    composeFunction: @Composable () -> Unit\n): ComposeEpoxyModel {\n    return ComposeEpoxyModel(*keys, composeFunction = composeFunction).apply {\n        id(id)\n    }\n}\n\n/**\n * [composeEpoxyModel] can be used directly in cases where more control over the epoxy model\n * is needed. Eg. When the epoxy model needs to be modified before it's added.\n *\n * Note: This does not return the model and instead takes a modelAction lambda that can be used to\n * add the model to the controller, or modify it before adding.\n *\n * This is done to avoid ART bug in Android 12 (background https://issuetracker.google.com/issues/197818595 and\n * https://github.com/airbnb/epoxy/issues/1199).\n * The main objective is to have the creation of the ComposeEpoxyModel the setting of the id and\n * the adding to the controller in the same method.\n * Note that even with this construct this might be spoiled by R8 outlining which, if enabled might\n * outline the creation of the ComposeEpoxyModel and setting of the id to a separate method.\n */\ninline fun composeEpoxyModel(\n    id: String,\n    vararg keys: Any,\n    noinline composeFunction: @Composable () -> Unit,\n    modelAction: (ComposeEpoxyModel) -> Unit\n) {\n    val composeEpoxyModel = ComposeEpoxyModel(*keys, composeFunction = composeFunction)\n    composeEpoxyModel.id(id)\n    modelAction.invoke(composeEpoxyModel)\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@Composable\ninline fun <reified T : EpoxyModel<*>> EpoxyInterop(\n    modifier: Modifier = Modifier,\n    crossinline modelBuilder: T.() -> Unit,\n) {\n    val model = T::class.java.newInstance().apply(modelBuilder)\n\n    AndroidView(\n        factory = { context ->\n            FrameLayout(context).apply {\n                addView((model.buildView(this)))\n            }\n        },\n        modifier = modifier,\n    ) { view ->\n        val modelView = view.getChildAt(0)\n        (model as EpoxyModel<View>).bind(modelView)\n        (model as GeneratedModel<View>).handlePostBind(modelView, 0)\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/.gitignore",
    "content": "/build"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/build.gradle",
    "content": "plugins {\n  id 'com.android.application'\n  id 'kotlin-android'\n  id 'kotlin-kapt'\n  id 'org.jetbrains.kotlin.plugin.compose'\n}\n\nandroid {\n  namespace 'com.airbnb.epoxy.composeinterop.maverickssample'\n\n  lint {\n    disable 'MutableCollectionMutableState'\n  }\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.composeinterop.maverickssample\"\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.COMPOSE_MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    versionCode 1\n    versionName \"1.0\"\n\n    testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n    }\n  }\n\n  buildFeatures {\n    dataBinding true\n    compose true\n  }\n  packagingOptions {\n    exclude \"**/attach_hotspot_windows.dll\"\n    exclude \"META-INF/licenses/**\"\n    exclude \"META-INF/AL2.0\"\n    exclude \"META-INF/LGPL2.1\"\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n  implementation 'com.airbnb.android:mavericks:2.3.0'\n\n  implementation project(':epoxy-compose')\n  implementation project(':epoxy-databinding')\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n  implementation 'androidx.constraintlayout:constraintlayout:2.0.4'\n  kapt project(':epoxy-processor')\n\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidDesignLibrary\n  implementation rootProject.deps.paris\n  implementation rootProject.deps.composeUi\n  implementation rootProject.deps.androidCoreKtx\n  implementation rootProject.deps.composeMaterial\n  implementation rootProject.deps.activityCompose\n  implementation rootProject.deps.composeUiTooling\n  kapt rootProject.deps.parisProcessor\n\n  testImplementation rootProject.deps.junit\n\n  androidTestImplementation rootProject.deps.androidTestExtJunitKtx\n  androidTestImplementation rootProject.deps.androidTestRules\n  androidTestImplementation rootProject.deps.androidTestRunner\n  androidTestImplementation \"androidx.compose.ui:ui-test-junit4:$COMPOSE_VERSION\"\n  debugImplementation(\"androidx.compose.ui:ui-test-manifest:$COMPOSE_VERSION\")\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/androidTest/java/com/airbnb/epoxy/composeinterop/maverickssample/MultiKeyComposeInteropFragmentTest.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample\n\nimport androidx.compose.ui.test.assertIsDisplayed\nimport androidx.compose.ui.test.junit4.createAndroidComposeRule\nimport androidx.compose.ui.test.onAllNodesWithText\nimport androidx.compose.ui.test.onNodeWithText\nimport androidx.compose.ui.test.performClick\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n@RunWith(AndroidJUnit4::class)\nclass MultiKeyComposeInteropFragmentTest {\n    @get:Rule\n    val composeTestRule = createAndroidComposeRule<MainActivity>()\n\n    @Test\n    fun testComposableInInteropUsingMutableStateUpdatesEvenWithoutKey() {\n        for (i in 0..10) {\n            val textToAssert = \"withoutInteropKey mutableState: $i, recomposingCount: ${i + 1}\"\n            waitUntil(textToAssert)\n            checkIfTextIsDisplayed(textToAssert)\n\n            composeTestRule.onNodeWithText(textToAssert).performClick()\n        }\n\n        waitUntil(\"withoutInteropKey mutableState: 11, recomposingCount: 12\")\n        checkIfTextIsDisplayed(\"withoutInteropKey mutableState: 11, recomposingCount: 12\")\n\n        Thread.sleep(2000)\n\n        waitUntil(\"withoutInteropKey mutableState: 11, recomposingCount: 12\")\n        checkIfTextIsDisplayed(\"withoutInteropKey mutableState: 11, recomposingCount: 12\")\n    }\n\n    @Test\n    fun testComposableInteropWithIntegerKeyUpdatesAndWithoutKeyDoesNot() {\n        val withoutInteropKeyText = \"withoutInteropKey Int: 0, recomposingCount: 1\"\n\n        for (i in 0..10) {\n            waitUntil(withoutInteropKeyText)\n            waitUntil(\"withInteropKey Int: $i, recomposingCount: ${i + 1}\")\n\n            checkIfTextIsDisplayed(withoutInteropKeyText)\n            checkIfTextIsDisplayed(\"withInteropKey Int: $i, recomposingCount: ${i + 1}\")\n\n            composeTestRule.onNodeWithText(withoutInteropKeyText).performClick()\n        }\n\n        waitUntil(\"withInteropKey Int: 11, recomposingCount: 12\")\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey Int: 11, recomposingCount: 12\")\n\n        Thread.sleep(2000)\n\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey Int: 11, recomposingCount: 12\")\n    }\n\n    @Test\n    fun testComposableInteropWithStringKeyUpdatesAndWithoutKeyDoesNot() {\n        var str = \"\"\n        val withoutInteropKeyText = \"withoutInteropKey String: , recomposingCount: 1\"\n\n        for (i in 0..10) {\n            waitUntil(withoutInteropKeyText)\n            waitUntil(\"withInteropKey String: $str, recomposingCount: ${i + 1}\")\n\n            checkIfTextIsDisplayed(withoutInteropKeyText)\n            checkIfTextIsDisplayed(\"withInteropKey String: $str, recomposingCount: ${i + 1}\")\n\n            composeTestRule.onNodeWithText(withoutInteropKeyText).performClick()\n\n            str += \"#\"\n        }\n\n        waitUntil(\"withInteropKey String: $str, recomposingCount: 12\")\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey String: $str, recomposingCount: 12\")\n\n        Thread.sleep(2000)\n\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey String: $str, recomposingCount: 12\")\n    }\n\n    @Test\n    fun testComposableInteropWithListKeyUpdatesAndWithoutKeyDoesNot() {\n        val list = mutableListOf<Int>()\n        val withoutInteropKeyText = \"withoutInteropKey List: [], recomposingCount: 1\"\n\n        for (i in 0..10) {\n            waitUntil(withoutInteropKeyText)\n            waitUntil(\"withInteropKey List: $list, recomposingCount: ${i + 1}\")\n\n            checkIfTextIsDisplayed(withoutInteropKeyText)\n            checkIfTextIsDisplayed(\"withInteropKey List: $list, recomposingCount: ${i + 1}\")\n\n            composeTestRule.onNodeWithText(withoutInteropKeyText).performClick()\n\n            list.add(1)\n        }\n\n        waitUntil(\"withInteropKey List: $list, recomposingCount: 12\")\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey List: $list, recomposingCount: 12\")\n\n        Thread.sleep(2000)\n\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey List: $list, recomposingCount: 12\")\n    }\n\n    @Test\n    fun testComposableInteropWithDataClassKeyUpdatesAndWithoutKeyDoesNot() {\n        val list = mutableListOf<Int>()\n        val withoutInteropKeyText = \"withoutInteropKey DataClass: DataClassKey(listInDataClass=[]), recomposingCount: 1\"\n\n        for (i in 0..10) {\n            waitUntil(withoutInteropKeyText)\n            waitUntil(\"withInteropKey DataClass: DataClassKey(listInDataClass=$list), recomposingCount: ${i + 1}\")\n\n            checkIfTextIsDisplayed(withoutInteropKeyText)\n            checkIfTextIsDisplayed(\"withInteropKey DataClass: DataClassKey(listInDataClass=$list), recomposingCount: ${i + 1}\")\n\n            composeTestRule.onNodeWithText(withoutInteropKeyText).performClick()\n\n            list.add(2)\n        }\n\n        waitUntil(\"withInteropKey DataClass: DataClassKey(listInDataClass=$list), recomposingCount: 12\")\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey DataClass: DataClassKey(listInDataClass=$list), recomposingCount: 12\")\n\n        Thread.sleep(2000)\n\n        checkIfTextIsDisplayed(withoutInteropKeyText)\n        checkIfTextIsDisplayed(\"withInteropKey DataClass: DataClassKey(listInDataClass=$list), recomposingCount: 12\")\n    }\n\n    private fun waitUntil(text: String) {\n        composeTestRule.waitUntil {\n            composeTestRule.onAllNodesWithText(text)\n                .fetchSemanticsNodes().isNotEmpty()\n        }\n    }\n\n    private fun checkIfTextIsDisplayed(text: String) {\n        composeTestRule.onNodeWithText(text).assertIsDisplayed()\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:name=\".SampleApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.Epoxy\">\n        <activity\n            android:name=\"com.airbnb.epoxy.composeinterop.maverickssample.MainActivity\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/java/com/airbnb/epoxy/composeinterop/maverickssample/ComposeInteropListFragmnet.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.text.ClickableText\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.SpanStyle\nimport androidx.compose.ui.text.buildAnnotatedString\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.withStyle\nimport androidx.fragment.app.Fragment\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.TypedEpoxyController\nimport com.airbnb.epoxy.composableInterop\nimport com.airbnb.epoxy.composeinterop.maverickssample.epoxyviews.headerView\nimport com.airbnb.mvrx.MavericksState\nimport com.airbnb.mvrx.MavericksView\nimport com.airbnb.mvrx.MavericksViewModel\nimport com.airbnb.mvrx.fragmentViewModel\nimport com.airbnb.mvrx.withState\n\ndata class CounterState(\n    val counter: List<Int> = List(100) { it },\n) : MavericksState\n\nclass HelloWorldViewModel(initialState: CounterState) :\n    MavericksViewModel<CounterState>(initialState) {\n\n    fun increase(index: Int) {\n        withState { state ->\n            val updatedCounterList =\n                state.counter.mapIndexed { i, value -> if (i == index) value + 1 else value }\n\n            setState {\n                copy(counter = updatedCounterList)\n            }\n        }\n    }\n}\n\nclass ComposeInteropListFragmnet : Fragment(R.layout.fragment_my), MavericksView {\n    private val viewModel by fragmentViewModel(HelloWorldViewModel::class)\n\n    private val controller: MyEpoxyController by lazy { MyEpoxyController(viewModel) }\n\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View = inflater.inflate(R.layout.fragment_my, container, false).apply {\n        findViewById<EpoxyRecyclerView>(R.id.epoxyRecyclerView).apply {\n            setController(controller)\n        }\n    }\n\n    override fun invalidate() = withState(viewModel) {\n        controller.setData(it)\n    }\n}\n\nclass MyEpoxyController(private val viewModel: HelloWorldViewModel) :\n    TypedEpoxyController<CounterState>() {\n\n    private fun annotatedString(str: String) = buildAnnotatedString {\n        withStyle(\n            style = SpanStyle(fontWeight = FontWeight.Bold)\n        ) {\n            append(str)\n        }\n    }\n\n    override fun buildModels(state: CounterState) {\n        state.counter.forEachIndexed { index, counterValue ->\n            composableInterop(\"$index\", counterValue) {\n                Row(\n                    modifier = Modifier.fillMaxWidth(),\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    TextFromCompose(counterValue) {\n                        this@MyEpoxyController.viewModel.increase(index)\n                    }\n                }\n            }\n\n            headerView {\n                id(index)\n                title(\"Text from normal epoxy model: $counterValue\")\n\n                clickListener { _ ->\n                    this@MyEpoxyController.viewModel.increase(index)\n                }\n            }\n        }\n    }\n\n    @Composable\n    fun TextFromCompose(counterValue: Int, onClick: () -> Unit) {\n        ClickableText(\n            text = annotatedString(\"Text from composable interop $counterValue\"),\n            onClick = {\n                onClick()\n            }\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/java/com/airbnb/epoxy/composeinterop/maverickssample/MainActivity.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\n\nclass MainActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/java/com/airbnb/epoxy/composeinterop/maverickssample/MultiKeyComposeInteropFragment.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.ClickableText\nimport androidx.compose.material.Divider\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.unit.dp\nimport androidx.fragment.app.Fragment\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.ModelCollector\nimport com.airbnb.epoxy.TypedEpoxyController\nimport com.airbnb.epoxy.composableInterop\nimport com.airbnb.mvrx.MavericksState\nimport com.airbnb.mvrx.MavericksView\nimport com.airbnb.mvrx.MavericksViewModel\nimport com.airbnb.mvrx.fragmentViewModel\nimport com.airbnb.mvrx.withState\n\ndata class MultiKeyComposeInteropState(\n    val keyAsInt: Int = 0,\n    val keyAsString: String = \"\",\n    val keyAsList: List<Int> = emptyList(),\n    val keyAsDataClass: DataClassKey = DataClassKey()\n) : MavericksState\n\ndata class DataClassKey(\n    var listInDataClass: MutableList<Int> = mutableListOf()\n)\n\nclass MultiKeyComposeInteropViewModel(initialState: MultiKeyComposeInteropState) :\n    MavericksViewModel<MultiKeyComposeInteropState>(initialState) {\n\n    fun increaseCounter() {\n        withState { state ->\n            val updatedCounter = state.keyAsInt + 1\n            setState { copy(keyAsInt = updatedCounter) }\n        }\n    }\n\n    fun appendKeyString() {\n        withState { state ->\n            val updatedString = state.keyAsString + \"#\"\n            setState { copy(keyAsString = updatedString) }\n        }\n    }\n\n    fun appendKeyList() {\n        withState { state ->\n            val updatedList = state.keyAsList.toMutableList()\n            updatedList.add(1)\n            setState { copy(keyAsList = updatedList) }\n        }\n    }\n\n    fun appendDataClass() {\n        withState { state ->\n            val updatedDataClass =\n                state.keyAsDataClass.copy(listInDataClass = state.keyAsDataClass.listInDataClass.toMutableList())\n\n            updatedDataClass.listInDataClass.add(2)\n\n            setState { copy(keyAsDataClass = updatedDataClass) }\n        }\n    }\n\n    val mutableCounter = mutableStateOf(0)\n    var recomposingForWithoutKeyMutableState = 0\n\n    var recomposingForWithoutKeyInt = 0\n    var recomposingForWithKeyInt = 0\n\n    var recomposingForWithoutKeyString = 0\n    var recomposingForWithKeyString = 0\n\n    var recomposingForWithoutKeyList = 0\n    var recomposingForWithKeyList = 0\n\n    var recomposingForWithoutKeyDataClass = 0\n    var recomposingForWithKeyDataClass = 0\n\n    fun increaseMutableState() {\n        mutableCounter.value++\n        println(\"counter.value: ${mutableCounter.value}\")\n    }\n}\n\nclass MultiKeyComposeInteropFargment :\n    Fragment(R.layout.fragment_multi_key_compose_interop),\n    MavericksView {\n    private val viewModel by fragmentViewModel(MultiKeyComposeInteropViewModel::class)\n\n    private val controller: MultiKeyComposeInteropEpoxyController by lazy {\n        MultiKeyComposeInteropEpoxyController(viewModel)\n    }\n\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View =\n        inflater.inflate(R.layout.fragment_multi_key_compose_interop, container, false).apply {\n            findViewById<EpoxyRecyclerView>(R.id.epoxyRecyclerView).apply {\n                setController(controller)\n            }\n        }\n\n    override fun invalidate() = withState(viewModel) {\n        controller.setData(it)\n    }\n}\n\nclass MultiKeyComposeInteropEpoxyController(private val viewModel: MultiKeyComposeInteropViewModel) :\n    TypedEpoxyController<MultiKeyComposeInteropState>() {\n\n    override fun buildModels(state: MultiKeyComposeInteropState) {\n        withMutableState()\n\n        withoutInteropKeyInt(state)\n        withInteropKeyInt(state)\n\n        withoutInteropKeyString(state)\n        withInteropKeyString(state)\n\n        withoutInteropKeyList(state)\n        withInteropKeyList(state)\n\n        withoutInteropKeyDataClass(state)\n        withInteropKeyDataClass(state)\n    }\n\n    @Composable\n    fun InteropDivider() {\n        Divider(\n            color = Color.LightGray,\n            thickness = 1.dp,\n            modifier = Modifier.padding(top = 10.dp, bottom = 10.dp)\n        )\n    }\n\n    @Composable\n    fun ComposableWithMutableState() {\n        viewModel.recomposingForWithoutKeyMutableState++\n\n        ClickableText(\n            text = AnnotatedString(\"withoutInteropKey mutableState: ${viewModel.mutableCounter.value}, recomposingCount: ${viewModel.recomposingForWithoutKeyMutableState}\"),\n            onClick = {\n                viewModel.increaseMutableState()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableTextWithoutKeyInt(counter: Int) {\n        viewModel.recomposingForWithoutKeyInt++\n\n        ClickableText(\n            text = AnnotatedString(\"withoutInteropKey Int: $counter, recomposingCount: ${viewModel.recomposingForWithoutKeyInt}\"),\n            onClick = {\n                viewModel.increaseCounter()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableTextWithKeyInt(counter: Int) {\n        viewModel.recomposingForWithKeyInt++\n\n        ClickableText(\n            text = AnnotatedString(\"withInteropKey Int: $counter, recomposingCount: ${viewModel.recomposingForWithKeyInt}\"),\n            onClick = {\n                viewModel.increaseCounter()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableTextWithoutKeyString(keyAsString: String) {\n        viewModel.recomposingForWithoutKeyString++\n\n        ClickableText(\n            text = AnnotatedString(\"withoutInteropKey String: $keyAsString, recomposingCount: ${viewModel.recomposingForWithoutKeyString}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendKeyString()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableTextWithKeyString(keyAsString: String) {\n        viewModel.recomposingForWithKeyString++\n\n        ClickableText(\n            text = AnnotatedString(\"withInteropKey String: $keyAsString, recomposingCount: ${viewModel.recomposingForWithKeyString}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendKeyString()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableWithoutInteropKeyList(keyAsList: List<Int>) {\n        viewModel.recomposingForWithoutKeyList++\n\n        ClickableText(\n            text = AnnotatedString(\"withoutInteropKey List: $keyAsList, recomposingCount: ${viewModel.recomposingForWithoutKeyList}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendKeyList()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableWithInteropKeyList(keyAsList: List<Int>) {\n        viewModel.recomposingForWithKeyList++\n\n        ClickableText(\n            text = AnnotatedString(\"withInteropKey List: $keyAsList, recomposingCount: ${viewModel.recomposingForWithKeyList}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendKeyList()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableWithoutInteropKeyDataClass(keyAsDataClass: DataClassKey) {\n        viewModel.recomposingForWithoutKeyDataClass++\n\n        ClickableText(\n            text = AnnotatedString(\"withoutInteropKey DataClass: $keyAsDataClass, recomposingCount: ${viewModel.recomposingForWithoutKeyDataClass}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendDataClass()\n            }\n        )\n    }\n\n    @Composable\n    fun ComposableWithInteropKeyDataClass(keyAsDataClass: DataClassKey) {\n        viewModel.recomposingForWithKeyDataClass++\n\n        ClickableText(\n            text = AnnotatedString(\"withInteropKey DataClass: $keyAsDataClass, recomposingCount: ${viewModel.recomposingForWithKeyDataClass}\"),\n            onClick = {\n                this@MultiKeyComposeInteropEpoxyController.viewModel.appendDataClass()\n            }\n        )\n    }\n\n    private fun ModelCollector.withMutableState() {\n        composableInterop(\"id_counter_for_mutableState\") {\n            Column {\n                this@MultiKeyComposeInteropEpoxyController.ComposableWithMutableState()\n                this@MultiKeyComposeInteropEpoxyController.InteropDivider()\n            }\n        }\n    }\n\n    private fun ModelCollector.withoutInteropKeyInt(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_counter_without_keys\") {\n            this@MultiKeyComposeInteropEpoxyController.ComposableTextWithoutKeyInt(state.keyAsInt)\n        }\n    }\n\n    private fun ModelCollector.withInteropKeyInt(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_counter_with_keys\", state.keyAsInt) {\n            Column {\n                this@MultiKeyComposeInteropEpoxyController.ComposableTextWithKeyInt(state.keyAsInt)\n                this@MultiKeyComposeInteropEpoxyController.InteropDivider()\n            }\n        }\n    }\n\n    private fun ModelCollector.withoutInteropKeyString(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withoutInteropKeyString\") {\n            this@MultiKeyComposeInteropEpoxyController.ComposableTextWithoutKeyString(state.keyAsString)\n        }\n    }\n\n    private fun ModelCollector.withInteropKeyString(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withInteropKeyString\", state.keyAsString) {\n            Column {\n                this@MultiKeyComposeInteropEpoxyController.ComposableTextWithKeyString(state.keyAsString)\n                this@MultiKeyComposeInteropEpoxyController.InteropDivider()\n            }\n        }\n    }\n\n    private fun ModelCollector.withoutInteropKeyList(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withoutInteropKeyList\") {\n            this@MultiKeyComposeInteropEpoxyController.ComposableWithoutInteropKeyList(state.keyAsList)\n        }\n    }\n\n    private fun ModelCollector.withInteropKeyList(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withInteropKeyList\", state.keyAsList) {\n            Column {\n                this@MultiKeyComposeInteropEpoxyController.ComposableWithInteropKeyList(state.keyAsList)\n                this@MultiKeyComposeInteropEpoxyController.InteropDivider()\n            }\n        }\n    }\n\n    private fun ModelCollector.withoutInteropKeyDataClass(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withoutInteropKeyDataClass\") {\n            this@MultiKeyComposeInteropEpoxyController.ComposableWithoutInteropKeyDataClass(state.keyAsDataClass)\n        }\n    }\n\n    private fun ModelCollector.withInteropKeyDataClass(state: MultiKeyComposeInteropState) {\n        composableInterop(\"id_withInteropKeyDataClass\", state.keyAsDataClass) {\n            Column {\n                this@MultiKeyComposeInteropEpoxyController.ComposableWithInteropKeyDataClass(state.keyAsDataClass)\n                this@MultiKeyComposeInteropEpoxyController.InteropDivider()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/java/com/airbnb/epoxy/composeinterop/maverickssample/SampleApplication.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample\n\nimport android.app.Application\nimport com.airbnb.mvrx.Mavericks\n\nclass SampleApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        Mavericks.initialize(this)\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/java/com/airbnb/epoxy/composeinterop/maverickssample/epoxyviews/HeaderView.kt",
    "content": "package com.airbnb.epoxy.composeinterop.maverickssample.epoxyviews\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.composeinterop.maverickssample.R\nimport com.airbnb.paris.annotations.Style\nimport com.airbnb.paris.annotations.Styleable\nimport com.airbnb.paris.extensions.headerViewStyle\nimport com.airbnb.paris.extensions.layoutHeight\nimport com.airbnb.paris.extensions.layoutWidth\n\n@Styleable // Dynamic styling via the Paris library\n@ModelView(saveViewState = true)\nclass HeaderView(context: Context?) : LinearLayout(context) {\n    private var title: TextView\n    private var caption: TextView\n    private var image: ImageView\n\n    init {\n        inflate(getContext(), R.layout.header_view, this)\n\n        title = findViewById(R.id.title_text)\n        caption = findViewById(R.id.caption_text)\n        image = findViewById(R.id.image)\n    }\n\n    @TextProp(defaultRes = R.string.app_name)\n    fun setTitle(title: CharSequence?) {\n        this.title.text = title\n    }\n\n    @TextProp\n    fun setCaption(caption: CharSequence?) {\n        this.caption.text = caption\n    }\n\n    @ModelProp\n    fun setShowImage(isVisible: Boolean) {\n        image.visibility = if (isVisible) View.VISIBLE else View.GONE\n    }\n\n    @CallbackProp\n    fun setClickListener(listener: OnClickListener?) {\n        this.title.setOnClickListener(listener)\n    }\n\n    companion object {\n        @Style(isDefault = true)\n        val headerStyle: com.airbnb.paris.styles.Style = headerViewStyle {\n            layoutWidth(ViewGroup.LayoutParams.MATCH_PARENT)\n            layoutHeight(ViewGroup.LayoutParams.WRAP_CONTENT)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:aapt=\"http://schemas.android.com/aapt\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.fragment.app.FragmentContainerView android:id=\"@+id/frame_layout\"\n    android:name=\"com.airbnb.epoxy.composeinterop.maverickssample.MultiKeyComposeInteropFargment\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" />\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/layout/fragment_multi_key_compose_interop.xml",
    "content": "<com.airbnb.epoxy.EpoxyRecyclerView android:id=\"@+id/epoxyRecyclerView\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\" />\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/layout/fragment_my.xml",
    "content": "<com.airbnb.epoxy.EpoxyRecyclerView android:id=\"@+id/epoxyRecyclerView\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\" />\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/layout/header_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:layout_gravity=\"center\"\n        android:id=\"@+id/image\"\n        android:layout_width=\"200dp\"\n        android:layout_height=\"200dp\"\n        android:src=\"@drawable/header\"\n        android:visibility=\"gone\" />\n\n    <TextView\n        android:id=\"@+id/title_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:lineSpacingMultiplier=\"0.8\"\n        android:paddingTop=\"8dp\"\n        android:textColor=\"#000000\"\n        android:textSize=\"16sp\" />\n\n    <TextView\n        android:id=\"@+id/caption_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"8dp\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:textColor=\"#000000\"\n        android:textSize=\"20sp\" />\n\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n</resources>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">MavericksExample</string>\n</resources>\n"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.Epoxy\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_500</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/white</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_700</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "epoxy-composeinterop-maverickssample/src/main/res/values-night/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.Epoxy\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_200</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/black</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_200</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "epoxy-composesample/.gitignore",
    "content": "/build"
  },
  {
    "path": "epoxy-composesample/build.gradle",
    "content": "plugins {\n  id 'com.android.application'\n  id 'kotlin-android'\n  id 'kotlin-kapt'\n  id 'org.jetbrains.kotlin.plugin.compose'\n}\n\nandroid {\n  namespace 'com.airbnb.epoxy.compose.sample'\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.compose.sample\"\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.COMPOSE_MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    versionCode 1\n    versionName \"1.0\"\n  }\n\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n    }\n  }\n  buildFeatures {\n    compose true\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n  implementation project(':epoxy-compose')\n  implementation project(':epoxy-databinding')\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n  implementation 'androidx.constraintlayout:constraintlayout:2.0.4'\n  kapt project(':epoxy-processor')\n  implementation 'com.jakewharton:butterknife:10.2.3'\n  kapt 'com.jakewharton:butterknife-compiler:10.2.3'\n\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidDesignLibrary\n  implementation rootProject.deps.paris\n  implementation rootProject.deps.composeUi\n  implementation rootProject.deps.androidCoreKtx\n  implementation rootProject.deps.composeMaterial\n  implementation rootProject.deps.activityCompose\n  implementation rootProject.deps.composeUiTooling\n  kapt rootProject.deps.parisProcessor\n}"
  },
  {
    "path": "epoxy-composesample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "epoxy-composesample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.Epoxy\">\n        <activity\n            android:name=\".ComposableInteropActivity\"\n            android:exported=\"true\" />\n        <activity\n            android:name=\".EpoxyInteropActivity\"\n            android:exported=\"true\" />\n        <activity\n            android:name=\".MainActivity\"\n            android:exported=\"true\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/Theme.Epoxy.NoActionBar\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/ComposableInteropActivity.kt",
    "content": "package com.airbnb.epoxy.compose.sample\n\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.Divider\nimport androidx.compose.material.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.composableInterop\nimport com.airbnb.epoxy.compose.sample.epoxyviews.headerView\n\nclass ComposableInteropActivity : ComponentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_composable_interop)\n\n        val recyclerView: EpoxyRecyclerView = findViewById(R.id.epoxy_recycler_view)\n\n        recyclerView.withModels {\n            headerView {\n                id(\"header\")\n                title(\"Testing Composable in Epoxy\")\n            }\n\n            for (i in 0..100) {\n                composableInterop(id = \"compose_text_$i\") {\n                    ShowCaption(\"Caption coming from composable\")\n                }\n\n                composableInterop(id = \"news_$i\") {\n                    NewsStory()\n                }\n            }\n        }\n    }\n}\n\n@Composable\n@Preview\nfun NewsStory() {\n    Column(\n        modifier = Modifier.padding(16.dp),\n        horizontalAlignment = Alignment.CenterHorizontally,\n    ) {\n        Image(\n            painter = painterResource(id = R.drawable.header),\n            contentDescription = null\n        )\n\n        ShowCaption(\"Above Image and below text are coming from Compose in Epoxy\")\n        ShowCaption(\"Davenport, California\")\n        ShowCaption(\"December 2021\")\n\n        Divider(\n            color = Color(0x859797CF),\n            thickness = 2.dp,\n            modifier = Modifier.padding(top = 16.dp)\n        )\n    }\n}\n\n@Composable\nfun ShowCaption(text: String) {\n    Text(\n        text,\n        textAlign = TextAlign.Center,\n        modifier = Modifier\n            .padding(4.dp)\n            .fillMaxWidth()\n    )\n}\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/EpoxyInteropActivity.kt",
    "content": "package com.airbnb.epoxy.compose.sample\n\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.platform.ComposeView\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.airbnb.epoxy.EpoxyInterop\nimport com.airbnb.epoxy.compose.sample.epoxyviews.HeaderViewModel_\n\nclass EpoxyInteropActivity : ComponentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_epoxy_interop)\n\n        val composeView: ComposeView = findViewById(R.id.compose_view)\n\n        composeView.setContent {\n            Column {\n                Title(\"Testing Epoxy in Composable\")\n\n                LazyColumn {\n                    items(100) { index ->\n                        EpoxyInterop<HeaderViewModel_>(\n                            modifier = Modifier.fillMaxWidth(),\n                        ) {\n                            id(\"id_header_view_model\", index.toLong())\n                            title(\"Epoxy model in compose $index\")\n                            showImage(true)\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun Title(titleText: String) {\n    Text(\n        text = titleText,\n        fontWeight = FontWeight.Bold,\n        textAlign = TextAlign.Center,\n        modifier = Modifier\n            .background(Color(0x85DFDFFF), RectangleShape)\n            .padding(20.dp)\n            .fillMaxWidth()\n    )\n}\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/MainActivity.kt",
    "content": "package com.airbnb.epoxy.compose.sample\n\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\n\nclass MainActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        setContentView(R.layout.activity_main)\n\n        findViewById<View>(R.id.button).setOnClickListener {\n            startActivity(Intent(this, ComposableInteropActivity::class.java))\n        }\n\n        findViewById<View>(R.id.button2).setOnClickListener {\n            startActivity(Intent(this, EpoxyInteropActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/epoxyviews/HeaderView.kt",
    "content": "package com.airbnb.epoxy.compose.sample.epoxyviews\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport com.airbnb.epoxy.AfterPropsSet\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.compose.sample.R\nimport com.airbnb.paris.annotations.Style\nimport com.airbnb.paris.annotations.Styleable\nimport com.airbnb.paris.extensions.headerViewStyle\nimport com.airbnb.paris.extensions.layoutHeight\nimport com.airbnb.paris.extensions.layoutWidth\n\n@Styleable // Dynamic styling via the Paris library\n@ModelView\nclass HeaderView(context: Context?) : LinearLayout(context) {\n    private var title: TextView? = null\n    private var caption: TextView? = null\n    private var image: ImageView? = null\n\n    init {\n        orientation = VERTICAL\n        inflate(getContext(), R.layout.header_view, this)\n\n        title = findViewById(R.id.title_text)\n        caption = findViewById(R.id.caption_text)\n        image = findViewById(R.id.image)\n    }\n\n    @TextProp(defaultRes = R.string.app_name)\n    fun setTitle(title: CharSequence?) {\n        this.title?.text = title\n    }\n\n    @TextProp\n    fun setCaption(caption: CharSequence?) {\n        this.caption?.text = caption\n    }\n\n    @ModelProp\n    fun setShowImage(isVisible: Boolean) {\n        image?.visibility = if (isVisible) View.VISIBLE else View.GONE\n    }\n\n    @AfterPropsSet\n    fun changeTitleColor() {\n        title?.text?.last()?.let {\n            if (it.isDigit()) {\n                val isEven = it.digitToInt() % 2 == 0\n                if (isEven) {\n                    title?.setTextColor(resources.getColor(com.google.android.material.R.color.design_default_color_primary))\n                } else {\n                    title?.setTextColor(resources.getColor(com.google.android.material.R.color.design_default_color_secondary))\n                }\n            }\n        }\n    }\n\n    companion object {\n        @Style(isDefault = true)\n        val headerStyle: com.airbnb.paris.styles.Style = headerViewStyle {\n            layoutWidth(ViewGroup.LayoutParams.MATCH_PARENT)\n            layoutHeight(ViewGroup.LayoutParams.WRAP_CONTENT)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/ui/theme/Color.kt",
    "content": "package com.airbnb.epoxy.compose.sample.ui.theme\n\nimport androidx.compose.ui.graphics.Color\n\nval Purple200 = Color(0xFFBB86FC)\nval Purple500 = Color(0xFF6200EE)\nval Purple700 = Color(0xFF3700B3)\nval Teal200 = Color(0xFF03DAC5)\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/ui/theme/Shape.kt",
    "content": "package com.airbnb.epoxy.compose.sample.ui.theme\n\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.Shapes\nimport androidx.compose.ui.unit.dp\n\nval Shapes = Shapes(\n    small = RoundedCornerShape(4.dp),\n    medium = RoundedCornerShape(4.dp),\n    large = RoundedCornerShape(0.dp)\n)\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/ui/theme/Theme.kt",
    "content": "package com.airbnb.epoxy.compose.sample.ui.theme\n\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.material.MaterialTheme\nimport androidx.compose.material.darkColors\nimport androidx.compose.material.lightColors\nimport androidx.compose.runtime.Composable\n\nprivate val DarkColorPalette = darkColors(\n    primary = Purple200,\n    primaryVariant = Purple700,\n    secondary = Teal200\n)\n\nprivate val LightColorPalette = lightColors(\n    primary = Purple500,\n    primaryVariant = Purple700,\n    secondary = Teal200\n\n    /* Other default colors to override\n    background = Color.White,\n    surface = Color.White,\n    onPrimary = Color.White,\n    onSecondary = Color.Black,\n    onBackground = Color.Black,\n    onSurface = Color.Black,\n    */\n)\n\n@Composable\nfun EpoxyTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {\n    val colors = if (darkTheme) {\n        DarkColorPalette\n    } else {\n        LightColorPalette\n    }\n\n    MaterialTheme(\n        colors = colors,\n        typography = Typography,\n        shapes = Shapes,\n        content = content\n    )\n}\n"
  },
  {
    "path": "epoxy-composesample/src/main/java/com/airbnb/epoxy/compose/sample/ui/theme/Type.kt",
    "content": "package com.airbnb.epoxy.compose.sample.ui.theme\n\nimport androidx.compose.material.Typography\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.sp\n\n// Set of Material typography styles to start with\nval Typography = Typography(\n    body1 = TextStyle(\n        fontFamily = FontFamily.Default,\n        fontWeight = FontWeight.Normal,\n        fontSize = 16.sp\n    )\n    /* Other default text styles to override\n    button = TextStyle(\n        fontFamily = FontFamily.Default,\n        fontWeight = FontWeight.W500,\n        fontSize = 14.sp\n    ),\n    caption = TextStyle(\n        fontFamily = FontFamily.Default,\n        fontWeight = FontWeight.Normal,\n        fontSize = 12.sp\n    )\n    */\n)\n"
  },
  {
    "path": "epoxy-composesample/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "epoxy-composesample/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:aapt=\"http://schemas.android.com/aapt\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>"
  },
  {
    "path": "epoxy-composesample/src/main/res/layout/activity_composable_interop.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.EpoxyRecyclerView android:id=\"@+id/epoxy_recycler_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" />"
  },
  {
    "path": "epoxy-composesample/src/main/res/layout/activity_epoxy_interop.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.compose.ui.platform.ComposeView android:id=\"@+id/compose_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\" />"
  },
  {
    "path": "epoxy-composesample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Composable interop\"\n        app:layout_constraintBottom_toTopOf=\"@+id/button2\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <Button\n        android:id=\"@+id/button2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Epoxy interop\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"@+id/button\"\n        app:layout_constraintStart_toStartOf=\"@+id/button\"\n        app:layout_constraintTop_toBottomOf=\"@id/button\" />\n</androidx.constraintlayout.widget.ConstraintLayout>\n\n"
  },
  {
    "path": "epoxy-composesample/src/main/res/layout/header_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:layout_gravity=\"center\"\n        android:id=\"@+id/image\"\n        android:layout_width=\"200dp\"\n        android:layout_height=\"200dp\"\n        android:src=\"@drawable/header\"\n        android:visibility=\"gone\" />\n\n    <TextView\n        android:id=\"@+id/title_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:lineSpacingMultiplier=\"0.8\"\n        android:paddingTop=\"8dp\"\n        android:textColor=\"#000000\"\n        android:textSize=\"16sp\" />\n\n    <TextView\n        android:id=\"@+id/caption_text\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"8dp\"\n        android:gravity=\"center\"\n        android:textColor=\"#000000\"\n        android:textSize=\"20sp\"\n        tools:text=\"caption\" />\n\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-composesample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "epoxy-composesample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "epoxy-composesample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n</resources>"
  },
  {
    "path": "epoxy-composesample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy Compose Sample</string>\n</resources>"
  },
  {
    "path": "epoxy-composesample/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.Epoxy\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_500</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/white</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_700</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n\n    <style name=\"Theme.Epoxy.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"Theme.Epoxy.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"Theme.Epoxy.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n</resources>"
  },
  {
    "path": "epoxy-composesample/src/main/res/values-night/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.Epoxy\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_200</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/black</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_200</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "epoxy-databinding/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-databinding/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxy.databinding'\n\n  defaultConfig {\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n  }\n\n  dataBinding {\n    // DataBinding is pulling in an old version of the support library which makes lint complain.\n    // Ignoring it for now until we can figure out how to fix it.\n    enabled = true\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n}\n\nconfigurations.all { strategy ->\n  strategy.resolutionStrategy.force rootProject.deps.androidAnnotations, rootProject.deps.androidRecyclerView,\n      rootProject.deps.androidDesignLibrary, rootProject.deps.androidAppcompat, rootProject.deps.junit,\n      rootProject.deps.robolectric, rootProject.deps.mockito\n}\n\ndependencies {\n    implementation rootProject.deps.androidAnnotations\n    implementation rootProject.deps.androidRecyclerView\n    implementation rootProject.deps.androidDesignLibrary\n    implementation rootProject.deps.androidAppcompat\n    implementation project(':epoxy-annotations')\n    implementation project(':epoxy-adapter')\n\n    testImplementation rootProject.deps.junit\n    testImplementation rootProject.deps.robolectric\n    testImplementation rootProject.deps.mockito\n}\n"
  },
  {
    "path": "epoxy-databinding/gradle.properties",
    "content": "POM_NAME=Epoxy Data Binding Support\nPOM_ARTIFACT_ID=epoxy-databinding\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-databinding/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/eli_hart/tools/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "epoxy-databinding/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:supportsRtl=\"true\"/>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-databinding/src/main/java/com/airbnb/epoxy/DataBindingEpoxyModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.ViewParent;\n\nimport com.airbnb.epoxy.DataBindingEpoxyModel.DataBindingHolder;\n\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\nimport androidx.databinding.DataBindingUtil;\nimport androidx.databinding.ViewDataBinding;\n\n/**\n * A version of {@link com.airbnb.epoxy.EpoxyModel} that can be used with databinding. The layout\n * resource used with this model must be a databinding layout. This class will create the\n * databinding object from the layout and call the {@link #setDataBindingVariables} methods when the\n * view needs binding to the model.\n * <p>\n * The easiest way to use this model is to have Epoxy generate a model to do all the binding work\n * for you. To do this, create an abstract subclass of this model, annotate it with {@link\n * EpoxyModelClass}, and pass your layout resource as the layout param. (You must pass the layout\n * this way instead of implementing {@link #getDefaultLayout()}).\n * <p>\n * Then, make a field to represent each of the data variables in your layout and annotate each one\n * with {@link EpoxyAttribute}. The name of each field must match the name of the variable in the\n * layout exactly.\n * <p>\n * Epoxy will generate a subclass of your model at compile time that implements {@link\n * #setDataBindingVariables(ViewDataBinding)} and {@link #setDataBindingVariables(ViewDataBinding,\n * EpoxyModel)} for you. This will do all binding for you, and also only bind variables that change\n * if you update your model (Note: The change optimization only works when used with {@link\n * EpoxyController}).\n */\npublic abstract class DataBindingEpoxyModel extends EpoxyModelWithHolder<DataBindingHolder> {\n\n  @Override\n  public View buildView(@NonNull ViewGroup parent) {\n    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());\n    ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, getViewType(), parent, false);\n    View view = binding.getRoot();\n    view.setTag(binding);\n    return view;\n  }\n\n  @Override\n  public void bind(@NonNull DataBindingHolder holder) {\n    setDataBindingVariables(holder.dataBinding);\n    holder.dataBinding.executePendingBindings();\n  }\n\n  @Override\n  public void bind(@NonNull DataBindingHolder holder, @NonNull EpoxyModel<?> previouslyBoundModel) {\n    setDataBindingVariables(holder.dataBinding, previouslyBoundModel);\n    holder.dataBinding.executePendingBindings();\n  }\n\n  @Override\n  public void bind(@NonNull DataBindingHolder holder, @NonNull List<Object> payloads) {\n    setDataBindingVariables(holder.dataBinding, payloads);\n    holder.dataBinding.executePendingBindings();\n  }\n\n  /**\n   * This is called when the model is bound to a view, and the view's variables should be updated\n   * with the model's data. {@link ViewDataBinding#executePendingBindings()} is called for you after\n   * this method is run.\n   * <p>\n   * If you leave your class abstract and have a model generated for you via annotations this will\n   * be implemented for you. However, you may choose to implement this manually if you like.\n   */\n  protected abstract void setDataBindingVariables(ViewDataBinding binding);\n\n  /**\n   * Similar to {@link #setDataBindingVariables(ViewDataBinding)}, but this method only binds\n   * variables that have changed. The changed model comes from {@link #bind(DataBindingHolder,\n   * EpoxyModel)}. This will only be called if the model is used in an {@link EpoxyController}\n   * <p>\n   * If you leave your class abstract and have a model generated for you via annotations this will\n   * be implemented for you. However, you may choose to implement this manually if you like.\n   */\n  protected void setDataBindingVariables(ViewDataBinding dataBinding,\n      EpoxyModel<?> previouslyBoundModel) {\n    setDataBindingVariables(dataBinding);\n  }\n\n  protected void setDataBindingVariables(ViewDataBinding dataBinding, List<Object> payloads) {\n    setDataBindingVariables(dataBinding);\n  }\n\n  @Override\n  public void unbind(@NonNull DataBindingHolder holder) {\n    holder.dataBinding.unbind();\n  }\n\n  @Override\n  protected final DataBindingHolder createNewHolder(@NonNull ViewParent parent) {\n    return new DataBindingHolder();\n  }\n\n  public static class DataBindingHolder extends EpoxyHolder {\n    private ViewDataBinding dataBinding;\n\n    public ViewDataBinding getDataBinding() {\n      return dataBinding;\n    }\n\n    @Override\n    protected void bindView(@NonNull View itemView) {\n      dataBinding = (ViewDataBinding) itemView.getTag();\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-glide-preloader/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-glide-preloader/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxy.preloader'\n\n  defaultConfig {\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n  implementation rootProject.deps.glide\n\n  api project(':epoxy-annotations')\n  api project(':epoxy-adapter')\n\n  implementation rootProject.deps.androidRecyclerView\n\n  androidTestImplementation rootProject.deps.junit\n  androidTestImplementation rootProject.deps.androidArchCoreTesting\n  androidTestImplementation rootProject.deps.androidTestRunner\n\n  kaptAndroidTest project(\":epoxy-processor\")\n}\n"
  },
  {
    "path": "epoxy-glide-preloader/gradle.properties",
    "content": "POM_NAME=Epoxy Glide Preloading\nPOM_ARTIFACT_ID=epoxy-glide-preloading\nPOM_PACKAGING=jar\n"
  },
  {
    "path": "epoxy-glide-preloader/src/androidTest/java/com/airbnb/epoxy/preloader/ExampleInstrumentedTest.java",
    "content": "package com.airbnb.epoxy.preloader;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.airbnb.epoxy.preloader.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "epoxy-glide-preloader/src/main/AndroidManifest.xml",
    "content": "<manifest />\n"
  },
  {
    "path": "epoxy-glide-preloader/src/main/java/com/airbnb/epoxy/GlidePreloadExtensions.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.content.pm.ApplicationInfo\nimport android.view.View\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.preload.EpoxyModelPreloader\nimport com.airbnb.epoxy.preload.EpoxyPreloader\nimport com.airbnb.epoxy.preload.PreloadErrorHandler\nimport com.airbnb.epoxy.preload.ViewData\nimport com.airbnb.epoxy.preload.ViewMetadata\nimport com.bumptech.glide.RequestBuilder\nimport com.bumptech.glide.RequestManager\n\n/**\n * Helper to create and add an [EpoxyPreloader] to this RecyclerView that preloads Glide image requests.\n *\n * If you are using [com.airbnb.epoxy.EpoxyRecyclerView], prefer the [addGlidePreloader] for EpoxyRecyclerView instead.\n *\n * @param maxPreloadDistance How many items to prefetch ahead of the last bound item\n * @param errorHandler Called when the preloader encounters an exception. By default this throws only\n * if the app is not in a debuggable model\n * @param preloader Describes how Glide should preload images for the EpoxyModel. Use [glidePreloader]\n * to easily create this.\n */\nfun <T : EpoxyModel<*>, U : ViewMetadata?> RecyclerView.addGlidePreloader(\n    epoxyController: EpoxyController,\n    requestManager: RequestManager,\n    maxPreloadDistance: Int = 3,\n    errorHandler: PreloadErrorHandler = { context, err -> if (!context.isDebuggable) throw err },\n    preloader: EpoxyModelPreloader<T, U, GlidePreloadRequestHolder>\n) {\n    EpoxyPreloader.with(\n        epoxyController = epoxyController,\n        requestHolderFactory = { GlidePreloadRequestHolder(requestManager) },\n        errorHandler = errorHandler,\n        maxItemsToPreload = maxPreloadDistance,\n        modelPreloader = preloader\n    ).let {\n        addOnScrollListener(it)\n    }\n}\n\n/**\n * Helper to create and add an [EpoxyPreloader] to this RecyclerView that preloads Glide image requests.\n *\n *\n * @param maxPreloadDistance How many items to prefetch ahead of the last bound item\n * @param errorHandler Called when the preloader encounters an exception. By default this throws only\n * if the app is not in a debuggable model\n * @param preloader Describes how Glide should preload images for the EpoxyModel. Use [glidePreloader]\n * to easily create this.\n */\nfun <T : EpoxyModel<*>, U : ViewMetadata?> EpoxyRecyclerView.addGlidePreloader(\n    requestManager: RequestManager,\n    maxPreloadDistance: Int = 3,\n    errorHandler: PreloadErrorHandler = { context, err -> if (!context.isDebuggable) throw err },\n    preloader: EpoxyModelPreloader<T, U, GlidePreloadRequestHolder>\n) {\n    addPreloader(\n        maxPreloadDistance = maxPreloadDistance,\n        errorHandler = errorHandler,\n        preloader = preloader,\n        requestHolderFactory = { GlidePreloadRequestHolder(requestManager) }\n    )\n}\n\n/**\n * Creates a [EpoxyModelPreloader] using [GlidePreloadRequestHolder] as the request holder.\n * This allows your Glide preload request to be automatically managed for you.\n *\n * This is similar to the other [glidePreloader], but with default viewMetadata\n */\ninline fun <reified T : EpoxyModel<*>> glidePreloader(\n    preloadableViewIds: List<Int> = emptyList(),\n    noinline viewSignature: (T) -> Any? = { _ -> null },\n    noinline buildRequest: (RequestManager, epoxyModel: T, ViewData<ViewMetadata?>) -> RequestBuilder<out Any>\n): EpoxyModelPreloader<T, ViewMetadata?, GlidePreloadRequestHolder> {\n    return glidePreloader(\n        preloadableViewIds,\n        { ViewMetadata.getDefault(it) },\n        viewSignature,\n        buildRequest\n    )\n}\n\n/**\n * Creates a [EpoxyModelPreloader] using [GlidePreloadRequestHolder] as the request holder.\n * This allows your Glide preload request to be automatically managed for you.\n *\n * @param preloadableViewIds see [EpoxyModelPreloader.preloadableViewIds]\n * @param viewMetadata see [EpoxyModelPreloader.buildViewMetadata]\n * @param viewSignature see [EpoxyModelPreloader.viewSignature]\n * @param buildRequest Create and return a new Glide request to prefetch images for the given model\n * and using the given [RequestManager]\n */\ninline fun <reified T : EpoxyModel<*>, U : ViewMetadata?> glidePreloader(\n    preloadableViewIds: List<Int> = emptyList(),\n    noinline viewMetadata: (View) -> U,\n    noinline viewSignature: (T) -> Any? = { _ -> null },\n    noinline buildRequest: (RequestManager, epoxyModel: T, ViewData<U>) -> RequestBuilder<out Any>\n): EpoxyModelPreloader<T, U, GlidePreloadRequestHolder> {\n    return EpoxyModelPreloader.with(\n        preloadableViewIds = preloadableViewIds,\n        viewMetadata = viewMetadata,\n        viewSignature = viewSignature,\n        doPreload = { model: T, target: GlidePreloadRequestHolder, viewData ->\n            target.startRequest(viewData) { requestManager ->\n                buildRequest(requestManager, model, viewData)\n            }\n        }\n    )\n}\n\ninternal val Context.isDebuggable: Boolean get() = (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0\n"
  },
  {
    "path": "epoxy-glide-preloader/src/main/java/com/airbnb/epoxy/GlidePreloadRequestHolder.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.os.Handler\nimport android.os.Looper\nimport android.widget.ImageView\nimport com.airbnb.epoxy.preload.ImageViewMetadata\nimport com.airbnb.epoxy.preload.PreloadRequestHolder\nimport com.airbnb.epoxy.preload.ViewData\nimport com.airbnb.epoxy.preload.ViewMetadata\nimport com.bumptech.glide.RequestBuilder\nimport com.bumptech.glide.RequestManager\nimport com.bumptech.glide.request.target.BaseTarget\nimport com.bumptech.glide.request.target.SizeReadyCallback\nimport com.bumptech.glide.request.transition.Transition\nimport com.bumptech.glide.util.Util\n\n/**\n * This class handles preloading a Glide request.\n * To use, call [startRequest] and provide your Glide request.\n *\n * @property requestManager The requestmanager that requests will be created with.\n */\nopen class GlidePreloadRequestHolder(\n    private val requestManager: RequestManager\n) : BaseTarget<Any>(), PreloadRequestHolder {\n    private var width: Int = 0\n    private var height: Int = 0\n\n    override fun getSize(cb: SizeReadyCallback) {\n        if (!Util.isValidDimensions(width, height)) {\n            error(\n                \"Width and height must both be > 0 or Target#SIZE_ORIGINAL, but given\" + \" width: \" +\n                    width + \" and height: \" + height + \", either provide dimensions in the constructor\" +\n                    \" or call override()\"\n            )\n        }\n        cb.onSizeReady(width, height)\n    }\n\n    override fun onResourceReady(resource: Any, transition: Transition<in Any>?) {\n        // Requests cannot be cleared in this callback (throws an exception)\n        // so we have to post it.\n        mainThreadHandler.postAtTime({ clear() }, this, 0)\n    }\n\n    /**\n     * Call this to create and execute your preload request.\n     *\n     * @param viewData Pass this so we know what size to downscale the image to. If its metadata\n     * is [ImageViewMetadata] then a scaleType transform will also be applied automatically (The same\n     * one as Glide's RequestManager applies when loading a request into an ImageView) (this is only\n     * (done if no previous transformation was already applied, and not if transformations are disabled)\n     *\n     * @param requestBuilder Use this lambda to create and return your request. The receiver is the\n     * [RequestManager] you should use to create the request.\n     *\n     */\n    open fun <U : ViewMetadata?> startRequest(\n        viewData: ViewData<U>,\n        requestBuilder: (RequestManager) -> RequestBuilder<out Any>\n    ) {\n        width = viewData.width\n        height = viewData.height\n\n        // Cancel any previous attempts to clear the target that may still be queued\n        mainThreadHandler.removeCallbacksAndMessages(this)\n\n        @Suppress(\"UNCHECKED_CAST\")\n        (requestBuilder(requestManager) as RequestBuilder<Any>)\n            .addTransformationForScaleTypeIfPossible(viewData)\n            .into(this)\n    }\n\n    /**\n     * Adds a transformation to scale the image for its scaleType if the given viewData\n     * is [ImageViewMetadata] and no transformation has yet been set.\n     *\n     * This is taken from RequestBuilder#into(ImageView).\n     */\n    protected fun RequestBuilder<Any>.addTransformationForScaleTypeIfPossible(\n        viewData: ViewData<*>\n    ): RequestBuilder<Any> {\n\n        val scaleType = (viewData.metadata as? ImageViewMetadata)?.scaleType ?: return this\n\n        if (isTransformationSet || !isTransformationAllowed) {\n            return this\n        }\n\n        // This clones the request options\n        // so we need to make sure to return the new object.\n        return when (scaleType) {\n            ImageView.ScaleType.CENTER_CROP -> clone().optionalCenterCrop()\n            ImageView.ScaleType.CENTER_INSIDE -> clone().optionalCenterInside()\n            ImageView.ScaleType.FIT_CENTER,\n            ImageView.ScaleType.FIT_START,\n            ImageView.ScaleType.FIT_END -> clone().optionalFitCenter()\n            ImageView.ScaleType.FIT_XY -> clone().optionalCenterInside()\n            else -> {\n                this\n            }\n        }\n    }\n\n    override fun clear() {\n        width = 0\n        height = 0\n        requestManager.clear(this)\n    }\n\n    override fun removeCallback(cb: SizeReadyCallback) {\n        // N/A\n    }\n\n    companion object {\n        protected val mainThreadHandler = Handler(Looper.getMainLooper())\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-integrationtest/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.integrationtest'\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.integrationtest\"\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    vectorDrawables.useSupportLibrary = true\n    versionCode 1\n    versionName \"1.0\"\n  }\n\n  dataBinding {\n    enabled = true\n  }\n\n  testOptions {\n    unitTests {\n      includeAndroidResources = true\n      all {\n        jvmArgs(\n            '--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'\n        )\n      }\n    }\n  }\n}\n\nkotlin {\n  jvmToolchain(17)\n}\n\ndependencies {\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidFragmentTesting\n  implementation rootProject.deps.androidPagingComponent\n  implementation rootProject.deps.androidRecyclerView\n  implementation rootProject.deps.lifecycleViewmodel\n  implementation rootProject.deps.lifecycleViewmodelKtx\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n  implementation project(':epoxy-databinding')\n  implementation project(':epoxy-viewbinder')\n\n  kapt project(':epoxy-processor')\n\n  testImplementation rootProject.deps.robolectric\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.mockito\n  testImplementation rootProject.deps.androidTestCore\n  testImplementation rootProject.deps.androidTestExtJunitKtx\n  testImplementation rootProject.deps.androidEspressoCore\n}\n\nrepositories {\n  mavenCentral()\n}\n"
  },
  {
    "path": "epoxy-integrationtest/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/eli_hart/tools/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/Theme.AppCompat.Light\">\n\n        <activity android:name=\".TestActivity\"/>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/AdapterWithFieldAssigned.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class AdapterWithFieldAssigned extends EpoxyController {\n\n  @AutoModel Model_ model1 = new Model_();\n\n  @Override\n  protected void buildModels() {\n    add(model1);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/AdapterWithIdChanged.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class AdapterWithIdChanged extends EpoxyController {\n\n  @AutoModel Model_ model1 = new Model_();\n\n  @Override\n  protected void buildModels() {\n    add(model1.id(23));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/BasicAutoModelsAdapter.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class BasicAutoModelsAdapter extends EpoxyController {\n\n  @AutoModel Model_ model1;\n  @AutoModel Model_ model2;\n\n  @Override\n  protected void buildModels() {\n    add(model1.id(1));\n    add(model2.id(2));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ControllerWithAutoModel.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithAutoModel extends EpoxyController {\n\n  @AutoModel Model_ model;\n\n  @Override\n  protected void buildModels() {\n    add(model);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ControllerWithoutImplicityAdding.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithoutImplicityAdding extends EpoxyController {\n  @AutoModel Model_ model1;\n\n  @Override\n  protected void buildModels() {\n    model1.value(3);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/EpoxyDataBindingConfig.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.EpoxyDataBindingLayouts;\nimport com.airbnb.epoxy.EpoxyDataBindingPattern;\n\n@EpoxyDataBindingPattern(rClass = R.class, layoutPrefix = \"view_holder\")\n@EpoxyDataBindingLayouts({R.layout.model_with_data_binding})\ninterface EpoxyDataBindingConfig {} \n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/KotlinViewWithDefaultParams.kt",
    "content": "package com.airbnb.epoxy.integrationtest\n\nimport android.content.Context\nimport android.view.View\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.TextProp\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_MATCH_HEIGHT)\nclass KotlinViewWithDefaultParams(context: Context) : View(context) {\n\n    @JvmOverloads\n    @ModelProp\n    fun someIntWithDefault(num: Int = IntDefault) {\n        someIntWithDefaultValue = num\n    }\n\n    var someIntWithDefaultValue = 0\n\n    @JvmOverloads\n    @TextProp\n    fun someTextWithDefault(msg: CharSequence = TextDefault) {\n        someTextWithDefaultValue = msg\n    }\n\n    var someTextWithDefaultValue: CharSequence = \"\"\n\n    @JvmOverloads\n    @ModelProp(group = \"group\")\n    fun propInGroupWithDefaultParam(num: Int? = IntGroupDefault) {\n        groupValue = num\n    }\n\n    @ModelProp(group = \"group\")\n    fun otherPropInGroup(num: Int) {\n        groupValue = num\n    }\n\n    // Make sure that overloads with the same function name and param name are distinguished correctly by type\n    @JvmOverloads\n    @ModelProp\n    fun setImage(image: Map<String, Int> = emptyMap()) {\n    }\n\n    @ModelProp\n    fun setImage(image: String) {\n    }\n\n    @ModelProp\n    fun somePropWithoutDefault(num: Int) {\n    }\n\n    var groupValue: Int? = null\n\n    companion object {\n        const val IntDefault = 2\n        const val IntGroupDefault = 3\n        const val TextDefault = \"hello world\"\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/Model.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.widget.TextView;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\n\nimport androidx.annotation.NonNull;\n\n@EpoxyModelClass\npublic abstract class Model extends EpoxyModel<TextView> {\n  @EpoxyAttribute public int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_click_listener;\n  }\n\n  @Override\n  public void bind(@NonNull TextView view) {\n    view.setText(String.valueOf(value));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelChangesDuringBind.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport androidx.annotation.NonNull;\n\npublic class ModelChangesDuringBind extends EpoxyModel<View> {\n  @EpoxyAttribute public int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_click_listener;\n  }\n\n  @Override\n  public void bind(@NonNull View view) {\n    super.bind(view);\n    value = 3;\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelGroupWithAnnotation.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\nimport com.airbnb.epoxy.EpoxyModelGroup;\nimport com.airbnb.epoxy.ModelGroupHolder;\n\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\n\n@EpoxyModelClass\npublic abstract class ModelGroupWithAnnotation extends EpoxyModelGroup {\n  @EpoxyAttribute int backgroundColor;\n\n  public ModelGroupWithAnnotation(List<? extends EpoxyModel<?>> models) {\n    super(R.layout.model_with_click_listener, models);\n  }\n\n  @Override\n  public void bind(@NonNull ModelGroupHolder holder) {\n    super.bind(holder);\n    holder.getRootView().setBackgroundColor(backgroundColor);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelWithCheckedChangeListener.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\nimport android.widget.CompoundButton;\nimport android.widget.CompoundButton.OnCheckedChangeListener;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport androidx.annotation.NonNull;\n\npublic class ModelWithCheckedChangeListener extends EpoxyModel<View> {\n\n  @EpoxyAttribute OnCheckedChangeListener checkedChangeListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_checked_change;\n  }\n\n  @Override\n  public void bind(@NonNull View view) {\n    if (view instanceof CompoundButton) {\n      ((CompoundButton) view).setOnCheckedChangeListener(checkedChangeListener);\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelWithClickListener.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport androidx.annotation.NonNull;\n\npublic class ModelWithClickListener extends EpoxyModel<View> {\n\n  @EpoxyAttribute public View.OnClickListener clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_click_listener;\n  }\n\n  @Override\n  public void bind(@NonNull View view) {\n    view.setOnClickListener(clickListener);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelWithConstructors.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.widget.TextView;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n@EpoxyModelClass\npublic abstract class ModelWithConstructors extends EpoxyModel<TextView> {\n  @EpoxyAttribute public int value;\n\n  public ModelWithConstructors(long id, int value) {\n    super(id);\n    this.value = value;\n  }\n\n  public ModelWithConstructors(int value) {\n    this.value = value;\n  }\n\n  public ModelWithConstructors(long id) {\n    super(id);\n  }\n\n  // Tests that kotlin extension functions\n  public ModelWithConstructors(\n      Collection<String> collection,\n      Iterable<String> iterable,\n      List<String> list,\n      List<? extends String> upperBoundList,\n//      List<? super String> lowerBoundList,!!! Doesn't work, we would need to transform this\n// type to\n// a MutableList\n      List<?> wildCardList,\n      Map<String, String> map,\n      Set<String> set,\n      Boolean boxedBoolean,\n      Byte boxedByte,\n      Short boxedShort,\n      Integer boxedInteger,\n      Long boxedLong,\n      Character boxedCharacter,\n      Float boxedFloat,\n      Double boxedDouble,\n      String[] stringArray,\n      byte[] byteArray,\n      short[] shortArray,\n      char[] charArray,\n      int[] intArray,\n      float[] floatArray,\n      double[] doubleArray,\n      long[] longArray,\n      boolean[] booleanArray,\n      Byte[] boxedByteArray,\n      Short[] boxedShortArray,\n      Character[] boxedCharArray,\n      Integer[] boxedIntArray,\n      Float[] boxedFloatArray,\n      Double[] boxedDoubleArray,\n      Long[] boxedLongArray,\n      Boolean[] boxedBooleanArray,\n      Object objectParam\n  ) {\n\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_click_listener;\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelWithLongClickListener.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport androidx.annotation.NonNull;\n\npublic class ModelWithLongClickListener extends EpoxyModel<View> {\n\n  @EpoxyAttribute View.OnLongClickListener clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return R.layout.model_with_click_listener;\n  }\n\n  @Override\n  public void bind(@NonNull View view) {\n    view.setOnLongClickListener(clickListener);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelWithNoGeneratedClass.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\n// This class isn't used, but tests that a model is not generated for this and the processor and\n// generated code handles this and compiles correctly. A kotlin extension function should not be\n// generated\npublic abstract class ModelWithNoGeneratedClass extends EpoxyModel<View> {\n  @EpoxyAttribute int value;\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ModelsWithCustomTypes.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.view.View;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\n\n/**\n * This tests that the annotation processor looks up the correct bound object type on the model when\n * a subclass defines a new type. In this test the generated model should correctly use TextView as\n * the model type instead of the ImageView type of the subclass.\n */\nclass ModelsWithCustomTypes {\n\n  @EpoxyModelClass\n  abstract static class ModelWithCustomType extends BaseModelWithCustomType<ImageView> {\n\n    public ModelWithCustomType() {\n    }\n\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n  }\n\n  abstract static class BaseModelWithCustomType<U extends View> extends EpoxyModel<TextView> {\n\n    public BaseModelWithCustomType() {\n    }\n\n    public void testMethod(U param) {\n\n    }\n\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/TestActivity.kt",
    "content": "package com.airbnb.epoxy.integrationtest\n\nimport androidx.appcompat.app.AppCompatActivity\n\n/**\n * Empty activity used for view testing.\n */\nclass TestActivity : AppCompatActivity()\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ViewWithAnnotationsForIntegrationTest.java",
    "content": "package com.airbnb.epoxy.integrationtest;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.View;\n\nimport com.airbnb.epoxy.CallbackProp;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\nimport androidx.annotation.Nullable;\n\n@ModelView(defaultLayout = R.layout.view_with_annotations_for_integration_test)\npublic class ViewWithAnnotationsForIntegrationTest extends View {\n  public static final String DEFAULT_STRING = \"hello world\";\n\n  public CharSequence requiredText;\n  public CharSequence nullableText;\n  public CharSequence textWithDefault;\n  public CharSequence nullableTextWithDefault;\n\n  public ViewWithAnnotationsForIntegrationTest(Context context) {\n    super(context);\n  }\n\n  public ViewWithAnnotationsForIntegrationTest(Context context,\n      @Nullable AttributeSet attrs) {\n    super(context, attrs);\n  }\n\n  public ViewWithAnnotationsForIntegrationTest(Context context,\n      @Nullable AttributeSet attrs, int defStyleAttr) {\n    super(context, attrs, defStyleAttr);\n  }\n\n  @ModelProp(options = Option.GenerateStringOverloads)\n  public void setRequiredText(CharSequence text) {\n    this.requiredText = text;\n  }\n\n  @ModelProp(options = Option.GenerateStringOverloads)\n  public void setNullableText(@Nullable CharSequence text) {\n    nullableText = text;\n  }\n\n  @ModelProp(options = Option.GenerateStringOverloads, defaultValue = \"DEFAULT_STRING\")\n  public void setTextWithDefault(CharSequence text) {\n    textWithDefault = text;\n  }\n\n  @ModelProp(options = Option.GenerateStringOverloads, defaultValue = \"DEFAULT_STRING\")\n  public void setNullableTextWithDefault(@Nullable CharSequence text) {\n    nullableTextWithDefault = text;\n  }\n\n  @CallbackProp\n  @Override\n  public void setOnClickListener(@Nullable OnClickListener l) {\n    super.setOnClickListener(l);\n  }\n\n  @ModelProp\n  public void setGroupWithNoDefault(String url) {\n\n  }\n\n  @CallbackProp\n  public void setGroupWithNoDefault(@Nullable OnClickListener url) {\n\n  }\n\n  @ModelProp\n  public void setGroupWithDefault(String url) {\n\n  }\n\n  @CallbackProp\n  public void setGroupWithDefault(@Nullable OnClickListener url) {\n\n  }\n\n  @ModelProp\n  public void setGroupWithDefault(int url) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ViewWithDelegate.kt",
    "content": "package com.airbnb.epoxy.integrationtest\n\nimport android.content.Context\nimport android.view.View\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_MATCH_HEIGHT)\nclass ViewWithDelegate @JvmOverloads constructor(\n    context: Context,\n    implementation: InterfaceImplementation = InterfaceImplementation()\n) : View(context), InterfaceWithModelProp by implementation\n\ninterface InterfaceWithModelProp {\n\n    @set:ModelProp\n    var flag: Boolean\n}\n\nclass InterfaceImplementation : InterfaceWithModelProp {\n\n    override var flag: Boolean = false\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/ViewWithInterface.kt",
    "content": "package com.airbnb.epoxy.integrationtest\n\nimport android.content.Context\nimport android.view.View\nimport androidx.annotation.Nullable\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.ModelView.Size\nimport com.airbnb.epoxy.TextProp\n\n@ModelView(autoLayout = Size.WRAP_WIDTH_MATCH_HEIGHT)\nclass ViewWithInterface(context: Context) :\n    View(context),\n    InterfaceForView,\n    InterfaceForView2,\n    ClassWithNestedInterface.NestedInterface,\n    InterfaceWithNoPropMethods {\n\n    override fun getSomething() = 5\n\n    @ModelProp\n    override fun valueOnNestedInterface(value: Int) {\n    }\n\n    @ModelProp\n    override fun setText(title: CharSequence?) {\n    }\n\n    @TextProp\n    override fun setText2(title: CharSequence?) {\n    }\n\n    @CallbackProp\n    override fun setListener(title: View.OnClickListener?) {\n    }\n\n    @ModelProp\n    fun nonInterfaceProp(title: Int) {\n        // method has different type from method of same name in other view\n    }\n}\n\n@ModelView(autoLayout = Size.WRAP_WIDTH_MATCH_HEIGHT)\nclass ViewWithInterface2(context: Context) : View(context), InterfaceForView, InterfaceForView2 {\n\n    @TextProp\n    override fun setText(@Nullable title: CharSequence?) {\n        // It is intended that this override has the nullable annotation and the other doesn't, to\n        // check that it doesn't affect the interface\n    }\n\n    @TextProp\n    override fun setText2(@Nullable title: CharSequence?) {\n    }\n\n    @CallbackProp\n    override fun setListener(title: View.OnClickListener?) {\n    }\n\n    @ModelProp\n    fun nonInterfaceProp(title: String) {\n    }\n}\n\ninterface InterfaceForView {\n    fun setText(title: CharSequence?)\n    fun setText2(title: CharSequence?)\n}\n\ninterface InterfaceForView2 {\n    fun setListener(title: View.OnClickListener?)\n}\n\ninterface InterfaceWithNoPropMethods {\n    fun getSomething(): Int\n}\n\nclass ClassWithNestedInterface {\n    interface NestedInterface {\n        fun valueOnNestedInterface(value: Int)\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/autoaddautomodels/ControllerWithImplicitlyAddedModels.java",
    "content": "package com.airbnb.epoxy.integrationtest.autoaddautomodels;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\nimport com.airbnb.epoxy.EpoxyModel.AddPredicate;\nimport com.airbnb.epoxy.integrationtest.Model_;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class ControllerWithImplicitlyAddedModels extends EpoxyController {\n  @AutoModel Model_ model1;\n  @AutoModel Model_ model2;\n  @AutoModel Model_ model3;\n  @AutoModel Model_ model4;\n  @AutoModel Model_ model5;\n  @AutoModel Model_ model6;\n  @AutoModel Model_ model7;\n  @AutoModel Model_ model8;\n  @AutoModel Model_ model9;\n\n  private List<Model_> expectedModels;\n\n  @Override\n  protected void buildModels() {\n    expectedModels = new ArrayList<>();\n\n    model1\n        .value(3);\n    expectedModels.add(model1);\n\n    add(model2);\n    expectedModels.add(model2);\n\n    model3\n        .addTo(this);\n    expectedModels.add(model3);\n\n    model4\n        .value(4)\n        .addTo(this);\n    expectedModels.add(model4);\n\n    model5\n        .value(34)\n        .addIf(false, this);\n\n    model6\n        .value(34)\n        .addIf(new AddPredicate() {\n          @Override\n          public boolean addIf() {\n            return false;\n          }\n        }, this);\n\n    model7\n        .addIf(true, this);\n    expectedModels.add(model7);\n\n    model8\n        .value(2)\n        .addIf(true, this);\n    expectedModels.add(model8);\n\n    model9\n        .value(34);\n    expectedModels.add(model9);\n  }\n\n  public List<Model_> getExpectedModels() {\n    return expectedModels;\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/autoaddautomodels/ControllerWithImplicitlyAddedModels2.java",
    "content": "package com.airbnb.epoxy.integrationtest.autoaddautomodels;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\nimport com.airbnb.epoxy.integrationtest.Model_;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class ControllerWithImplicitlyAddedModels2 extends EpoxyController {\n  @AutoModel Model_ model1;\n  @AutoModel Model_ model2;\n  @AutoModel Model_ model3;\n  @AutoModel Model_ model4;\n  @AutoModel Model_ model5;\n  @AutoModel Model_ model6;\n  @AutoModel Model_ model7;\n  @AutoModel Model_ model8;\n  @AutoModel Model_ model9;\n\n  private List<Model_> expectedModels;\n\n  @Override\n  protected void buildModels() {\n    expectedModels = new ArrayList<>();\n\n    add(model1);\n    expectedModels.add(model1);\n\n    add(model2.value(2));\n    expectedModels.add(model2);\n\n    add(model3.value(3));\n    expectedModels.add(model3);\n\n    model4.value(4);\n    expectedModels.add(model4);\n\n    model5.value(5);\n    expectedModels.add(model5);\n\n    model6.addIf(false, this);\n\n    model7.addIf(false, this);\n\n    model8.addIf(true, this);\n    expectedModels.add(model8);\n\n    add(model9);\n    expectedModels.add(model9);\n  }\n\n  public List<Model_> getExpectedModels() {\n    return expectedModels;\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/autoaddautomodels/ControllerWithImplicitlyAddedModels3.java",
    "content": "package com.airbnb.epoxy.integrationtest.autoaddautomodels;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\nimport com.airbnb.epoxy.integrationtest.Model_;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class ControllerWithImplicitlyAddedModels3 extends EpoxyController {\n  @AutoModel Model_ model1;\n  @AutoModel Model_ model2;\n  @AutoModel Model_ model3;\n  @AutoModel Model_ model4;\n\n  private List<Model_> expectedModels;\n\n  @Override\n  protected void buildModels() {\n    expectedModels = new ArrayList<>();\n\n    model1.value(1);\n    expectedModels.add(model1);\n\n    Model_ localModel = new Model_();\n    add(localModel.id(1));\n    expectedModels.add(localModel);\n\n    localModel = new Model_();\n    add(localModel.id(2).value(2));\n    expectedModels.add(localModel);\n\n    model2.value(2);\n    expectedModels.add(model2);\n\n    localModel = new Model_();\n    localModel.id(3).value(3).addTo(this);\n    expectedModels.add(localModel);\n\n    model3.addIf(false, this);\n\n    add(model4);\n    expectedModels.add(model4);\n  }\n\n  public List<Model_> getExpectedModels() {\n    return expectedModels;\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/java/com/airbnb/epoxy/integrationtest/autoaddautomodels/PackageConfig.java",
    "content": "package com.airbnb.epoxy.integrationtest.autoaddautomodels;\n\nimport com.airbnb.epoxy.PackageEpoxyConfig;\n\n@PackageEpoxyConfig(implicitlyAddAutoModels = true)\npublic interface PackageConfig {\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/model_with_checked_change.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<CheckBox xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n</CheckBox>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/model_with_click_listener.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n</TextView>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/model_with_data_binding.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data>\n\n        <variable\n            name=\"stringValue\"\n            type=\"String\" />\n\n        <variable\n            name=\"clickListener\"\n            type=\"android.view.View.OnClickListener\" />\n    </data>\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:text=\"@{stringValue}\" />\n\n</layout>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/vertical_linear_group.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\" />"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/view_holder_databinding_test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data>\n\n        <variable\n            name=\"stringValue\"\n            type=\"String\" />\n\n        <variable\n            name=\"clickListener\"\n            type=\"android.view.View.OnClickListener\" />\n    </data>\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:text=\"@{stringValue}\" />\n\n</layout>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/view_holder_nested_databinding_test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    This layout contains a nested databinding layout which causes the generated ViewDataBinding\n    class to override the \"setLifecycleOwner\" method. Since single parameter methods prefixed with\n    \"set\" are parsed as model properties, this layout and the ensuing generated Epoxy model class\n    act as a test by ensuring the module still builds successfully.\n-->\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\">\n\n        <include layout=\"@layout/view_holder_databinding_test\" />\n\n    </LinearLayout>\n\n</layout>\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/view_holder_no_databinding.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <!-- This layout does nothing, but it tests that the databinding processor skips none databinding layouts that match the naming pattern. -->\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/layout/view_with_annotations_for_integration_test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.integrationtest.ViewWithAnnotationsForIntegrationTest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\" />\n"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/values/plurals.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <plurals name=\"plural_test_string\">\n        <item quantity=\"one\">@string/plural_test_string_one</item>\n    </plurals>\n    <plurals name=\"plural_test_string_with_args\">\n        <item quantity=\"one\">@string/plural_test_string_with_args_one</item>\n    </plurals>\n</resources>"
  },
  {
    "path": "epoxy-integrationtest/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy Integration test</string>\n    <string name=\"string_with_no_args\">String with args</string>\n    <string name=\"string_with_args\">String with args %d</string>\n    <string name=\"plural_test_string_one\">plural test string one</string>\n    <string name=\"plural_test_string_with_args_one\">plural test string with args %d</string>\n</resources>\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/AutoModelIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.integrationtest.AdapterWithFieldAssigned;\nimport com.airbnb.epoxy.integrationtest.AdapterWithIdChanged;\nimport com.airbnb.epoxy.integrationtest.BasicAutoModelsAdapter;\nimport com.airbnb.epoxy.integrationtest.ControllerWithoutImplicityAdding;\nimport com.airbnb.epoxy.integrationtest.Model_;\nimport com.airbnb.epoxy.integrationtest.autoaddautomodels.ControllerWithImplicitlyAddedModels;\nimport com.airbnb.epoxy.integrationtest.autoaddautomodels.ControllerWithImplicitlyAddedModels2;\nimport com.airbnb.epoxy.integrationtest.autoaddautomodels.ControllerWithImplicitlyAddedModels3;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\npublic class AutoModelIntegrationTest {\n\n  @Test\n  public void basicAutoModels() {\n    BasicAutoModelsAdapter controller = new BasicAutoModelsAdapter();\n    controller.requestModelBuild();\n\n    List<EpoxyModel<?>> models = controller.getAdapter().getCopyOfModels();\n\n    assertEquals(\"Models size\", 2, models.size());\n    assertEquals(\"First model\", Model_.class, models.get(0).getClass());\n    assertEquals(\"Second model\", Model_.class, models.get(1).getClass());\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void assigningValueToFieldFails() {\n    AdapterWithFieldAssigned testAdapter = new AdapterWithFieldAssigned();\n    testAdapter.requestModelBuild();\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void assigningIdToAutoModelFails() {\n    AdapterWithIdChanged testAdapter = new AdapterWithIdChanged();\n    testAdapter.requestModelBuild();\n  }\n\n  @Test\n  public void implicitlyAddingAutoModelsDisabledByDefault() {\n    ControllerWithoutImplicityAdding controller = new ControllerWithoutImplicityAdding();\n    controller.requestModelBuild();\n\n    assertEquals(new ArrayList<>(), controller.getAdapter().getCopyOfModels());\n  }\n\n  @Test\n  public void implicitlyAddingAutoModels() {\n    ControllerWithImplicitlyAddedModels controller = new ControllerWithImplicitlyAddedModels();\n    controller.requestModelBuild();\n\n    assertEquals(controller.getExpectedModels(), controller.getAdapter().getCopyOfModels());\n  }\n\n  @Test\n  public void implicitlyAddingAutoModels2() {\n    ControllerWithImplicitlyAddedModels2 controller = new ControllerWithImplicitlyAddedModels2();\n    controller.requestModelBuild();\n\n    assertEquals(controller.getExpectedModels(), controller.getAdapter().getCopyOfModels());\n  }\n\n  @Test\n  public void implicitlyAddingAutoModels3() {\n    ControllerWithImplicitlyAddedModels3 controller = new ControllerWithImplicitlyAddedModels3();\n    controller.requestModelBuild();\n\n    assertEquals(controller.getExpectedModels(), controller.getAdapter().getCopyOfModels());\n  }\n}"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/BindDiffTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport com.airbnb.epoxy.integrationtest.ViewWithAnnotationsForIntegrationTest\nimport com.airbnb.epoxy.integrationtest.ViewWithAnnotationsForIntegrationTestModel_\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.mockito.Mockito.mock\nimport org.mockito.Mockito.verify\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\n\n/** Tests that a partial bind of model (from a diff) binds the correct props. This is particularly tricky with prop groups. */\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\nclass BindDiffTest {\n\n    private inline fun validateDiff(\n        model1Props: ViewWithAnnotationsForIntegrationTestModel_.() -> Unit,\n        model2Props: ViewWithAnnotationsForIntegrationTestModel_.() -> Unit,\n        viewCallVerifications: ViewWithAnnotationsForIntegrationTest.() -> Unit\n    ) {\n        val model1 = ViewWithAnnotationsForIntegrationTestModel_().id(1).apply(model1Props)\n        val model2 = ViewWithAnnotationsForIntegrationTestModel_().id(1).apply(model2Props)\n\n        val viewMock = mock(ViewWithAnnotationsForIntegrationTest::class.java)\n        model2.bind(viewMock, model1)\n\n        verify(viewMock).viewCallVerifications()\n    }\n\n    @Test\n    fun singlePropChanged() {\n        validateDiff(\n            model1Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n                groupWithDefault(\"text\")\n            },\n            model2Props = {\n                requiredText(\"hello2\")\n                groupWithNoDefault(\"text\")\n                groupWithDefault(\"text\")\n            },\n            viewCallVerifications = {\n                setRequiredText(\"hello2\")\n            }\n        )\n    }\n\n    @Test\n    fun multiplePropsChanged() {\n        validateDiff(\n            model1Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n            },\n            model2Props = {\n                requiredText(\"hello2\")\n                groupWithNoDefault(\"text2\")\n            },\n            viewCallVerifications = {\n                setGroupWithNoDefault(\"text2\")\n                setRequiredText(\"hello2\")\n            }\n        )\n    }\n\n    @Test\n    fun propGroupChangedFromOneAttributeToAnother() {\n        val clickListener = View.OnClickListener {}\n        validateDiff(\n            model1Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n            },\n            model2Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(clickListener)\n            },\n            viewCallVerifications = {\n                setGroupWithNoDefault(clickListener)\n            }\n        )\n    }\n\n    @Test\n    fun propGroupChangedToDefault() {\n        validateDiff(\n            model1Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n                groupWithDefault(\"custom value\")\n            },\n            model2Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n            },\n            viewCallVerifications = {\n                setGroupWithDefault(null as View.OnClickListener?)\n            }\n        )\n    }\n\n    @Test\n    fun propGroupChangedFromDefault() {\n        validateDiff(\n            model1Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n            },\n            model2Props = {\n                requiredText(\"hello\")\n                groupWithNoDefault(\"text\")\n                groupWithDefault(\"custom value\")\n            },\n            viewCallVerifications = {\n                setGroupWithDefault(\"custom value\")\n            }\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/BindModelIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.widget.TextView;\n\nimport com.airbnb.epoxy.integrationtest.Model_;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.spy;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class BindModelIntegrationTest {\n\n  private Model_ model;\n\n  class TestAdapter extends BaseEpoxyAdapter {\n\n    private boolean diffPayloadsEnabled;\n    private List<EpoxyModel<?>> models;\n\n    TestAdapter(boolean diffPayloadsEnabled) {\n      this.diffPayloadsEnabled = diffPayloadsEnabled;\n      this.models = new ArrayList<>();\n      models.add(model);\n    }\n\n    @Override\n    List<EpoxyModel<?>> getCurrentModels() {\n      return models;\n    }\n\n    @Override\n    boolean diffPayloadsEnabled() {\n      return diffPayloadsEnabled;\n    }\n  }\n\n  @Before\n  public void before() {\n    model = spy(new Model_()).id(1);\n  }\n\n  @Test\n  public void bindNoPayloads() {\n    TestAdapter adapter = new TestAdapter(false);\n    EpoxyViewHolder viewHolder = ControllerLifecycleHelper.createViewHolder(adapter, 0);\n    adapter.onBindViewHolder(viewHolder, 0);\n\n    verify(model).bind((TextView) viewHolder.itemView);\n    verify(model, never()).bind(any(TextView.class), any(List.class));\n    verify(model, never()).bind(any(TextView.class), any(EpoxyModel.class));\n  }\n\n  @Test\n  public void bindWithPayloads() {\n    TestAdapter adapter = new TestAdapter(false);\n    EpoxyViewHolder viewHolder = ControllerLifecycleHelper.createViewHolder(adapter, 0);\n\n    ArrayList<Object> payloads = new ArrayList<>();\n    payloads.add(\"hello\");\n\n    adapter.onBindViewHolder(viewHolder, 0, payloads);\n\n    verify(model).bind((TextView) viewHolder.itemView, payloads);\n    // This is called if the payloads bind call isn't implemented\n    verify(model).bind(any(TextView.class));\n    verify(model, never()).bind(any(TextView.class), any(EpoxyModel.class));\n  }\n\n  @Test\n  public void bindWithDiffPayload() {\n    TestAdapter adapter = new TestAdapter(true);\n    EpoxyViewHolder viewHolder = ControllerLifecycleHelper.createViewHolder(adapter, 0);\n\n    Model_ originallyBoundModel = new Model_();\n    originallyBoundModel.id(model.id());\n\n    List<Object> payloads = DiffPayloadTestUtil.payloadsWithChangedModels(originallyBoundModel);\n    adapter.onBindViewHolder(viewHolder, 0, payloads);\n\n    verify(model).bind((TextView) viewHolder.itemView, originallyBoundModel);\n    // This is called if the payloads bind call isn't implemented\n    verify(model).bind(any(TextView.class));\n    verify(model, never()).bind(any(TextView.class), any(List.class));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ControllerLifecycleHelper.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport android.widget.FrameLayout\nimport androidx.test.core.app.ApplicationProvider\n\ninternal class ControllerLifecycleHelper {\n    private var viewHolder: EpoxyViewHolder? = null\n    fun buildModelsAndBind(controller: EpoxyController) {\n        controller.requestModelBuild()\n        bindModels(controller)\n    }\n\n    fun bindModels(controller: EpoxyController) {\n        bindModels(controller.adapter)\n    }\n\n    fun bindModels(adapter: BaseEpoxyAdapter) {\n        val models = adapter.currentModels\n        for (i in models.indices) {\n            viewHolder = createViewHolder(adapter, i)\n            adapter.onBindViewHolder(viewHolder!!, i)\n        }\n    }\n\n    fun bindModel(model: EpoxyModel<*>): View {\n        val controller = SimpleEpoxyController()\n        controller.setModels(listOf(model))\n        bindModels(controller)\n        return viewHolder!!.itemView\n    }\n\n    fun recycleLastBoundModel(controller: EpoxyController) {\n        controller.adapter.onViewRecycled(viewHolder!!)\n    }\n\n    companion object {\n        @JvmStatic\n        fun createViewHolder(adapter: BaseEpoxyAdapter, position: Int): EpoxyViewHolder {\n            return adapter.onCreateViewHolder(\n                FrameLayout(ApplicationProvider.getApplicationContext()),\n                adapter.getItemViewType(position)\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/DataBindingModelIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.View.OnClickListener;\nimport android.widget.Button;\n\nimport com.airbnb.epoxy.DataBindingEpoxyModel.DataBindingHolder;\nimport com.airbnb.epoxy.integrationtest.DatabindingTestBindingModel_;\nimport com.airbnb.epoxy.integrationtest.ModelWithDataBindingBindingModel_;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\nimport static junit.framework.Assert.assertNotNull;\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.ArgumentMatchers.eq;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class DataBindingModelIntegrationTest {\n\n  @Test\n  public void createDataBindingModel() {\n    SimpleEpoxyController controller = new SimpleEpoxyController();\n    ModelWithDataBindingBindingModel_ firstModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"hello\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(firstModel));\n\n    ControllerLifecycleHelper lifecycleHelper = new ControllerLifecycleHelper();\n    EpoxyViewHolder viewHolder = lifecycleHelper.createViewHolder(controller.getAdapter(), 0);\n    controller.getAdapter().onBindViewHolder(viewHolder, 0);\n\n    DataBindingHolder dataBindingHolder = ((DataBindingHolder) viewHolder.objectToBind());\n    assertNotNull(dataBindingHolder.getDataBinding());\n\n    // Check that the requiredText was set on the view\n    assertEquals(firstModel.stringValue(), ((Button) viewHolder.itemView).getText());\n\n    ModelWithDataBindingBindingModel_ secondModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"hello again\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(secondModel));\n    List<Object> payloads = DiffPayloadTestUtil.payloadsWithChangedModels(firstModel);\n    controller.getAdapter().onBindViewHolder(viewHolder, 0, payloads);\n\n    // Check that the requiredText was updated after the change payload\n    assertEquals(secondModel.stringValue(), ((Button) viewHolder.itemView).getText());\n  }\n\n  @Test\n  public void fullyCreateDataBindingModel() {\n    SimpleEpoxyController controller = new SimpleEpoxyController();\n    ModelWithDataBindingBindingModel_ firstModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"hello\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(firstModel));\n\n    ControllerLifecycleHelper lifecycleHelper = new ControllerLifecycleHelper();\n    EpoxyViewHolder viewHolder = lifecycleHelper.createViewHolder(controller.getAdapter(), 0);\n    controller.getAdapter().onBindViewHolder(viewHolder, 0);\n\n    DataBindingHolder dataBindingHolder = ((DataBindingHolder) viewHolder.objectToBind());\n    assertNotNull(dataBindingHolder.getDataBinding());\n\n    // Check that the requiredText was set on the view\n    assertEquals(firstModel.stringValue(), ((Button) viewHolder.itemView).getText());\n\n    ModelWithDataBindingBindingModel_ secondModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"hello again\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(secondModel));\n    List<Object> payloads = DiffPayloadTestUtil.payloadsWithChangedModels(firstModel);\n    controller.getAdapter().onBindViewHolder(viewHolder, 0, payloads);\n\n    // Check that the requiredText was updated after the change payload\n    assertEquals(secondModel.stringValue(), ((Button) viewHolder.itemView).getText());\n  }\n\n  @Test\n  public void typesWithOutHashCodeAreNotDiffed() {\n    SimpleEpoxyController controller = new SimpleEpoxyController();\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithDataBindingBindingModel_ firstModel = new ModelWithDataBindingBindingModel_()\n        .clickListener(new OnClickListener() {\n          @Override\n          public void onClick(View v) {\n\n          }\n        })\n        .id(1);\n\n    controller.setModels(Collections.singletonList(firstModel));\n    verify(observerMock).onItemRangeInserted(0, 1);\n\n    ModelWithDataBindingBindingModel_ secondModel = new ModelWithDataBindingBindingModel_()\n        .clickListener(new OnClickListener() {\n          @Override\n          public void onClick(View v) {\n\n          }\n        })\n        .id(1);\n\n    controller.setModels(Collections.singletonList(secondModel));\n    verifyNoMoreInteractions(observerMock);\n  }\n\n  @Test\n  public void typesWithHashCodeAreDiffed() {\n    SimpleEpoxyController controller = new SimpleEpoxyController();\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithDataBindingBindingModel_ firstModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"value1\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(firstModel));\n    verify(observerMock).onItemRangeInserted(0, 1);\n\n    ModelWithDataBindingBindingModel_ secondModel = new ModelWithDataBindingBindingModel_()\n        .stringValue(\"value2\")\n        .id(1);\n\n    controller.setModels(Collections.singletonList(secondModel));\n    verify(observerMock).onItemRangeChanged(eq(0), eq(1), any());\n    verifyNoMoreInteractions(observerMock);\n  }\n\n  @Test\n  public void generatesBindingModelFromNamingPattern() {\n    // Make sure that the model was generated from the annotation naming pattern\n    new DatabindingTestBindingModel_();\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/DiffPayloadTestUtil.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nclass DiffPayloadTestUtil {\n\n  static DiffPayload diffPayloadWithModels(EpoxyModel<?>... models) {\n    List<EpoxyModel<?>> epoxyModels = Arrays.asList(models);\n    return new DiffPayload(epoxyModels);\n  }\n\n  static List<Object> payloadsWithDiffPayloads(DiffPayload... diffPayloads) {\n    List<DiffPayload> payloads = Arrays.asList(diffPayloads);\n    return new ArrayList<Object>(payloads);\n  }\n\n  static List<Object> payloadsWithChangedModels(EpoxyModel<?>... models) {\n    return payloadsWithDiffPayloads(diffPayloadWithModels(models));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyAdapterIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.integrationtest.Model;\nimport com.airbnb.epoxy.integrationtest.Model_;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\n\nimport static org.junit.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\npublic class EpoxyAdapterIntegrationTest {\n\n  private ControllerLifecycleHelper lifecycleHelper = new ControllerLifecycleHelper();\n  private final SimpleEpoxyAdapter adapter = new SimpleEpoxyAdapter();\n\n  @Test\n  public void returnModelViewType() {\n    Model testModel = new Model_();\n    adapter.addModel(testModel);\n    int itemViewType = adapter.getItemViewType(0);\n\n    assertEquals(testModel.getViewType(), itemViewType);\n  }\n\n  @Test\n  public void returnHiddenModelViewType() {\n    Model testModel = new Model_();\n    testModel.hide();\n    adapter.addModel(testModel);\n    int itemViewType = adapter.getItemViewType(0);\n\n    assertEquals(new HiddenEpoxyModel().getViewType(), itemViewType);\n  }\n\n  @Test\n  public void bindHiddenModel() {\n    Model testModel = new Model_();\n    testModel.hide();\n    adapter.addModel(testModel);\n\n    lifecycleHelper.bindModels(adapter);\n  }\n\n  @Test\n  public void bindNormalModel() {\n    Model testModel = new Model_();\n    adapter.addModel(testModel);\n\n    lifecycleHelper.bindModels(adapter);\n  }\n}"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyModelGroupRecyclingTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.os.Looper\nimport android.widget.FrameLayout\nimport android.widget.FrameLayout.LayoutParams\nimport androidx.test.ext.junit.rules.activityScenarioRule\nimport androidx.test.runner.AndroidJUnit4\nimport com.airbnb.epoxy.integrationtest.R\nimport com.airbnb.epoxy.integrationtest.TestActivity\nimport org.junit.Assert\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.Shadows\nimport org.robolectric.annotation.Config\n\n/**\n * Tests view pool of [EpoxyModelGroup] within [EpoxyRecyclerView].\n */\n@Config(sdk = [21], qualifiers = \"h831dp-mdpi\")\n@RunWith(AndroidJUnit4::class)\nclass EpoxyModelGroupRecyclingTest {\n\n    @get:Rule\n    var activityRule = activityScenarioRule<TestActivity>()\n\n    private lateinit var recyclerView1: EpoxyRecyclerView\n\n    private lateinit var recyclerView2: EpoxyRecyclerView\n\n    /**\n     * Verify that the groups inherit of the view pool configuration from the parent recycler view.\n     * Pool is shared within the context.\n     */\n    @Test\n    fun testModelGroupPool_shared() {\n\n        setupRecyclerView(shareViewPoolAcrossContext = true)\n        Assert.assertSame(recyclerView1.recycledViewPool, recyclerView2.recycledViewPool)\n\n        var modelsBound = 0\n        val assertOnModelBound: (EpoxyModelGroup, ModelGroupHolder, Int) -> Unit = { _, view, _ ->\n            modelsBound++\n            Assert.assertSame(recyclerView1.recycledViewPool, view.viewPool)\n        }\n        withModels(\n            buildModels1 = {\n                group {\n                    id(\"1\")\n                    layout(R.layout.vertical_linear_group)\n                    onBind(assertOnModelBound)\n\n                    group {\n                        id(\"1.1\")\n                        layout(R.layout.vertical_linear_group)\n                        onBind(assertOnModelBound)\n                    }\n\n                    group {\n                        id(\"1.1.1\")\n                        layout(R.layout.vertical_linear_group)\n                        onBind(assertOnModelBound)\n                    }\n                }\n            },\n            buildModels2 = {\n                group {\n                    layout(R.layout.vertical_linear_group)\n                    id(\"2\")\n                    onBind(assertOnModelBound)\n                }\n            }\n        )\n        Assert.assertEquals(4, modelsBound)\n    }\n\n    /**\n     * Verify that the groups inherit of the view pool configuration from the parent recycler view.\n     * Pool is not shared within the context.\n     */\n    @Test\n    fun testModelGroupPool_notShared() {\n\n        setupRecyclerView(shareViewPoolAcrossContext = false)\n        Assert.assertNotEquals(recyclerView1.recycledViewPool, recyclerView2.recycledViewPool)\n\n        var modelsBound = 0\n        val assertOnModelBound1: (EpoxyModelGroup, ModelGroupHolder, Int) -> Unit = { _, view, _ ->\n            modelsBound++\n            Assert.assertSame(recyclerView1.recycledViewPool, view.viewPool)\n        }\n        val assertOnModelBound2: (EpoxyModelGroup, ModelGroupHolder, Int) -> Unit = { _, view, _ ->\n            modelsBound++\n            Assert.assertSame(recyclerView2.recycledViewPool, view.viewPool)\n        }\n        withModels(\n            buildModels1 = {\n                group {\n                    id(\"1\")\n                    layout(R.layout.vertical_linear_group)\n                    onBind(assertOnModelBound1)\n\n                    group {\n                        id(\"1.1\")\n                        layout(R.layout.vertical_linear_group)\n                        onBind(assertOnModelBound1)\n\n                        group {\n                            id(\"1.1.1\")\n                            layout(R.layout.vertical_linear_group)\n                            onBind(assertOnModelBound1)\n                        }\n                    }\n                }\n            },\n            buildModels2 = {\n                group {\n                    layout(R.layout.vertical_linear_group)\n                    id(\"2\")\n                    onBind(assertOnModelBound2)\n                }\n            }\n        )\n        Assert.assertEquals(4, modelsBound)\n    }\n\n    /** Sets the models in the [recyclerView1] and [recyclerView2]. */\n    private fun setupRecyclerView(\n        shareViewPoolAcrossContext: Boolean\n    ) {\n        activityRule.scenario.onActivity {\n            if (shareViewPoolAcrossContext) {\n                recyclerView1 = EpoxyRecyclerView(it)\n                recyclerView2 = EpoxyRecyclerView(it)\n            } else {\n                recyclerView1 = NonSharedEpoxyRecyclerView(it)\n                recyclerView2 = NonSharedEpoxyRecyclerView(it)\n            }\n            it.setContentView(\n                FrameLayout(it).apply {\n                    addView(\n                        recyclerView1,\n                        LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)\n                    )\n                    addView(\n                        recyclerView2,\n                        LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)\n                    )\n                }\n            )\n            Shadows.shadowOf(Looper.getMainLooper()).idle()\n        }\n    }\n\n    /** Sets the models in the [recyclerView1] and [recyclerView2]. */\n    private fun withModels(\n        buildModels1: EpoxyController.() -> Unit,\n        buildModels2: EpoxyController.() -> Unit\n    ) {\n        activityRule.scenario.onActivity {\n            recyclerView1.withModels {\n                buildModels1.invoke(this)\n            }\n            recyclerView2.withModels {\n                buildModels2.invoke(this)\n            }\n            Shadows.shadowOf(Looper.getMainLooper()).idle()\n        }\n    }\n\n    private class NonSharedEpoxyRecyclerView(\n        context: Context\n    ) : EpoxyRecyclerView(context) {\n\n        override fun shouldShareViewPoolAcrossContext() = false\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyModelIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyModel.SpanSizeOverrideCallback;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\n\nimport static org.junit.Assert.assertEquals;\n\n@RunWith(RobolectricTestRunner.class)\npublic class EpoxyModelIntegrationTest {\n\n  static class ModelWithSpanCount extends EpoxyModel<View> {\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n\n    @Override\n    public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n      return 6;\n    }\n  }\n\n  @Test\n  public void modelReturnsSpanCount() {\n    ModelWithSpanCount model = new ModelWithSpanCount();\n    assertEquals(6, model.spanSize(0, 0, 0));\n  }\n\n  static class ModelWithSpanCountCallback extends EpoxyModel<View> {\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n  }\n\n  @Test\n  public void modelReturnsSpanCountFromCallback() {\n    ModelWithSpanCountCallback model = new ModelWithSpanCountCallback();\n    model.spanSizeOverride(new SpanSizeOverrideCallback() {\n      @Override\n      public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n        return 7;\n      }\n    });\n\n    assertEquals(7, model.spanSize(0, 0, 0));\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyModelValidationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.EpoxyController.Interceptor;\nimport com.airbnb.epoxy.integrationtest.ControllerWithAutoModel;\nimport com.airbnb.epoxy.integrationtest.Model;\nimport com.airbnb.epoxy.integrationtest.ModelChangesDuringBind_;\nimport com.airbnb.epoxy.integrationtest.Model_;\nimport com.airbnb.epoxy.integrationtest.R;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.ExpectedException;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport java.util.List;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class EpoxyModelValidationTest {\n  @Rule\n  public ExpectedException thrown = ExpectedException.none();\n\n  static class Controller extends EpoxyController {\n\n    @Override\n    protected void buildModels() {\n\n    }\n  }\n\n  @Test\n  public void testModelCannotBeAddedTwice() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"This model was already added to the controller at position 0\");\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        Model model = new Model_().id(1);\n        model.addTo(this);\n        model.addTo(this);\n      }\n    };\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void addToOnlyValidInsideBuildModels() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Can only call this when inside\");\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n      }\n    };\n\n    new Model_()\n        .id(1)\n        .addTo(controller);\n  }\n\n  @Test\n  public void addModelOnlyValidInsideBuildModels() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Can only call this when inside\");\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n      }\n    };\n\n    controller.add(new Model_().id(1));\n  }\n\n  @Test\n  public void cannotCallBuildModelsDirectly() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Can only call this when inside\");\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new Model_()\n            .id(1)\n            .addTo(this);\n      }\n    };\n\n    controller.buildModels();\n  }\n\n  @Test\n  public void mustSpecifyModelIdInController() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"You must set an id on a model\");\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new Model_()\n            .addTo(this);\n      }\n    };\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void hideModelNotAllowedInController() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"You cannot hide a model\");\n\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        new Model_()\n            .id(1)\n            .hide()\n            .addTo(this);\n      }\n    };\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void cannotChangeIdAfterAddingModelToController() {\n    thrown.expect(IllegalEpoxyUsage.class);\n    thrown.expectMessage(\"Cannot change a model's id\");\n\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.id(2);\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_reset() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.reset();\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_bindListener() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model_ model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.onBind(null);\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_unbindListener() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model_ model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.onUnbind(null);\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_setter() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model_ model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.value(2);\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_layout() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.layout(com.airbnb.viewmodeladapter.R.layout.view_holder_empty_view);\n  }\n\n  @Test\n  public void mutationNotAllowedAfterModelIsAdded_hide() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n\n    model.hide();\n  }\n\n  @Test\n  public void mutationAllowedDuringInterceptorCall() {\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        model.reset();\n      }\n    });\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void hashChangeThrows_beforeBind() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final Model model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.requestModelBuild();\n    model.value = 3;\n    new ControllerLifecycleHelper().bindModels(controller);\n  }\n\n  @Test\n  public void hashChangeThrows_duringBind() {\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    final ModelChangesDuringBind_ model =\n        new ModelChangesDuringBind_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    new ControllerLifecycleHelper().buildModelsAndBind(controller);\n  }\n\n  @Test\n  public void hashChangeThrows_beforeNextModelBuild() {\n    // This only works for controllers with AutoModels since only those have generated helpers\n    thrown.expect(ImmutableModelException.class);\n    thrown.expectMessage(\"Epoxy attribute fields on a model cannot be changed\");\n\n    ControllerWithAutoModel controller = new ControllerWithAutoModel();\n\n    controller.requestModelBuild();\n    Model model = (Model) controller.getAdapter().getCopyOfModels().get(0);\n    model.value = 3;\n\n    controller.requestModelBuild();\n  }\n\n  @Test\n  public void hashChangeDuringInterceptorIsAllowed() {\n    final Model_ model = new Model_().id(1);\n    EpoxyController controller = new EpoxyController() {\n\n      @Override\n      protected void buildModels() {\n        add(model);\n      }\n    };\n\n    controller.addInterceptor(new Interceptor() {\n      @Override\n      public void intercept(List<EpoxyModel<?>> models) {\n        model.value(3);\n      }\n    });\n\n    controller.requestModelBuild();\n  }\n}"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyViewBinderIntegrationTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.testing.launchFragmentInContainer\nimport androidx.test.espresso.Espresso.onView\nimport androidx.test.espresso.assertion.ViewAssertions.doesNotExist\nimport androidx.test.espresso.assertion.ViewAssertions.matches\nimport androidx.test.espresso.matcher.ViewMatchers.isDisplayed\nimport androidx.test.espresso.matcher.ViewMatchers.withText\nimport androidx.test.ext.junit.rules.activityScenarioRule\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport com.airbnb.epoxy.integrationtest.TestActivity\nimport com.airbnb.epoxy.integrationtest.model\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertNull\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n@RunWith(AndroidJUnit4::class)\nclass EpoxyViewBinderIntegrationTest {\n\n    @get:Rule\n    var activityRule = activityScenarioRule<TestActivity>()\n\n    @Test\n    fun testActivity() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder.invalidate()\n\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testActivity_optionalBinder() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by it.optionalEpoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder!!.invalidate()\n\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testActivity_optionalBinder_noView() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by it.optionalEpoxyView(\n                View.generateViewId(),\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            assertNull(binder)\n            assertEquals(0, initializedValue)\n        }\n    }\n\n    @Test\n    fun testFragment() {\n        var initializedValue = 0\n        launchFragmentInContainer<TestFragment>().onFragment {\n            val stubId = addViewBinderContainer(it.view as ViewGroup)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder.invalidate()\n\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testFragment_optionalBinder() {\n        var initializedValue = 0\n        launchFragmentInContainer<TestFragment>().onFragment {\n            val stubId = addViewBinderContainer(it.view as ViewGroup)\n\n            val binder by it.optionalEpoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder!!.invalidate()\n\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testFragment_optionalBinder_noView() {\n        var initializedValue = 0\n        launchFragmentInContainer<TestFragment>().onFragment {\n            addViewBinderContainer(it.view as ViewGroup)\n\n            val binder by it.optionalEpoxyView(\n                View.generateViewId(),\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            assertNull(binder)\n            assertEquals(0, initializedValue)\n        }\n    }\n\n    @Test\n    fun testViewGroup() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by frameLayout.epoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder.invalidate()\n\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testViewGroup_optionalBinder() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by frameLayout.optionalEpoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder!!.invalidate()\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    @Test\n    fun testViewGroup_optionalBinder_noView() {\n        var initializedValue = 0\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by frameLayout.optionalEpoxyView(\n                View.generateViewId(),\n                initializer = { initializedValue = 1 },\n                modelProvider = { buildTestBinderModel() }\n            )\n            assertNull(binder)\n            assertEquals(0, initializedValue)\n        }\n    }\n\n    @Test\n    fun testModelUpdated() {\n        var initializedValue = 0\n        var displayedValue = 5\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { ++initializedValue },\n                modelProvider = {\n                    model {\n                        id(1)\n                        value(displayedValue)\n                    }\n                }\n            )\n            binder.invalidate()\n            onView(withText(\"5\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n\n            displayedValue = 10\n            binder.invalidate()\n            onView(withText(\"5\")).check(doesNotExist())\n            onView(withText(\"10\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue) // No change expected\n        }\n    }\n\n    @Test(expected = IllegalStateException::class)\n    fun testNotAnEpoxyViewStub() {\n        EpoxyViewBinder.globalExceptionHandler = { _, exception ->\n            // Reset back to a no-op handler\n            EpoxyViewBinder.globalExceptionHandler = { _, _ -> }\n            throw exception\n        }\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = View.generateViewId()\n            View(it).apply {\n                layoutParams = ViewGroup.LayoutParams(\n                    ViewGroup.LayoutParams.MATCH_PARENT,\n                    ViewGroup.LayoutParams.MATCH_PARENT\n                )\n                id = stubId\n                frameLayout.addView(this)\n            }\n            it.setContentView(frameLayout)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder.invalidate()\n        }\n    }\n\n    @Test\n    fun testNotAnEpoxyViewStub_exceptionSwallowed() {\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = View.generateViewId()\n            View(it).apply {\n                layoutParams = ViewGroup.LayoutParams(\n                    ViewGroup.LayoutParams.MATCH_PARENT,\n                    ViewGroup.LayoutParams.MATCH_PARENT\n                )\n                id = stubId\n                frameLayout.addView(this)\n            }\n            it.setContentView(frameLayout)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { },\n                modelProvider = { buildTestBinderModel() }\n            )\n            binder.invalidate()\n        }\n        // Not setting an exception handler should not cause a crash\n    }\n\n    @Test\n    fun testModelUpdate() {\n        var initializedValue = 0\n        var displayedValue = 5\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it)\n            val stubId = addViewBinderContainer(frameLayout)\n            it.setContentView(frameLayout)\n\n            val binder by it.epoxyView(\n                stubId,\n                initializer = { initializedValue = 1 },\n                modelProvider = {\n                    model {\n                        id(1)\n                        value(displayedValue)\n                    }\n                }\n            )\n            binder.invalidate()\n            displayedValue = 10\n            binder.invalidate()\n\n            onView(withText(\"10\")).check(matches(isDisplayed()))\n            assertEquals(1, initializedValue)\n        }\n    }\n\n    /** Creates and adds a simple model with a text view showing the text \"5\". */\n    private fun ModelCollector.buildTestBinderModel() {\n        model {\n            id(1)\n            value(5)\n        }\n    }\n\n    /** Adds an [EpoxyViewStub] as a child of the [root] and returns the view stub's ID. */\n    private fun addViewBinderContainer(root: ViewGroup): Int {\n        EpoxyViewStub(root.context).apply {\n            layoutParams = ViewGroup.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT,\n                ViewGroup.LayoutParams.MATCH_PARENT\n            )\n            id = View.generateViewId()\n            root.addView(this)\n            return id\n        }\n    }\n\n    /** Simple fragment with a [FrameLayout] for a root view. */\n    class TestFragment : Fragment() {\n\n        override fun onCreateView(\n            inflater: LayoutInflater,\n            container: ViewGroup?,\n            savedInstanceState: Bundle?\n        ): View {\n            return FrameLayout(inflater.context)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyViewBinderVisibilityTrackerTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.os.Looper\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.LinearLayout\nimport android.widget.ScrollView\nimport android.widget.Space\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.test.ext.junit.rules.activityScenarioRule\nimport androidx.test.runner.AndroidJUnit4\nimport com.airbnb.epoxy.integrationtest.R\nimport com.airbnb.epoxy.integrationtest.TestActivity\nimport com.airbnb.epoxy.models.TrackerTestModel\nimport com.airbnb.epoxy.models.trackerTestModel\nimport com.airbnb.epoxy.models.trackerTestModelGroup\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper\nimport org.junit.After\nimport org.junit.Before\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.Shadows.shadowOf\nimport org.robolectric.annotation.Config\nimport kotlin.math.roundToInt\n\n@Config(qualifiers = \"h831dp-mdpi\")\n@RunWith(AndroidJUnit4::class)\nclass EpoxyViewBinderVisibilityTrackerTest {\n\n    @get:Rule\n    var activityRule = activityScenarioRule<TestActivity>()\n\n    private lateinit var linearLayout: LinearLayout\n    private lateinit var scrollView: ScrollView\n    private val scrollViewId = View.generateViewId()\n    private var ids = 0\n\n    @Before\n    fun setUp() {\n        activityRule.scenario.onActivity {\n            linearLayout = LinearLayout(it)\n            linearLayout.orientation = LinearLayout.VERTICAL\n            scrollView = ScrollView(it)\n            scrollView.addView(linearLayout)\n            scrollView.id = scrollViewId\n            it.setContentView(scrollView)\n            shadowOf(Looper.getMainLooper()).idle()\n        }\n    }\n\n    @After\n    fun tearDown() {\n        ids = 0\n    }\n\n    @Test\n    fun testModelInitiallyVisible_full() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            it.withModel(itemHeight) {\n                trackerTestModel(\"model\", itemHeight, helper = helper)\n            }\n\n            helper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelInitiallyVisible_partial() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val spaceHeight = (itemHeight * 1.5).toInt()\n            it.addSpace(spaceHeight)\n            it.withModel(itemHeight) {\n                trackerTestModel(\"model\", itemHeight, helper = helper)\n            }\n\n            helper.assert(\n                visibleHeight = scrollView.measuredHeight - spaceHeight,\n                percentVisibleHeight = (scrollView.measuredHeight - spaceHeight).toFloat() / itemHeight * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelInitiallyVisible_partial_scrolledToBottom() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val spaceHeight = (itemHeight * 1.5).toInt()\n            it.addSpace(spaceHeight)\n            it.withModel(itemHeight) {\n                trackerTestModel(\"model\", itemHeight, helper = helper)\n            }\n\n            scrollView.scrollTo(0, spaceHeight - itemHeight)\n            shadowOf(Looper.getMainLooper()).idle()\n\n            // The binder currently doesn't get updates when scrolled so visibility remains the same prior to scrolling\n            helper.assert(\n                visibleHeight = scrollView.measuredHeight - spaceHeight,\n                percentVisibleHeight = (scrollView.measuredHeight - spaceHeight).toFloat() / itemHeight * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelRemoved() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            var addModel = true\n            val binder = it.withModel(itemHeight) {\n                if (addModel) {\n                    trackerTestModel(\"model\", itemHeight, helper = helper)\n                }\n            }\n\n            addModel = false\n            helper.reset()\n            binder.invalidate()\n            shadowOf(Looper.getMainLooper()).idle()\n\n            helper.assert(\n                visibleHeight = 0,\n                percentVisibleHeight = 0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.INVISIBLE,\n                    VisibilityState.UNFOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelAdded() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 3\n            var addModel = false\n            val binder = it.withModel(itemHeight) {\n                if (addModel) {\n                    trackerTestModel(\"model\", itemHeight, helper = helper)\n                }\n            }\n\n            addModel = true\n            binder.invalidate()\n            shadowOf(Looper.getMainLooper()).idle()\n\n            helper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelReplaced_notSupported() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val replacementHelper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 3\n            var useReplacement = false\n            val binder = it.withModel(itemHeight) {\n                if (useReplacement) {\n                    trackerTestModel(\"replacementModel\", itemHeight, helper = replacementHelper)\n                } else {\n                    trackerTestModel(\"model\", itemHeight, helper = helper)\n                }\n            }\n\n            useReplacement = true\n            helper.reset()\n            binder.invalidate()\n            shadowOf(Looper.getMainLooper()).idle()\n\n            // Replacement of models that use the same view are not currently supported so there should be no changes\n            helper.assertDefault()\n            replacementHelper.assertDefault()\n        }\n    }\n\n    @Test\n    fun testModelReplaced_differentModel() {\n        activityRule.scenario.onActivity {\n            val helper = nextAssertHelper()\n            val replacementGroupHelper = nextAssertHelper()\n            val replacementNestedHelper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 3\n            var useReplacement = false\n            val binder = it.withModel(itemHeight) {\n                if (useReplacement) {\n                    trackerTestModelGroup(\"group\", replacementGroupHelper) {\n                        layout(R.layout.view_holder_no_databinding)\n                        setModels(\n                            TrackerTestModel(\n                                \"innerModel\",\n                                itemHeight,\n                                helper = replacementNestedHelper\n                            )\n                        )\n                    }\n                } else {\n                    trackerTestModel(\"model\", itemHeight, helper = helper)\n                }\n            }\n\n            useReplacement = true\n            helper.reset()\n            binder.invalidate()\n            shadowOf(Looper.getMainLooper()).idle()\n\n            // Replacement of new models is only partially supported. The old model will not receive events but the new\n            // one will.\n            helper.assertDefault()\n\n            replacementGroupHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n            replacementNestedHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelGroup() {\n        activityRule.scenario.onActivity {\n            val groupHelper = nextAssertHelper()\n            val nestedHelper = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            it.withModel(itemHeight) {\n                trackerTestModelGroup(\"group\", groupHelper) {\n                    layout(R.layout.view_holder_no_databinding)\n                    setModels(\n                        TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper)\n                    )\n                }\n            }\n\n            groupHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n            nestedHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testModelGroup_withCarousel() {\n        activityRule.scenario.onActivity {\n            val groupHelper = nextAssertHelper()\n            val helper1 = nextAssertHelper()\n            val helper2 = nextAssertHelper()\n            val helper3 = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val itemWidth = (scrollView.measuredWidth / 1.5).roundToInt()\n            it.withModel(itemHeight) {\n                trackerTestModelGroup(\"group\", groupHelper) {\n                    layout(R.layout.view_holder_no_databinding)\n                    setModels(\n                        CarouselModel_().apply {\n                            id(\"carousel\")\n                            paddingDp(0)\n                            models(\n                                listOf(\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper1\n                                    ),\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper2\n                                    ),\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper3\n                                    )\n                                )\n                            )\n                        }\n                    )\n                }\n            }\n\n            groupHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n\n            helper1.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n\n            helper2.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth / 2,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = (scrollView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n\n            helper3.assertDefault()\n        }\n    }\n\n    @Test\n    fun testModelGroup_withCarousel_scrolledToEnd() {\n        activityRule.scenario.onActivity {\n            val groupHelper = nextAssertHelper()\n            val helper1 = nextAssertHelper()\n            val helper2 = nextAssertHelper()\n            val helper3 = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val itemWidth = (scrollView.measuredWidth / 1.5).roundToInt()\n            val binder = it.withModel(itemHeight) {\n                trackerTestModelGroup(\"group\", groupHelper) {\n                    layout(R.layout.view_holder_no_databinding)\n                    setModels(\n                        CarouselModel_().apply {\n                            id(\"carousel\")\n                            paddingDp(0)\n                            models(\n                                listOf(\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper1\n                                    ),\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper2\n                                    ),\n                                    TrackerTestModel(\n                                        \"carouselItem1\",\n                                        itemHeight = itemHeight,\n                                        itemWidth = itemWidth,\n                                        helper = helper3\n                                    )\n                                )\n                            )\n                        }\n                    )\n                }\n            }\n\n            // Scroll so last carousel model is fully visible\n            ((binder.view as ViewGroup).getChildAt(0) as RecyclerView)\n                .layoutManager!!\n                .scrollToPosition(2)\n            shadowOf(Looper.getMainLooper()).idle()\n\n            groupHelper.assert(\n                visibleHeight = itemHeight,\n                percentVisibleHeight = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n\n            helper1.assert(\n                visibleHeight = 0,\n                visibleWidth = 0,\n                percentVisibleHeight = 0f,\n                percentVisibleWidth = 0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE,\n                    VisibilityState.INVISIBLE,\n                    VisibilityState.UNFOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\n                )\n            )\n\n            helper2.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth / 2,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = (scrollView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n\n            helper3.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    @Test\n    fun testCarousel() {\n        activityRule.scenario.onActivity {\n            val helper1 = nextAssertHelper()\n            val helper2 = nextAssertHelper()\n            val helper3 = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val itemWidth = (scrollView.measuredWidth / 1.5).roundToInt()\n            it.withModel(itemHeight) {\n                add(\n                    CarouselModel_().apply {\n                        id(\"carousel\")\n                        paddingDp(0)\n                        models(\n                            listOf(\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper1\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper2\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper3\n                                )\n                            )\n                        )\n                    }\n                )\n            }\n\n            helper1.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n\n            helper2.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth / 2,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = (scrollView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n\n            helper3.assertDefault()\n        }\n    }\n\n    @Test\n    fun testCarousel_scrolledToEnd() {\n        activityRule.scenario.onActivity {\n            val helper1 = nextAssertHelper()\n            val helper2 = nextAssertHelper()\n            val helper3 = nextAssertHelper()\n            val itemHeight = scrollView.measuredHeight / 2\n            val itemWidth = (scrollView.measuredWidth / 1.5).roundToInt()\n            val binder = it.withModel(itemHeight) {\n                add(\n                    CarouselModel_().apply {\n                        id(\"carousel\")\n                        paddingDp(0)\n                        models(\n                            listOf(\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper1\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper2\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper3\n                                )\n                            )\n                        )\n                    }\n                )\n            }\n\n            // Scroll so last carousel model is fully visible\n            (binder.view as RecyclerView).layoutManager!!.scrollToPosition(2)\n            shadowOf(Looper.getMainLooper()).idle()\n\n            helper1.assert(\n                visibleHeight = 0,\n                visibleWidth = 0,\n                percentVisibleHeight = 0f,\n                percentVisibleWidth = 0f,\n                visible = false,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE,\n                    VisibilityState.INVISIBLE,\n                    VisibilityState.UNFOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\n                )\n            )\n\n            helper2.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth / 2,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = (scrollView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n                visible = true,\n                partialImpression = false,\n                fullImpression = false,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE\n                )\n            )\n\n            helper3.assert(\n                visibleHeight = itemHeight,\n                visibleWidth = itemWidth,\n                percentVisibleHeight = 100f,\n                percentVisibleWidth = 100f,\n                visible = true,\n                partialImpression = true,\n                fullImpression = true,\n                visitedStates = intArrayOf(\n                    VisibilityState.VISIBLE,\n                    VisibilityState.FOCUSED_VISIBLE,\n                    VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                    VisibilityState.FULL_IMPRESSION_VISIBLE\n                )\n            )\n        }\n    }\n\n    /**\n     * Set up an [EpoxyViewBinder] and add models to it. Do not call this multiple times in a test as it will re-set up\n     * the view binder, not make incremental changes. If incremental changes are needed, add logic to the\n     * [modelProvider].\n     *\n     * @see [LifecycleAwareEpoxyViewBinder]\n     *\n     * @param stubHeight the height to use for the view binder's stub. This will inherently be used for the populated\n     * model's height per [EpoxyViewBinder] logic.\n     * @param modelProvider the provider block used for the [EpoxyViewBinder]\n     */\n    private fun TestActivity.withModel(\n        stubHeight: Int,\n        modelProvider: ModelCollector.(Context) -> Unit\n    ): LifecycleAwareEpoxyViewBinder {\n        val viewBinderContainer = EpoxyViewStub(this)\n        viewBinderContainer.layoutParams =\n            ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, stubHeight)\n        viewBinderContainer.id = View.generateViewId()\n        linearLayout.addView(viewBinderContainer)\n\n        val binder by epoxyView(\n            viewBinderContainer.id,\n            useVisibilityTracking = true,\n            modelProvider = { modelProvider(this@withModel) }\n        )\n\n        binder.invalidate()\n        shadowOf(Looper.getMainLooper()).idle()\n        return binder\n    }\n\n    /**\n     * Adds an empty view of the desired height to the linear layout in the fragment. Useful for testing partial\n     * visibility.\n     */\n    private fun TestActivity.addSpace(height: Int) {\n        val spaceView = Space(this)\n        spaceView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height)\n        linearLayout.addView(spaceView)\n    }\n\n    /** Get a [VisibilityAssertHelper] using an auto-incrementing ID. */\n    private fun nextAssertHelper() = VisibilityAssertHelper(ids++)\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyVisibilityItemTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.view.View\nimport android.widget.FrameLayout\nimport androidx.test.ext.junit.rules.activityScenarioRule\nimport androidx.test.runner.AndroidJUnit4\nimport com.airbnb.epoxy.integrationtest.TestActivity\nimport org.junit.Assert.assertFalse\nimport org.junit.Assert.assertTrue\nimport org.junit.Before\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.mockito.ArgumentMatchers.eq\nimport org.mockito.Mock\nimport org.mockito.Mockito.verify\nimport org.mockito.Mockito.verifyNoInteractions\nimport org.mockito.Mockito.verifyNoMoreInteractions\nimport org.mockito.MockitoAnnotations\nimport org.robolectric.annotation.LooperMode\n\n@RunWith(AndroidJUnit4::class)\n@LooperMode(LooperMode.Mode.LEGACY)\nclass EpoxyVisibilityItemTest {\n\n    @get:Rule\n    var activityRule = activityScenarioRule<TestActivity>()\n\n    @Mock\n    lateinit var mockEpoxyHolder: EpoxyViewHolder\n\n    @Before\n    fun setUp() {\n        MockitoAnnotations.openMocks(this)\n    }\n\n    @Test\n    fun testUpdate() {\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it).apply {\n                it.setContentView(this)\n            }\n            val view = View(frameLayout.context).apply {\n                layoutParams = FrameLayout.LayoutParams(100, 100)\n                frameLayout.addView(this)\n            }\n\n            val item = EpoxyVisibilityItem()\n            val measured = item.update(view, frameLayout, false)\n            assertTrue(measured)\n        }\n    }\n\n    @Test\n    fun testUpdate_visibilityGone() {\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it).apply {\n                it.setContentView(this)\n            }\n            val view = View(frameLayout.context).apply {\n                visibility = View.GONE\n                layoutParams = FrameLayout.LayoutParams(100, 100)\n                frameLayout.addView(this)\n            }\n\n            val item = EpoxyVisibilityItem()\n            val measured = item.update(view, frameLayout, false)\n            assertFalse(measured)\n        }\n    }\n\n    @Test\n    fun testUpdate_visibilityInvisible() {\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it).apply {\n                it.setContentView(this)\n            }\n            val view = View(frameLayout.context).apply {\n                visibility = View.INVISIBLE\n                layoutParams = FrameLayout.LayoutParams(100, 100)\n                frameLayout.addView(this)\n            }\n\n            val item = EpoxyVisibilityItem()\n            val measured = item.update(view, frameLayout, false)\n            assertTrue(measured)\n        }\n    }\n\n    @Test\n    fun testUpdate_noSize() {\n        activityRule.scenario.onActivity {\n            val frameLayout = FrameLayout(it).apply {\n                it.setContentView(this)\n            }\n            val view = View(frameLayout.context).apply {\n                layoutParams = FrameLayout.LayoutParams(0, 0)\n                frameLayout.addView(this)\n            }\n\n            val item = EpoxyVisibilityItem()\n            val measured = item.update(view, frameLayout, false)\n            assertFalse(measured)\n        }\n    }\n\n    @Test\n    fun testHandleVisible() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleVisible(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.VISIBLE))\n        }\n    }\n\n    @Test\n    fun testHandleVisible_subsequentCall() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleVisible(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.VISIBLE))\n            item.handleVisible(mockEpoxyHolder, false)\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleVisible_viewInitiallyGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPreViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleVisible(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleVisible_viewTransitionToGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleVisible(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFocus() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleFocus(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.FOCUSED_VISIBLE))\n        }\n    }\n\n    @Test\n    fun testHandleFocus_subsequentCall() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleFocus(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.FOCUSED_VISIBLE))\n            item.handleFocus(mockEpoxyHolder, false)\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFocus_viewInitiallyGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPreViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleFocus(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFocus_viewTransitionToGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleFocus(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandlePartialImpressionVisible() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handlePartialImpressionVisible(mockEpoxyHolder, false, 50)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.PARTIAL_IMPRESSION_VISIBLE))\n        }\n    }\n\n    @Test\n    fun testHandlePartialImpressionVisible_subsequentCall() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handlePartialImpressionVisible(mockEpoxyHolder, false, 50)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.PARTIAL_IMPRESSION_VISIBLE))\n            item.handlePartialImpressionVisible(mockEpoxyHolder, false, 50)\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandlePartialImpressionVisible_viewInitiallyGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPreViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handlePartialImpressionVisible(mockEpoxyHolder, false, 100)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandlePartialImpressionVisible_viewTransitionToGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handlePartialImpressionVisible(mockEpoxyHolder, false, 100)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFullImpressionVisible() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleFullImpressionVisible(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.FULL_IMPRESSION_VISIBLE))\n        }\n    }\n\n    @Test\n    fun testHandleFullImpressionVisible_subsequentCall() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleFullImpressionVisible(mockEpoxyHolder, false)\n            verify(mockEpoxyHolder).visibilityStateChanged(eq(VisibilityState.FULL_IMPRESSION_VISIBLE))\n            item.handleFullImpressionVisible(mockEpoxyHolder, false)\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFullImpressionVisible_viewInitiallyGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPreViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleFullImpressionVisible(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleFullImpressionVisible_viewTransitionToGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleFullImpressionVisible(mockEpoxyHolder, false)\n            verifyNoInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleChanged() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(100f), eq(100f), eq(100), eq(100))\n        }\n    }\n\n    @Test\n    fun testHandleChanged_subsequentCall() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate()\n\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(100f), eq(100f), eq(100), eq(100))\n            item.handleChanged(mockEpoxyHolder, true)\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    @Test\n    fun testHandleChanged_viewInitiallyGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPreViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(0f), eq(0f), eq(0), eq(0))\n        }\n    }\n\n    @Test\n    fun testHandleChanged_viewTransitionToGone() {\n        activityRule.scenario.onActivity {\n            val item = it.createViewAndUpdate(\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(0f), eq(0f), eq(0), eq(0))\n        }\n    }\n\n    @Test\n    fun testHandleChanged_goneTransitionsToVisible() {\n        activityRule.scenario.onActivity {\n            val wrapper = EpoxyVisibilityItemWrapper(\n                activity = it,\n                onPostViewAdded = { view ->\n                    view.visibility = View.GONE\n                }\n            )\n            val item = wrapper.item\n\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(0f), eq(0f), eq(0), eq(0))\n\n            // Change visibility and update the item\n            wrapper.view.visibility = View.VISIBLE\n            item.update(wrapper.view, wrapper.rootLayout, false)\n\n            // Ensure holder is is notified\n            item.handleChanged(mockEpoxyHolder, true)\n            verify(mockEpoxyHolder).visibilityChanged(eq(100f), eq(100f), eq(100), eq(100))\n            verifyNoMoreInteractions(mockEpoxyHolder)\n        }\n    }\n\n    /**\n     * This class wraps an [EpoxyVisibilityItem] and contains references to the views needed to\n     * perform subsequent [EpoxyVisibilityItem.update] calls. This will:\n     * * Create a [FrameLayout] and set it as the content view in the activity.\n     * * Create a [View] and add it to the [FrameLayout]. Default size is 100px x 100px.\n     * * Create an [EpoxyVisibilityItem] and call [EpoxyVisibilityItem.update] on it.\n     *\n     * @param onPreViewAdded invoked before the view is added to the [FrameLayout]. Use this to\n     * customize the view (e.g set visibility, change size, etc).\n     * @param onPostViewAdded invoked after the view is added to the [FrameLayout]. Use this to\n     * customize the view (e.g set visibility, change size, etc).\n     */\n    private class EpoxyVisibilityItemWrapper(\n        activity: Activity,\n        detachEvent: Boolean = false,\n        onPreViewAdded: (View) -> (Unit) = {},\n        onPostViewAdded: (View) -> (Unit) = {},\n    ) {\n\n        val rootLayout: FrameLayout = FrameLayout(activity)\n        val view: View\n        val item: EpoxyVisibilityItem\n\n        init {\n            activity.setContentView(rootLayout)\n            view = View(rootLayout.context).apply {\n                layoutParams = FrameLayout.LayoutParams(100, 100)\n                onPreViewAdded.invoke(this)\n                rootLayout.addView(this)\n                onPostViewAdded.invoke(this)\n            }\n\n            item = EpoxyVisibilityItem().apply {\n                update(view, rootLayout, detachEvent)\n            }\n        }\n    }\n\n    /**\n     * Helper function that gets the [EpoxyVisibilityItem] from the [EpoxyVisibilityItemWrapper]\n     * for simple tests.\n     */\n    private fun TestActivity.createViewAndUpdate(\n        detachEvent: Boolean = false,\n        onPreViewAdded: (View) -> (Unit) = {},\n        onPostViewAdded: (View) -> (Unit) = {}\n    ): EpoxyVisibilityItem {\n        return EpoxyVisibilityItemWrapper(this, detachEvent, onPreViewAdded, onPostViewAdded).item\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/EpoxyVisibilityTrackerModelGroupTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.os.Looper\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.test.ext.junit.rules.activityScenarioRule\nimport androidx.test.runner.AndroidJUnit4\nimport com.airbnb.epoxy.integrationtest.R\nimport com.airbnb.epoxy.integrationtest.TestActivity\nimport com.airbnb.epoxy.models.TrackerTestModel\nimport com.airbnb.epoxy.models.trackerTestModel\nimport com.airbnb.epoxy.models.trackerTestModelGroup\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper\nimport org.junit.After\nimport org.junit.Before\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.Shadows.shadowOf\nimport org.robolectric.annotation.Config\nimport kotlin.math.roundToInt\n\n/**\n * Tests visibility tracking of [EpoxyModelGroup]s inside of a [RecyclerView].\n */\n@Config(sdk = [21], qualifiers = \"h831dp-mdpi\")\n@RunWith(AndroidJUnit4::class)\nclass EpoxyVisibilityTrackerModelGroupTest {\n\n    @get:Rule\n    var activityRule = activityScenarioRule<TestActivity>()\n\n    private lateinit var recyclerView: EpoxyRecyclerView\n    private lateinit var epoxyVisibilityTracker: EpoxyVisibilityTracker\n\n    private var ids = 0\n\n    @Before\n    fun setUp() {\n        epoxyVisibilityTracker = EpoxyVisibilityTracker()\n        activityRule.scenario.onActivity {\n            recyclerView = EpoxyRecyclerView(it)\n            epoxyVisibilityTracker.attach(recyclerView)\n            it.setContentView(recyclerView)\n            shadowOf(Looper.getMainLooper()).idle()\n        }\n    }\n\n    @After\n    fun tearDown() {\n        epoxyVisibilityTracker.detach(recyclerView)\n        ids = 0\n    }\n\n    @Test\n    fun testGroupInitiallyVisible_full() {\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val itemHeight = recyclerView.measuredHeight / 2\n        withModels {\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n        nestedHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyVisible_partial() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 25\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val firstItemHeight = recyclerView.measuredHeight - 100\n        val groupHeight = 200\n\n        withModels {\n            trackerTestModel(\"firstModel\", firstItemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", groupHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n        nestedHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyVisible_partial_underThreshold() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 51\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val firstItemHeight = recyclerView.measuredHeight - 100\n        val groupHeight = 200\n\n        withModels {\n            trackerTestModel(\"firstModel\", firstItemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", groupHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE\n            )\n        )\n        nestedHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyVisible_partial_hiddenChild() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 25\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val offScreenHelper = nextAssertHelper()\n        val firstItemHeight = recyclerView.measuredHeight - 100\n        val groupChildHeight = 200\n\n        withModels {\n            trackerTestModel(\"firstModel\", firstItemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", groupChildHeight, helper = nestedHelper),\n                    TrackerTestModel(\"offScreenModel\", groupChildHeight, helper = offScreenHelper)\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 25f, // half of first child and none of the second\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n        nestedHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n        offScreenHelper.assert(\n            visibleHeight = 0,\n            percentVisibleHeight = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyOffScreen() {\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val nestedItemHeight = 100\n        withModels {\n            trackerTestModel(\n                \"firstModel\",\n                itemHeight = recyclerView.height,\n                helper = nextAssertHelper()\n            )\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", nestedItemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = 0,\n            percentVisibleHeight = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n        nestedHelper.assert(\n            visibleHeight = 0,\n            percentVisibleHeight = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyOffScreen_scrolledToPartial() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 50\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val nestedItemHeight = 100\n        withModels {\n            trackerTestModel(\n                \"firstModel\",\n                itemHeight = recyclerView.height,\n                helper = nextAssertHelper()\n            )\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", nestedItemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        // Scroll so model is partially visible\n        (recyclerView.layoutManager as LinearLayoutManager)\n            .scrollToPositionWithOffset(0, -nestedItemHeight / 2)\n        shadowOf(Looper.getMainLooper()).idle()\n\n        groupHelper.assert(\n            visibleHeight = nestedItemHeight / 2,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n\n        )\n        nestedHelper.assert(\n            visibleHeight = nestedItemHeight / 2,\n            percentVisibleHeight = 50f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testGroupInitiallyOffScreen_scrolledToFull() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 50\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val nestedItemHeight = 100\n        withModels {\n            trackerTestModel(\n                \"firstModel\",\n                itemHeight = recyclerView.height,\n                helper = nextAssertHelper()\n            )\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", nestedItemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        // Scroll so model is fully visible\n        (recyclerView.layoutManager as LinearLayoutManager)\n            .scrollToPositionWithOffset(0, -nestedItemHeight)\n        shadowOf(Looper.getMainLooper()).idle()\n\n        groupHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n\n        )\n        nestedHelper.assert(\n            visibleHeight = 100,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testAddModelToGroup() {\n        val itemHeight = recyclerView.measuredHeight / 3\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        // Reset the existing helpers to test what happens when a model is added\n        groupHelper.reset()\n        nestedHelper.reset()\n        val newHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"newModel\", itemHeight, helper = newHelper)\n                )\n            }\n        }\n\n        // Group only has a visible height change as other attributes didn't change\n        groupHelper.assert(\n            visibleHeight = itemHeight * 2,\n            percentVisibleHeight = 100f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n\n        // Existing nested model doesn't have visibility changes because there was no size change\n        nestedHelper.assertDefault()\n\n        // New model has visibility changes\n        newHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testRemoveModelFromGroup() {\n        val itemHeight = recyclerView.measuredHeight / 3\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val toRemoveHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toRemove\", itemHeight, helper = toRemoveHelper)\n                )\n            }\n        }\n\n        // Reset the existing helpers to test what happens when a model is removed\n        groupHelper.reset()\n        nestedHelper.reset()\n        toRemoveHelper.reset()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper)\n                )\n            }\n        }\n\n        // Group only has a visible height change as other attributes didn't change\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n\n        // Existing nested model doesn't have visibility changes because there was no size change\n        nestedHelper.assertDefault()\n\n        // Removed model will have no visited states because the model group does not have a\n        // reference to it anymore for visibility changes.\n        toRemoveHelper.assertDefault()\n    }\n\n    @Test\n    fun testModelVisibility_existingHiddenModel() {\n        val itemHeight = recyclerView.measuredHeight / 3\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val hiddenHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toHide\", itemHeight, helper = hiddenHelper).hide()\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n        nestedHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n        // Hidden model is not initially traversed\n        hiddenHelper.assert(\n            visibleHeight = 0,\n            percentVisibleHeight = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n    }\n\n    @Test\n    fun testModelVisibility_hideModel() {\n        val itemHeight = recyclerView.measuredHeight / 3\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val toHideHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toHide\", itemHeight, helper = toHideHelper)\n                )\n            }\n        }\n\n        // Reset the existing helpers to test what happens when a model is hidden\n        groupHelper.reset()\n        nestedHelper.reset()\n        toHideHelper.reset()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toHide\", itemHeight, helper = toHideHelper).hide()\n                )\n            }\n        }\n\n        // Group only has a visible height change as other attributes didn't change\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n\n        // Existing nested model doesn't have visibility changes because there was no size change\n        nestedHelper.assertDefault()\n\n        // Hidden model receives appropriate visibility changes\n        toHideHelper.assert(\n            visibleHeight = 0,\n            percentVisibleHeight = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.INVISIBLE,\n                VisibilityState.UNFOCUSED_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testModelVisibility_showModel() {\n        val itemHeight = recyclerView.measuredHeight / 3\n        val groupHelper = nextAssertHelper()\n        val nestedHelper = nextAssertHelper()\n        val toShowHelper = nextAssertHelper()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toShow\", itemHeight, helper = toShowHelper).hide()\n                )\n            }\n        }\n\n        // Reset the existing helpers to test what happens when a hidden model is shown\n        groupHelper.reset()\n        nestedHelper.reset()\n        toShowHelper.reset()\n        withModels {\n            trackerTestModel(\"firstModel\", itemHeight, helper = nextAssertHelper())\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    TrackerTestModel(\"innerModel\", itemHeight, helper = nestedHelper),\n                    TrackerTestModel(\"toShow\", itemHeight, helper = toShowHelper)\n                )\n            }\n        }\n\n        // Group only has a visible height change as other attributes didn't change\n        groupHelper.assert(\n            visibleHeight = itemHeight * 2,\n            percentVisibleHeight = 100f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n\n        // Existing nested model doesn't have visibility changes because there was no size change\n        nestedHelper.assertDefault()\n\n        // Shown model receives appropriate visibility changes\n        toShowHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    @Test\n    fun testGroupWithCarousel() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 50\n        val groupHelper = nextAssertHelper()\n        val helper1 = nextAssertHelper()\n        val helper2 = nextAssertHelper()\n        val helper3 = nextAssertHelper()\n        val itemHeight = recyclerView.measuredHeight / 2\n        val itemWidth = (recyclerView.measuredWidth / 1.5).roundToInt()\n        withModels {\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    CarouselModel_().apply {\n                        id(\"carousel\")\n                        paddingDp(0)\n                        models(\n                            listOf(\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper1\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper2\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper3\n                                )\n                            )\n                        )\n                    }\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper1.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper2.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth / 2,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = (recyclerView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper3.assertDefault()\n    }\n\n    @Test\n    fun testGroupWithCarousel_noPartialImpression() {\n        val groupHelper = nextAssertHelper()\n        val helper1 = nextAssertHelper()\n        val helper2 = nextAssertHelper()\n        val helper3 = nextAssertHelper()\n        val itemHeight = recyclerView.measuredHeight / 2\n        val itemWidth = (recyclerView.measuredWidth / 1.5).roundToInt()\n        withModels {\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    CarouselModel_().apply {\n                        id(\"carousel\")\n                        paddingDp(0)\n                        models(\n                            listOf(\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper1\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper2\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper3\n                                )\n                            )\n                        )\n                    }\n                )\n            }\n        }\n\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper1.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = 100f,\n            visible = true,\n            partialImpression = false,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper2.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth / 2,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = (recyclerView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n            visible = true,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE\n            )\n        )\n\n        helper3.assertDefault()\n    }\n\n    @Test\n    fun testGroupWithCarousel_scrolledToEnd() {\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 50\n        val groupHelper = nextAssertHelper()\n        val helper1 = nextAssertHelper()\n        val helper2 = nextAssertHelper()\n        val helper3 = nextAssertHelper()\n        val itemHeight = recyclerView.measuredHeight / 2\n        val itemWidth = (recyclerView.measuredWidth / 1.5).roundToInt()\n\n        withModels {\n            trackerTestModelGroup(\"group\", groupHelper) {\n                layout(R.layout.vertical_linear_group)\n                setModels(\n                    CarouselModel_().apply {\n                        id(\"carousel\")\n                        paddingDp(0)\n                        models(\n                            listOf(\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper1\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper2\n                                ),\n                                TrackerTestModel(\n                                    \"carouselItem1\",\n                                    itemHeight = itemHeight,\n                                    itemWidth = itemWidth,\n                                    helper = helper3\n                                )\n                            )\n                        )\n                    }\n                )\n            }\n        }\n\n        // Scroll so last carousel model is fully visible\n        ((recyclerView.getChildAt(0) as ViewGroup).getChildAt(0) as RecyclerView)\n            .layoutManager\n            ?.scrollToPosition(2)\n        shadowOf(Looper.getMainLooper()).idle()\n\n        groupHelper.assert(\n            visibleHeight = itemHeight,\n            percentVisibleHeight = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper1.assert(\n            visibleHeight = 0,\n            visibleWidth = 0,\n            percentVisibleHeight = 0f,\n            percentVisibleWidth = 0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE,\n                VisibilityState.INVISIBLE,\n                VisibilityState.UNFOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_INVISIBLE\n            )\n        )\n\n        helper2.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth / 2,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = (recyclerView.measuredWidth - itemWidth).toFloat() / itemWidth * 100,\n            visible = true,\n            partialImpression = true,\n            fullImpression = false,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            )\n        )\n\n        helper3.assert(\n            visibleHeight = itemHeight,\n            visibleWidth = itemWidth,\n            percentVisibleHeight = 100f,\n            percentVisibleWidth = 100f,\n            visible = true,\n            partialImpression = true,\n            fullImpression = true,\n            visitedStates = intArrayOf(\n                VisibilityState.VISIBLE,\n                VisibilityState.FOCUSED_VISIBLE,\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n                VisibilityState.FULL_IMPRESSION_VISIBLE\n            )\n        )\n    }\n\n    /** Get a [VisibilityAssertHelper] using an auto-incrementing ID. */\n    private fun nextAssertHelper() = VisibilityAssertHelper(ids++)\n\n    /** Sets the models in the [recyclerView]. */\n    private fun withModels(buildModels: EpoxyController.() -> Unit) {\n        activityRule.scenario.onActivity {\n            recyclerView.withModels {\n                buildModels.invoke(this)\n            }\n            shadowOf(Looper.getMainLooper()).idle()\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/KotlinDefaultParamTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.integrationtest.KotlinViewWithDefaultParams\nimport com.airbnb.epoxy.integrationtest.KotlinViewWithDefaultParamsModel_\nimport org.junit.Assert.assertEquals\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\nimport org.robolectric.annotation.LooperMode\n\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\n@LooperMode(LooperMode.Mode.LEGACY)\nclass KotlinDefaultParamTest {\n\n    private lateinit var testController: TestController\n\n    @Before\n    fun setup() {\n        testController = TestController()\n    }\n\n    private class TestController : EpoxyController() {\n        private val lifecycleHelper = ControllerLifecycleHelper()\n\n        private var model: EpoxyModel<*>? = null\n\n        override fun buildModels() {\n            add(model!!)\n        }\n\n        fun buildWithModel(model: EpoxyModel<*>) {\n            this.model = model.id(1)\n            lifecycleHelper.buildModelsAndBind(this)\n        }\n    }\n\n    class Model(block: Model.() -> Unit) : KotlinViewWithDefaultParamsModel_() {\n        var view: KotlinViewWithDefaultParams? = null\n\n        init {\n            onBind { _, boundView, _ -> view = boundView }\n            block()\n        }\n    }\n\n    @Test\n    fun defaultParamIsUsed() {\n        val model = Model {}\n\n        testController.buildWithModel(model)\n\n        assertEquals(KotlinViewWithDefaultParams.IntDefault, model.view?.someIntWithDefaultValue)\n    }\n\n    @Test\n    fun customValueOverridesDefault() {\n        val model = Model {\n            someIntWithDefault(100)\n        }\n\n        testController.buildWithModel(model)\n\n        assertEquals(100, model.view?.someIntWithDefaultValue)\n    }\n\n    @Test\n    fun defaultTextPropValueIsUsed() {\n        val model = Model {}\n\n        testController.buildWithModel(model)\n\n        assertEquals(KotlinViewWithDefaultParams.TextDefault, model.view?.someTextWithDefaultValue)\n    }\n\n    @Test\n    fun defaultTextPropValueIsOverwrittenByManualValue() {\n        val model = Model {\n            someTextWithDefault(\"my custom value\")\n        }\n\n        testController.buildWithModel(model)\n\n        assertEquals(\"my custom value\", model.view?.someTextWithDefaultValue)\n    }\n\n    @Test\n    fun groupHasDefaultValue() {\n        val model = Model {}\n\n        testController.buildWithModel(model)\n\n        assertEquals(KotlinViewWithDefaultParams.IntGroupDefault, model.view?.groupValue)\n    }\n\n    @Test\n    fun overrideGroupValue() {\n        val model = Model {\n            propInGroupWithDefaultParam(100)\n        }\n\n        testController.buildWithModel(model)\n\n        assertEquals(100, model.view?.groupValue)\n    }\n\n    @Test\n    fun overrideGroupOtherValue() {\n        val model = Model {\n            otherPropInGroup(100)\n        }\n\n        testController.buildWithModel(model)\n\n        assertEquals(100, model.view?.groupValue)\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ModelBuilderExtensionIntegrationTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.integrationtest.Model\nimport com.airbnb.epoxy.integrationtest.ModelWithConstructors\nimport com.airbnb.epoxy.integrationtest.model\nimport com.airbnb.epoxy.integrationtest.modelWithConstructors\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\n\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\nclass ModelBuilderExtensionIntegrationTest {\n\n    @Test\n    fun generatedExtensionFunction() {\n        Controller().run {\n            requestModelBuild()\n\n            val model = adapter.copyOfModels.first() as Model\n            assertEquals(model.value, 5)\n            assertEquals(model.id(), 1)\n        }\n    }\n\n    @Test\n    fun modelsWithConstructors() {\n        Controller().run {\n            requestModelBuild()\n\n            val model = adapter.copyOfModels.get(1) as ModelWithConstructors\n            assertEquals(model.value, 10)\n            assertEquals(model.id(), 2)\n        }\n    }\n}\n\nprivate class Controller : EpoxyController() {\n    override fun buildModels() {\n        model {\n            id(1)\n            value(5)\n        }\n\n        modelWithConstructors(value = 10, id = 2) { }\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ModelClickListenerTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.View.OnClickListener;\nimport android.widget.CompoundButton;\n\nimport com.airbnb.epoxy.integrationtest.ModelWithCheckedChangeListener_;\nimport com.airbnb.epoxy.integrationtest.ModelWithClickListener_;\nimport com.airbnb.epoxy.integrationtest.ModelWithLongClickListener_;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\nimport static junit.framework.Assert.assertFalse;\nimport static junit.framework.Assert.assertNotNull;\nimport static junit.framework.Assert.assertNotSame;\nimport static junit.framework.Assert.assertNull;\nimport static junit.framework.Assert.assertTrue;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.ArgumentMatchers.eq;\nimport static org.mockito.Mockito.doReturn;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.spy;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\nimport static org.mockito.Mockito.when;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class ModelClickListenerTest {\n\n  private ControllerLifecycleHelper lifecycleHelper = new ControllerLifecycleHelper();\n\n  static class TestController extends EpoxyController {\n    private EpoxyModel<?> model;\n\n    @Override\n    protected void buildModels() {\n      add(model.id(1));\n    }\n\n    void setModel(EpoxyModel<?> model) {\n      this.model = model;\n    }\n  }\n\n  static class ModelClickListener implements OnModelClickListener<ModelWithClickListener_, View> {\n    boolean clicked;\n\n    @Override\n    public void onClick(ModelWithClickListener_ model, View view, View v, int position) {\n      clicked = true;\n    }\n  }\n\n  static class ModelLongClickListener\n      implements OnModelLongClickListener<ModelWithLongClickListener_, View> {\n    boolean clicked;\n\n    @Override\n    public boolean onLongClick(ModelWithLongClickListener_ model, View view, View v, int position) {\n      clicked = true;\n      return true;\n    }\n  }\n\n  static class ModelCheckedChangeListener\n      implements OnModelCheckedChangeListener<ModelWithCheckedChangeListener_, View> {\n    boolean checked;\n\n    @Override\n    public void onChecked(ModelWithCheckedChangeListener_ model, View parentView,\n        CompoundButton checkedView, boolean isChecked, int position) {\n      checked = true;\n    }\n  }\n\n  static class ViewClickListener implements OnClickListener {\n    boolean clicked;\n\n    @Override\n    public void onClick(View v) {\n      clicked = true;\n    }\n  }\n\n  @Test\n  public void basicModelClickListener() {\n    final ModelWithClickListener_ model = new ModelWithClickListener_();\n    ModelClickListener modelClickListener = spy(new ModelClickListener());\n    model.clickListener(modelClickListener);\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    View viewMock = mockModelForClicking(model);\n\n    model.clickListener().onClick(viewMock);\n    assertTrue(modelClickListener.clicked);\n\n    verify(modelClickListener).onClick(eq(model), any(View.class), eq(viewMock), eq(1));\n  }\n\n  private View mockModelForClicking(EpoxyModel model) {\n    View mockedView = mock(View.class);\n    RecyclerView recyclerMock = mock(RecyclerView.class);\n    EpoxyViewHolder holderMock = mock(EpoxyViewHolder.class);\n\n    when(holderMock.getAdapterPosition()).thenReturn(1);\n    doReturn(recyclerMock).when(mockedView).getParent();\n    doReturn(holderMock).when(recyclerMock).findContainingViewHolder(mockedView);\n    doReturn(model).when(holderMock).getModel();\n\n    when(mockedView.getParent()).thenReturn(recyclerMock);\n    when(recyclerMock.findContainingViewHolder(mockedView)).thenReturn(holderMock);\n    when(holderMock.getAdapterPosition()).thenReturn(1);\n    when(holderMock.getModel()).thenReturn(model);\n\n    View parentView = mock(View.class);\n    when(holderMock.objectToBind()).thenReturn(parentView);\n    doReturn(parentView).when(holderMock).objectToBind();\n    return mockedView;\n  }\n\n  @Test\n  public void basicModelLongClickListener() {\n    final ModelWithLongClickListener_ model = new ModelWithLongClickListener_();\n    ModelLongClickListener modelClickListener = spy(new ModelLongClickListener());\n    model.clickListener(modelClickListener);\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    View viewMock = mockModelForClicking(model);\n\n    model.clickListener().onLongClick(viewMock);\n    assertTrue(modelClickListener.clicked);\n\n    verify(modelClickListener).onLongClick(eq(model), any(View.class), eq(viewMock), eq(1));\n  }\n\n  @Test\n  public void basicModelCheckedChangeListener() {\n    final ModelWithCheckedChangeListener_ model = new ModelWithCheckedChangeListener_();\n    ModelCheckedChangeListener modelCheckedChangeListener = spy(new ModelCheckedChangeListener());\n    model.checkedChangeListener(modelCheckedChangeListener);\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    CompoundButton compoundMock = mockCompoundButtonForClicking(model);\n\n    model.checkedChangeListener().onCheckedChanged(compoundMock, true);\n    assertTrue(modelCheckedChangeListener.checked);\n\n    verify(modelCheckedChangeListener).onChecked(eq(model), any(View.class), any(CompoundButton.class), eq(true), eq(1));\n  }\n\n  private CompoundButton mockCompoundButtonForClicking(EpoxyModel model) {\n    CompoundButton mockedView = mock(CompoundButton.class);\n    RecyclerView recyclerMock = mock(RecyclerView.class);\n    EpoxyViewHolder holderMock = mock(EpoxyViewHolder.class);\n\n    when(holderMock.getAdapterPosition()).thenReturn(1);\n    doReturn(recyclerMock).when(mockedView).getParent();\n    doReturn(holderMock).when(recyclerMock).findContainingViewHolder(mockedView);\n    doReturn(model).when(holderMock).getModel();\n\n    when(mockedView.getParent()).thenReturn(recyclerMock);\n    when(recyclerMock.findContainingViewHolder(mockedView)).thenReturn(holderMock);\n    when(holderMock.getAdapterPosition()).thenReturn(1);\n    when(holderMock.getModel()).thenReturn(model);\n\n    View parentView = mock(View.class);\n    when(holderMock.objectToBind()).thenReturn(parentView);\n    doReturn(parentView).when(holderMock).objectToBind();\n    return mockedView;\n  }\n\n  @Test\n  public void modelClickListenerOverridesViewClickListener() {\n    final ModelWithClickListener_ model = new ModelWithClickListener_();\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    ViewClickListener viewClickListener = new ViewClickListener();\n    model.clickListener(viewClickListener);\n    assertNotNull(model.clickListener());\n\n    ModelClickListener modelClickListener = new ModelClickListener();\n    model.clickListener(modelClickListener);\n    assertNotSame(model.clickListener(), viewClickListener);\n\n    lifecycleHelper.buildModelsAndBind(controller);\n    mockModelForClicking(model);\n    assertNotNull(model.clickListener());\n    View viewMock = mockModelForClicking(model);\n\n    model.clickListener().onClick(viewMock);\n    assertTrue(modelClickListener.clicked);\n    assertFalse(viewClickListener.clicked);\n  }\n\n  @Test\n  public void viewClickListenerOverridesModelClickListener() {\n    final ModelWithClickListener_ model = new ModelWithClickListener_();\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    ModelClickListener modelClickListener = new ModelClickListener();\n    model.clickListener(modelClickListener);\n\n    ViewClickListener viewClickListener = new ViewClickListener();\n    model.clickListener(viewClickListener);\n\n    lifecycleHelper.buildModelsAndBind(controller);\n    assertNotNull(model.clickListener());\n\n    model.clickListener().onClick(null);\n    assertTrue(viewClickListener.clicked);\n    assertFalse(modelClickListener.clicked);\n  }\n\n  @Test\n  public void resetClearsModelClickListener() {\n    final ModelWithClickListener_ model = new ModelWithClickListener_();\n\n    TestController controller = new TestController();\n    controller.setModel(model);\n\n    ModelClickListener modelClickListener = spy(new ModelClickListener());\n    model.clickListener(modelClickListener);\n    model.reset();\n\n    lifecycleHelper.buildModelsAndBind(controller);\n    assertNull(model.clickListener());\n  }\n\n  @Test\n  public void modelClickListenerIsDiffed() {\n    // Internally we wrap the model click listener with an anonymous click listener. We can't hash\n    // the anonymous click listener since that changes the model state, instead our anonymous\n    // click listener should use the hashCode of the user's click listener\n\n    ModelClickListener modelClickListener = new ModelClickListener();\n    ViewClickListener viewClickListener = new ViewClickListener();\n\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.setModel(model);\n    controller.requestModelBuild();\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    model = new ModelWithClickListener_();\n    model.clickListener(modelClickListener);\n    controller.setModel(model);\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    // The second update shouldn't cause a item change\n    model = new ModelWithClickListener_();\n    model.clickListener(modelClickListener);\n    controller.setModel(model);\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    model = new ModelWithClickListener_();\n    model.clickListener(viewClickListener);\n    controller.setModel(model);\n    lifecycleHelper.buildModelsAndBind(controller);\n\n    verify(observerMock, times(2)).onItemRangeChanged(eq(0), eq(1), any());\n    verifyNoMoreInteractions(observerMock);\n  }\n\n  @Test\n  public void viewClickListenerIsDiffed() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.setModel(model);\n    controller.requestModelBuild();\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    ViewClickListener viewClickListener = new ViewClickListener();\n    model = new ModelWithClickListener_();\n    model.clickListener(viewClickListener);\n    controller.setModel(model);\n    controller.requestModelBuild();\n\n    // The second update shouldn't cause a item change\n    model = new ModelWithClickListener_();\n    model.clickListener(viewClickListener);\n    controller.setModel(model);\n    controller.requestModelBuild();\n\n    ModelClickListener modelClickListener = new ModelClickListener();\n    model = new ModelWithClickListener_();\n    model.clickListener(modelClickListener);\n    controller.setModel(model);\n    controller.requestModelBuild();\n\n    verify(observerMock, times(2)).onItemRangeChanged(eq(0), eq(1), any());\n    verifyNoMoreInteractions(observerMock);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ModelGroupIntegrationTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.integrationtest.ModelGroupWithAnnotation_\nimport com.airbnb.epoxy.integrationtest.Model_\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\n\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\nclass ModelGroupIntegrationTest {\n\n    @Test\n    fun modelGroupSubclassIsGenerated() {\n        // Just checking that the generated class exists and compiles\n        ModelGroupWithAnnotation_(listOf(Model_()))\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ModelViewDelegateTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.integrationtest.ViewWithDelegateModel_\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\n\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\nclass ModelViewDelegateTest {\n\n    @Test\n    fun propMethodIsOnModel() {\n        val model = ViewWithDelegateModel_()\n        model.flag(true)\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ModelViewInterfaceTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport com.airbnb.epoxy.integrationtest.ClassWithNestedInterface_NestedInterfaceModel_\nimport com.airbnb.epoxy.integrationtest.InterfaceForView2Model_\nimport com.airbnb.epoxy.integrationtest.InterfaceForViewModel_\nimport com.airbnb.epoxy.integrationtest.ViewWithInterface2Model_\nimport com.airbnb.epoxy.integrationtest.ViewWithInterfaceModel_\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.Config\n\n@RunWith(RobolectricTestRunner::class)\n@Config(sdk = [21])\nclass ModelViewInterfaceTest {\n\n    @Test\n    fun interfaceIsGeneratedForView() {\n        val model: InterfaceForViewModel_ = ViewWithInterfaceModel_()\n        model.text(\"\")\n    }\n\n    @Test\n    fun generatedInterfaceIncludesBaseModelProps() {\n        val model: InterfaceForViewModel_ = ViewWithInterfaceModel_()\n        model.id(1)\n            .id(\"sfd\")\n            .spanSizeOverride(null)\n    }\n\n    @Test\n    fun textPropMethodsAreOnInterface() {\n        val model: InterfaceForViewModel_ = ViewWithInterfaceModel_()\n        model.text(\"\")\n            .text2(\"asdf\")\n            .text2(3)\n            .text2(3, \"arg\")\n    }\n\n    @Test\n    fun multipleModelsDeclareInterface() {\n        val model1: InterfaceForViewModel_ = ViewWithInterfaceModel_()\n        val model2: InterfaceForViewModel_ = ViewWithInterface2Model_()\n\n        model1.text(\"\")\n            .text2(\"\")\n            .id(1)\n\n        model2.text(\"\")\n            .text2(\"\")\n            .id(1)\n    }\n\n    @Test\n    fun viewCanHaveMultipleInterfaces() {\n        val model = ViewWithInterfaceModel_()\n        val interface1 = model as InterfaceForViewModel_\n        val interface2 = model as InterfaceForView2Model_\n\n        interface1.text(\"\")\n        interface2.listener(null)\n    }\n\n    @Test\n    fun nestedInterfaceWorks() {\n        val model = ViewWithInterfaceModel_() as ClassWithNestedInterface_NestedInterfaceModel_\n        model.listener(View.OnClickListener { })\n    }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/OnModelBindListenerTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.integrationtest.ModelWithClickListener_;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;\n\nimport static junit.framework.Assert.assertFalse;\nimport static junit.framework.Assert.assertTrue;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.ArgumentMatchers.eq;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class OnModelBindListenerTest {\n\n  private ControllerLifecycleHelper lifecycleHelper = new ControllerLifecycleHelper();\n\n  static class TestController extends EpoxyController {\n\n    private EpoxyModel model;\n\n    @Override\n    protected void buildModels() {\n      add(model);\n    }\n\n    void setModel(EpoxyModel model) {\n      this.model = model.id(1);\n    }\n\n    void buildWithModel(EpoxyModel model) {\n      setModel(model);\n      requestModelBuild();\n    }\n  }\n\n  static class BindListener implements OnModelBoundListener<ModelWithClickListener_, View> {\n    boolean called;\n\n    @Override\n    public void onModelBound(ModelWithClickListener_ model, View view, int position) {\n      called = true;\n    }\n  }\n\n  static class UnbindListener implements OnModelUnboundListener<ModelWithClickListener_, View> {\n    boolean called;\n\n    @Override\n    public void onModelUnbound(ModelWithClickListener_ model, View view) {\n      called = true;\n    }\n  }\n\n  @Test\n  public void onBindListenerGetsCalled() {\n    TestController controller = new TestController();\n\n    BindListener bindListener = new BindListener();\n    ModelWithClickListener_ model = new ModelWithClickListener_().onBind(bindListener);\n    controller.setModel(model);\n\n    assertFalse(bindListener.called);\n    lifecycleHelper.buildModelsAndBind(controller);\n    assertTrue(bindListener.called);\n  }\n\n  @Test\n  public void onUnbindListenerGetsCalled() {\n    TestController controller = new TestController();\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.setModel(model);\n\n    UnbindListener unbindlistener = new UnbindListener();\n    model.onUnbind(unbindlistener);\n\n    assertFalse(unbindlistener.called);\n    lifecycleHelper.buildModelsAndBind(controller);\n    assertFalse(unbindlistener.called);\n\n    lifecycleHelper.recycleLastBoundModel(controller);\n    assertTrue(unbindlistener.called);\n  }\n\n  @Test\n  public void bindListenerChangesHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    // shouldn't change\n    model = new ModelWithClickListener_();\n    model.onBind(null);\n    controller.buildWithModel(model);\n    verify(observerMock, never()).onItemRangeChanged(eq(0), eq(1), any());\n\n    model = new ModelWithClickListener_();\n    BindListener listener1 = new BindListener();\n    model.onBind(listener1);\n    controller.buildWithModel(model);\n    verify(observerMock, times(1)).onItemRangeChanged(eq(0), eq(1), any());\n\n    model = new ModelWithClickListener_();\n    model.onBind(listener1);\n    controller.buildWithModel(model);\n    verify(observerMock, times(1)).onItemRangeChanged(eq(0), eq(1), any());\n  }\n\n  @Test\n  public void nullBindListenerChangesHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    model = new ModelWithClickListener_();\n    model.onBind(new BindListener());\n    controller.buildWithModel(model);\n\n    model = new ModelWithClickListener_();\n    model.onBind(null);\n    controller.buildWithModel(model);\n\n    verify(observerMock, times(2)).onItemRangeChanged(eq(0), eq(1), any());\n  }\n\n  @Test\n  public void newBindListenerDoesNotChangeHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    model = new ModelWithClickListener_();\n    model.onBind(new BindListener());\n    controller.buildWithModel(model);\n\n    model = new ModelWithClickListener_();\n    model.onBind(new BindListener());\n    controller.buildWithModel(model);\n\n    verify(observerMock).onItemRangeChanged(eq(0), eq(1), any());\n  }\n\n  @Test\n  public void unbindListenerChangesHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    // shouldn't change\n    model = new ModelWithClickListener_();\n    model.onUnbind(null);\n    controller.buildWithModel(model);\n    verify(observerMock, never()).onItemRangeChanged(eq(0), eq(1), any());\n\n    model = new ModelWithClickListener_();\n    UnbindListener listener1 = new UnbindListener();\n    model.onUnbind(listener1);\n    controller.buildWithModel(model);\n    verify(observerMock, times(1)).onItemRangeChanged(eq(0), eq(1), any());\n\n    model = new ModelWithClickListener_();\n    model.onUnbind(listener1);\n    controller.buildWithModel(model);\n    verify(observerMock, times(1)).onItemRangeChanged(eq(0), eq(1), any());\n  }\n\n  @Test\n  public void nullUnbindListenerChangesHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    model = new ModelWithClickListener_();\n    model.onUnbind(new UnbindListener());\n    controller.buildWithModel(model);\n\n    model = new ModelWithClickListener_();\n    model.onUnbind(null);\n    controller.buildWithModel(model);\n\n    verify(observerMock, times(2)).onItemRangeChanged(eq(0), eq(1), any());\n  }\n\n  @Test\n  public void newUnbindListenerDoesNotChangHashCode() {\n    TestController controller = new TestController();\n\n    AdapterDataObserver observerMock = mock(AdapterDataObserver.class);\n    controller.getAdapter().registerAdapterDataObserver(observerMock);\n\n    ModelWithClickListener_ model = new ModelWithClickListener_();\n    controller.buildWithModel(model);\n    verify(observerMock).onItemRangeInserted(eq(0), eq(1));\n\n    model = new ModelWithClickListener_();\n    model.onUnbind(new UnbindListener());\n    controller.buildWithModel(model);\n\n    model = new ModelWithClickListener_();\n    model.onUnbind(new UnbindListener());\n    controller.buildWithModel(model);\n\n    verify(observerMock).onItemRangeChanged(eq(0), eq(1), any());\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/ViewAnnotationsStringOverloadsIntegrationTest.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.res.Resources;\n\nimport com.airbnb.epoxy.integrationtest.R;\nimport com.airbnb.epoxy.integrationtest.ViewWithAnnotationsForIntegrationTest;\nimport com.airbnb.epoxy.integrationtest.ViewWithAnnotationsForIntegrationTestModel_;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.annotation.LooperMode;\n\nimport androidx.test.core.app.ApplicationProvider;\n\nimport static junit.framework.Assert.assertEquals;\nimport static junit.framework.Assert.assertNull;\n\n@RunWith(RobolectricTestRunner.class)\n@LooperMode(LooperMode.Mode.LEGACY)\npublic class ViewAnnotationsStringOverloadsIntegrationTest {\n\n  private ControllerLifecycleHelper lifecycleHelper;\n\n  ViewWithAnnotationsForIntegrationTest bind(ViewWithAnnotationsForIntegrationTestModel_ model) {\n    lifecycleHelper = new ControllerLifecycleHelper();\n    model.id(1);\n    return (ViewWithAnnotationsForIntegrationTest) lifecycleHelper.bindModel(model);\n  }\n\n  @Test\n  public void normalCharSequenceIsSet() {\n    String text = \"hello world\";\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_().requiredText(text);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(text, view.requiredText);\n  }\n\n  @Test\n  public void getStringOffModel() {\n    String text = \"hello world!\";\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_().requiredText(text);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(model.getRequiredText(view.getContext()), view.requiredText);\n  }\n\n  @Test\n  public void stringResIsSet() {\n    int stringWithNoArgs = R.string.string_with_no_args;\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(stringWithNoArgs);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(view.getContext().getText(stringWithNoArgs), view.requiredText);\n  }\n\n  @Test\n  public void stringResWithArgsIsSet() {\n    int stringWithNoArgs = R.string.string_with_args;\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(stringWithNoArgs, 3);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(view.getContext().getString(stringWithNoArgs, 3), view.requiredText);\n  }\n\n  @Test\n  public void quantityStringIsSet() {\n    int pluralString = R.plurals.plural_test_string;\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredTextQuantityRes(pluralString, 1);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(view.getContext().getResources().getQuantityString(pluralString, 1),\n        view.requiredText);\n  }\n\n  @Test\n  public void quantityStringWithArgsIsSet() {\n    int pluralString = R.plurals.plural_test_string_with_args;\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredTextQuantityRes(pluralString, 1, 3);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(view.getContext().getResources().getQuantityString(pluralString, 1, 3),\n        view.requiredText);\n  }\n\n  @Test(expected = IllegalArgumentException.class)\n  public void requiredTextThrowsWhenSetWithNull() {\n    new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(null);\n  }\n\n  @Test(expected = IllegalStateException.class)\n  public void requiredTextThrowsWhenNotSet() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_();\n\n    bind(model);\n  }\n\n  @Test(expected = IllegalArgumentException.class)\n  public void requiredTextThrowsOnBadStringRes() {\n    new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(0);\n  }\n\n  @Test(expected = IllegalArgumentException.class)\n  public void requiredTextThrowsOnBadStringResWithArgs() {\n    new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(0, \"args\");\n  }\n\n  @Test(expected = IllegalArgumentException.class)\n  public void requiredTextThrowsOnBadQuantityString() {\n    new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredTextQuantityRes(0, 23, \"args\");\n  }\n\n  @Test\n  public void nullableTextSetsNullWhenNotSet() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_().requiredText(\"required\");\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertNull(view.nullableText);\n  }\n\n  @Test\n  public void nullableTextAllowsNull() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .nullableText(null);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertNull(view.nullableText);\n  }\n\n  @Test\n  public void nullableTextAllowsZeroStringRes() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .nullableText(0);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertNull(view.nullableText);\n  }\n\n  @Test\n  public void nullableTextAllowsZeroQuantityRes() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .nullableTextQuantityRes(0, 1);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertNull(view.nullableText);\n  }\n\n  @Test\n  public void defaultStringValueSetIfNothingElseIsSet() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\");\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING, view.textWithDefault);\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING,\n        view.nullableTextWithDefault);\n  }\n\n  @Test\n  public void stringOverridesDefault() {\n    String text = \"hello world\";\n\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .textWithDefault(text)\n            .nullableTextWithDefault(text);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(text, view.nullableTextWithDefault);\n    assertEquals(text, view.textWithDefault);\n  }\n\n  @Test\n  public void nullableStringOverridesDefaultWithNull() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .nullableTextWithDefault(null);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(null, view.nullableTextWithDefault);\n  }\n\n  @Test\n  public void zeroStringResSetsDefault() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .textWithDefault(0)\n            .nullableTextWithDefault(0);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING, view.textWithDefault);\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING,\n        view.nullableTextWithDefault);\n  }\n\n  @Test\n  public void zeroQuantityStringResSetsDefault() {\n    ViewWithAnnotationsForIntegrationTestModel_ model =\n        new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .textWithDefaultQuantityRes(0, 1)\n            .nullableTextWithDefaultQuantityRes(0, 1);\n\n    ViewWithAnnotationsForIntegrationTest view = bind(model);\n\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING, view.textWithDefault);\n    assertEquals(ViewWithAnnotationsForIntegrationTest.DEFAULT_STRING,\n        view.nullableTextWithDefault);\n  }\n\n  @Test\n  public void stringOverloadsResetEachOther() {\n    Resources r = ApplicationProvider.getApplicationContext().getResources();\n\n    ViewWithAnnotationsForIntegrationTest view =\n        bind(new ViewWithAnnotationsForIntegrationTestModel_()\n            .requiredText(\"required\")\n            .nullableText(R.string.string_with_no_args)\n            .nullableText(\"test\"));\n\n    assertEquals(\"test\", view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(\"test\")\n        .nullableText(R.string.string_with_no_args));\n\n    assertEquals(r.getString(R.string.string_with_no_args), view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(R.string.string_with_no_args)\n        .nullableTextQuantityRes(R.plurals.plural_test_string, 1));\n\n    assertEquals(r.getQuantityString(R.plurals.plural_test_string, 1), view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(R.string.string_with_no_args)\n        .nullableTextQuantityRes(0, 1));\n\n    assertNull(view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableTextQuantityRes(R.plurals.plural_test_string, 1)\n        .nullableText(R.string.string_with_args, 2));\n\n    assertEquals(r.getString(R.string.string_with_args, 2), view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(0)\n        .nullableText(R.string.string_with_args, 2));\n\n    assertEquals(r.getString(R.string.string_with_args, 2), view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(0)\n        .nullableText(R.string.string_with_args, 2));\n\n    assertEquals(r.getString(R.string.string_with_args, 2), view.nullableText);\n\n    view = bind(new ViewWithAnnotationsForIntegrationTestModel_()\n        .requiredText(\"required\")\n        .nullableText(R.string.string_with_args, 2)\n        .nullableText(0));\n\n    assertNull(view.nullableText);\n  }\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/models/TrackerTestModel.kt",
    "content": "package com.airbnb.epoxy.models\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModelWithView\nimport com.airbnb.epoxy.ModelCollector\nimport com.airbnb.epoxy.VisibilityState\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper.Companion.description\n\n/**\n * Epoxy model used for visibility testing.\n */\ninternal class TrackerTestModel(\n    private val debugTag: String,\n    private val itemHeight: Int,\n    private val itemWidth: Int = FrameLayout.LayoutParams.MATCH_PARENT,\n    private val helper: VisibilityAssertHelper\n) : EpoxyModelWithView<View>() {\n\n    init {\n        id(helper.id)\n    }\n\n    override fun buildView(parent: ViewGroup): View {\n        VisibilityAssertHelper.log(\"buildView[$debugTag](id=${helper.id})\")\n        return TextView(parent.context).apply {\n            // Force height\n            layoutParams = RecyclerView.LayoutParams(itemWidth, itemHeight)\n        }\n    }\n\n    override fun onVisibilityChanged(ph: Float, pw: Float, vh: Int, vw: Int, view: View) {\n        helper.percentVisibleHeight = ph\n        helper.percentVisibleWidth = pw\n        helper.visibleHeight = vh\n        helper.visibleWidth = vw\n        if (ph.toInt() != 100) helper.fullImpression = false\n    }\n\n    override fun onVisibilityStateChanged(state: Int, view: View) {\n        VisibilityAssertHelper.log(\"onVisibilityStateChanged[$debugTag](id=${helper.id})=${state.description()}\")\n        helper.visitedStates.add(state)\n        when (state) {\n            VisibilityState.VISIBLE, VisibilityState.INVISIBLE ->\n                helper.visible = state == VisibilityState.VISIBLE\n            VisibilityState.FOCUSED_VISIBLE, VisibilityState.UNFOCUSED_VISIBLE ->\n                helper.focused = state == VisibilityState.FOCUSED_VISIBLE\n            VisibilityState.PARTIAL_IMPRESSION_VISIBLE, VisibilityState.PARTIAL_IMPRESSION_INVISIBLE ->\n                helper.partialImpression = state == VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            VisibilityState.FULL_IMPRESSION_VISIBLE ->\n                helper.fullImpression = state == VisibilityState.FULL_IMPRESSION_VISIBLE\n        }\n    }\n}\n\n/**\n * Helper function to create a [TrackerTestModel] and add it to the [EpoxyController].\n */\ninternal fun ModelCollector.trackerTestModel(\n    debugTag: String,\n    itemHeight: Int,\n    itemWidth: Int = FrameLayout.LayoutParams.MATCH_PARENT,\n    helper: VisibilityAssertHelper,\n    modelInitializer: (TrackerTestModel.() -> Unit)? = null\n) {\n    add(\n        TrackerTestModel(debugTag, itemHeight, itemWidth, helper)\n            .apply { modelInitializer?.invoke(this) }\n    )\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/models/TrackerTestModelGroup.kt",
    "content": "package com.airbnb.epoxy.models\n\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelGroup\nimport com.airbnb.epoxy.ModelCollector\nimport com.airbnb.epoxy.ModelGroupHolder\nimport com.airbnb.epoxy.VisibilityState\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper.Companion.description\nimport com.airbnb.epoxy.utils.VisibilityAssertHelper.Companion.log\n\n/**\n * Epoxy model group used for visibility testing.\n */\ninternal class TrackerTestModelGroup(\n    private val debugTag: String,\n    private val helper: VisibilityAssertHelper\n) : EpoxyModelGroup() {\n\n    init {\n        id(helper.id)\n    }\n\n    /**\n     * Add models to this group, removing any that existed prior.\n     */\n    fun setModels(vararg modelsToAdd: EpoxyModel<*>) {\n        models.clear()\n        for (model in modelsToAdd) {\n            addModel(model)\n        }\n    }\n\n    override fun onVisibilityChanged(\n        percentVisibleHeight: Float,\n        percentVisibleWidth: Float,\n        visibleHeight: Int,\n        visibleWidth: Int,\n        holder: ModelGroupHolder\n    ) {\n        helper.percentVisibleHeight = percentVisibleHeight\n        helper.percentVisibleWidth = percentVisibleWidth\n        helper.visibleHeight = visibleHeight\n        helper.visibleWidth = visibleWidth\n        if (percentVisibleHeight.toInt() != 100) helper.fullImpression = false\n    }\n\n    override fun onVisibilityStateChanged(visibilityState: Int, holder: ModelGroupHolder) {\n        log(\"onVisibilityStateChanged[$debugTag](id=${helper.id})=${visibilityState.description()}\")\n        helper.visitedStates.add(visibilityState)\n        when (visibilityState) {\n            VisibilityState.VISIBLE, VisibilityState.INVISIBLE ->\n                helper.visible = visibilityState == VisibilityState.VISIBLE\n            VisibilityState.FOCUSED_VISIBLE, VisibilityState.UNFOCUSED_VISIBLE ->\n                helper.focused = visibilityState == VisibilityState.FOCUSED_VISIBLE\n            VisibilityState.PARTIAL_IMPRESSION_VISIBLE, VisibilityState.PARTIAL_IMPRESSION_INVISIBLE ->\n                helper.partialImpression = visibilityState == VisibilityState.PARTIAL_IMPRESSION_VISIBLE\n            VisibilityState.FULL_IMPRESSION_VISIBLE ->\n                helper.fullImpression = visibilityState == VisibilityState.FULL_IMPRESSION_VISIBLE\n        }\n    }\n}\n\n/**\n * Helper function to create a [TrackerTestModelGroup] and add it to the [EpoxyController].\n */\ninternal fun ModelCollector.trackerTestModelGroup(\n    debugTag: String,\n    helper: VisibilityAssertHelper,\n    modelInitializer: (TrackerTestModelGroup.() -> Unit)? = null\n) {\n    add(\n        TrackerTestModelGroup(debugTag, helper)\n            .apply { modelInitializer?.invoke(this) }\n    )\n}\n"
  },
  {
    "path": "epoxy-integrationtest/src/test/java/com/airbnb/epoxy/utils/VisibilityAssertHelper.kt",
    "content": "package com.airbnb.epoxy.utils\n\nimport android.util.Log\nimport com.airbnb.epoxy.EpoxyVisibilityTracker\nimport com.airbnb.epoxy.VisibilityState\nimport org.junit.Assert\nimport kotlin.math.abs\n\n/**\n * Helper for asserting visibility.\n */\ninternal class VisibilityAssertHelper(val id: Int) {\n\n    var visitedStates = mutableListOf<Int>()\n    var visibleHeight = 0\n    var visibleWidth = 0\n    var percentVisibleHeight = 0.0f\n    var percentVisibleWidth = 0.0f\n    var visible = false\n    var focused = false\n    var partialImpression = false\n    var fullImpression = false\n\n    /**\n     * Resets the attributes to the state where no visibility changes occurred.\n     */\n    fun reset() {\n        visitedStates = mutableListOf()\n        visibleHeight = 0\n        visibleWidth = 0\n        percentVisibleHeight = 0.0f\n        percentVisibleWidth = 0.0f\n        visible = false\n        focused = false\n        partialImpression = false\n        fullImpression = false\n    }\n\n    /**\n     * Asserts that no visibility changes occurred.\n     */\n    fun assertDefault() {\n        assert(\n            id = id,\n            visibleHeight = 0,\n            visibleWidth = 0,\n            percentVisibleHeight = 0.0f,\n            percentVisibleWidth = 0.0f,\n            visible = false,\n            partialImpression = false,\n            fullImpression = false,\n            visitedStates = IntArray(0)\n        )\n    }\n\n    /**\n     * Asserts that the desired visibility changes occurred. Use null to omit an assertion for that\n     * attribute.\n     */\n    fun assert(\n        id: Int? = null,\n        visibleHeight: Int? = null,\n        visibleWidth: Int? = null,\n        percentVisibleHeight: Float? = null,\n        percentVisibleWidth: Float? = null,\n        visible: Boolean? = null,\n        partialImpression: Boolean? = null,\n        fullImpression: Boolean? = null,\n        visitedStates: IntArray? = null\n    ) {\n        id?.let {\n            Assert.assertEquals(\n                \"id expected $it got ${this.id}\",\n                it,\n                this.id\n            )\n        }\n        visibleHeight?.let {\n            // assert using tolerance, see TOLERANCE_PIXELS\n            log(\"assert visibleHeight, got $it, expected ${this.visibleHeight}\")\n            Assert.assertTrue(\n                \"visibleHeight expected ${it}px got ${this.visibleHeight}px\",\n                abs(it - this.visibleHeight) <= TOLERANCE_PIXELS\n            )\n        }\n        visibleWidth?.let {\n            // assert using tolerance, see TOLERANCE_PIXELS\n            log(\"assert visibleWidth, got $it, expected ${this.visibleWidth}\")\n            Assert.assertTrue(\n                \"visibleWidth expected ${it}px got ${this.visibleWidth}px\",\n                abs(it - this.visibleWidth) <= TOLERANCE_PIXELS\n            )\n        }\n        percentVisibleHeight?.let {\n            Assert.assertEquals(\n                \"percentVisibleHeight expected $it got ${this.percentVisibleHeight}\",\n                it,\n                this.percentVisibleHeight,\n                0.05f\n            )\n        }\n        percentVisibleWidth?.let {\n            Assert.assertEquals(\n                \"percentVisibleWidth expected $it got ${this.percentVisibleWidth}\",\n                it,\n                this.percentVisibleWidth,\n                0.05f\n            )\n        }\n        visible?.let {\n            Assert.assertEquals(\n                \"visible expected $it got ${this.visible}\",\n                it,\n                this.visible\n            )\n        }\n        partialImpression?.let {\n            Assert.assertEquals(\n                \"partialImpression expected $it got ${this.partialImpression}\",\n                it,\n                this.partialImpression\n            )\n        }\n        fullImpression?.let {\n            Assert.assertEquals(\n                \"fullImpression expected $it got ${this.fullImpression}\",\n                it,\n                this.fullImpression\n            )\n        }\n        visitedStates?.let { assertVisited(it) }\n    }\n\n    private fun assertVisited(states: IntArray) {\n        val expectedStates = mutableListOf<Int>()\n        states.forEach { expectedStates.add(it) }\n        for (state in expectedStates) {\n            if (!visitedStates.contains(state)) {\n                Assert.fail(\n                    \"Expected visited ${expectedStates.description()}, \" +\n                        \"got ${visitedStates.description()}\"\n                )\n            }\n        }\n        for (state in ALL_STATES) {\n            if (!expectedStates.contains(state) && visitedStates.contains(state)) {\n                Assert.fail(\n                    \"Expected ${state.description()} not visited, \" +\n                        \"got ${visitedStates.description()}\"\n                )\n            }\n        }\n    }\n\n    /**\n     * List of Int to VisibilityState constant names.\n     */\n    private fun List<Int>.description(): String {\n        val builder = StringBuilder(\"[\")\n        forEachIndexed { index, state ->\n            builder.append(state.description())\n            builder.append(if (index < size - 1) \",\" else \"\")\n        }\n        builder.append(\"]\")\n        return builder.toString()\n    }\n\n    companion object {\n        private const val TAG = \"VisibilityAssertHelper\"\n        /**\n         * Tolerance used for robolectric ui assertions when comparing data in pixels\n         */\n        private const val TOLERANCE_PIXELS = 1\n\n        private val ALL_STATES = intArrayOf(\n            VisibilityState.VISIBLE,\n            VisibilityState.INVISIBLE,\n            VisibilityState.FOCUSED_VISIBLE,\n            VisibilityState.UNFOCUSED_VISIBLE,\n            VisibilityState.PARTIAL_IMPRESSION_VISIBLE,\n            VisibilityState.PARTIAL_IMPRESSION_INVISIBLE,\n            VisibilityState.FULL_IMPRESSION_VISIBLE\n        )\n\n        /**\n         * Logs debug messages based on the flag in [EpoxyVisibilityTracker].\n         */\n        fun log(message: String) {\n            if (EpoxyVisibilityTracker.DEBUG_LOG) {\n                Log.d(TAG, message)\n            }\n        }\n\n        /**\n         * List of Int to VisibilityState constant names.\n         */\n        fun Int.description(): String {\n            return when (this) {\n                VisibilityState.VISIBLE -> \"VISIBLE\"\n                VisibilityState.INVISIBLE -> \"INVISIBLE\"\n                VisibilityState.FOCUSED_VISIBLE -> \"FOCUSED_VISIBLE\"\n                VisibilityState.UNFOCUSED_VISIBLE -> \"UNFOCUSED_VISIBLE\"\n                VisibilityState.PARTIAL_IMPRESSION_VISIBLE -> \"PARTIAL_IMPRESSION_VISIBLE\"\n                VisibilityState.PARTIAL_IMPRESSION_INVISIBLE -> \"PARTIAL_IMPRESSION_INVISIBLE\"\n                VisibilityState.FULL_IMPRESSION_VISIBLE -> \"FULL_IMPRESSION_VISIBLE\"\n                else -> throw IllegalStateException(\"Please declare new state here\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-kspsample/.gitignore",
    "content": "/build"
  },
  {
    "path": "epoxy-kspsample/build.gradle",
    "content": "plugins {\n  id 'com.android.application'\n  id 'kotlin-android'\n}\napply plugin: 'com.google.devtools.ksp'\n//apply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.ksp.sample'\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.compose.sample\"\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.COMPOSE_MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    versionCode 1\n    versionName \"1.0\"\n  }\n\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n    }\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\nksp {\n  arg(\"logEpoxyTimings\", \"true\")\n  arg(\"validateEpoxyModelUsage\", \"true\")\n}\n\ndependencies {\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n  ksp project(':epoxy-processor')\n  ksp rootProject.deps.parisProcessor\n\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidDesignLibrary\n  implementation rootProject.deps.paris\n  implementation rootProject.deps.androidCoreKtx\n}\n"
  },
  {
    "path": "epoxy-kspsample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application android:label=\"@string/app_name\">\n        <activity\n            android:name=\"com.airbnb.epoxy.ksp.sample.MainActivity\"\n            android:exported=\"true\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "epoxy-kspsample/src/main/java/com/airbnb/epoxy/ksp/sample/MainActivity.kt",
    "content": "package com.airbnb.epoxy.ksp.sample\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.ksp.sample.epoxyviews.headerView\n\nclass MainActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        findViewById<EpoxyRecyclerView>(R.id.epoxy_recycler_view).withModels {\n            headerView {\n                id(\"header\")\n                title(\"Hello World\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-kspsample/src/main/java/com/airbnb/epoxy/ksp/sample/epoxyviews/EpoxyConfig.kt",
    "content": "package com.airbnb.epoxy.ksp.sample.epoxyviews\n\nimport com.airbnb.epoxy.ksp.sample.R\nimport com.airbnb.paris.annotations.ParisConfig\n\n@ParisConfig(rClass = R::class)\nobject EpoxyConfig\n"
  },
  {
    "path": "epoxy-kspsample/src/main/java/com/airbnb/epoxy/ksp/sample/epoxyviews/HeaderView.kt",
    "content": "package com.airbnb.epoxy.ksp.sample.epoxyviews\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.ksp.sample.R\nimport com.airbnb.paris.annotations.Style\nimport com.airbnb.paris.annotations.Styleable\nimport com.airbnb.paris.extensions.headerViewStyle\nimport com.airbnb.paris.extensions.layoutHeight\nimport com.airbnb.paris.extensions.layoutWidth\n\n@Styleable // Dynamic styling via the Paris library\n@ModelView\nclass HeaderView(context: Context?) : LinearLayout(context) {\n    private var title: TextView? = null\n    private var caption: TextView? = null\n    private var image: ImageView? = null\n\n    init {\n        orientation = VERTICAL\n        inflate(getContext(), R.layout.header_view, this)\n\n        title = findViewById(R.id.title_text)\n        caption = findViewById(R.id.caption_text)\n        image = findViewById(R.id.image)\n    }\n\n    @TextProp(defaultRes = R.string.app_name)\n    fun setTitle(title: CharSequence?) {\n        this.title?.text = title\n    }\n\n    @TextProp\n    fun setCaption(caption: CharSequence?) {\n        this.caption?.text = caption\n    }\n\n    @JvmOverloads\n    @ModelProp\n    fun setShowImage(isVisible: Boolean = false) {\n        image?.visibility = if (isVisible) View.VISIBLE else View.GONE\n    }\n\n    companion object {\n        @Style(isDefault = true)\n        val headerStyle: com.airbnb.paris.styles.Style = headerViewStyle {\n            layoutWidth(ViewGroup.LayoutParams.MATCH_PARENT)\n            layoutHeight(ViewGroup.LayoutParams.MATCH_PARENT)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-kspsample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.EpoxyRecyclerView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/epoxy_recycler_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n</com.airbnb.epoxy.EpoxyRecyclerView>\n\n"
  },
  {
    "path": "epoxy-kspsample/src/main/res/layout/header_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:layout_gravity=\"center\"\n        android:id=\"@+id/image\"\n        android:layout_width=\"200dp\"\n        android:layout_height=\"200dp\"\n        android:visibility=\"gone\" />\n\n    <TextView\n        android:id=\"@+id/title_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:lineSpacingMultiplier=\"0.8\"\n        android:paddingTop=\"8dp\"\n        android:textColor=\"#000000\"\n        android:textSize=\"16sp\" />\n\n    <TextView\n        android:id=\"@+id/caption_text\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"8dp\"\n        android:gravity=\"center\"\n        android:textColor=\"#000000\"\n        android:textSize=\"20sp\"\n        tools:text=\"caption\" />\n\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-kspsample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy KSP Sample</string>\n</resources>"
  },
  {
    "path": "epoxy-modelfactory/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-modelfactory/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxymodelfactory'\n\n  defaultConfig {\n    minSdkVersion rootProject.PARIS_MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n}\n\ndependencies {\n  implementation project(':epoxy-adapter')\n  implementation rootProject.deps.paris\n  implementation rootProject.deps.androidRecyclerView\n}\n\n"
  },
  {
    "path": "epoxy-modelfactory/gradle.properties",
    "content": "POM_NAME=Epoxy Model Factory\nPOM_ARTIFACT_ID=epoxy-modelfactory\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-modelfactory/src/main/AndroidManifest.xml",
    "content": "<manifest />\n"
  },
  {
    "path": "epoxy-modelfactory/src/main/java/com/airbnb/epoxy/ModelProperties.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View.OnClickListener;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.RawRes;\n\nimport com.airbnb.paris.styles.Style;\n\nimport java.util.List;\n\npublic interface ModelProperties {\n\n  @NonNull\n  String getId();\n\n  boolean has(@NonNull String propertyName);\n\n  boolean getBoolean(@NonNull String propertyName);\n\n  double getDouble(@NonNull String propertyName);\n\n  @DrawableRes\n  int getDrawableRes(@NonNull String propertyName);\n\n  @Nullable\n  List<? extends EpoxyModel<?>> getEpoxyModelList(@NonNull String propertyName);\n\n  int getInt(@NonNull String propertyName);\n\n  long getLong(@NonNull String propertyName);\n\n  @Nullable\n  OnClickListener getOnClickListener(@NonNull String propertyName);\n\n  @RawRes\n  int getRawRes(@NonNull String propertyName);\n\n  @Nullable\n  String getString(@NonNull String propertyName);\n\n  @Nullable\n  List<String> getStringList(@NonNull String propertyName);\n\n  /**\n   * @return Null to apply the default style.\n   */\n  @Nullable\n  Style getStyle();\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-modelfactorytest/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.modelfactorytest'\n\n  defaultConfig {\n    minSdkVersion rootProject.PARIS_MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n  }\n\n  testOptions.unitTests.includeAndroidResources = true\n\n  testOptions {\n      unitTests {\n        all {\n          jvmArgs(\n              '--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',\n              '--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'\n          )\n        }\n      }\n    }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\nconfigurations.all { strategy ->\n  strategy.resolutionStrategy.force rootProject.deps.junit, rootProject.deps.robolectric,\n      rootProject.deps.mockito\n}\n\n// Java files in the \"resources\" folder are not included in the build for some reason (seems like source files are skipped?)\n// This files are needed to test the annotation processor, so we manually copy them into the build.\ntask('copyDebugTestResources', type: Copy) {\n  from(\"${projectDir}/src/test/resources\")\n  into(\"${buildDir}/intermediates/sourceFolderJavaResources/debug\")\n}\n\ntask('copyReleaseTestResources', type: Copy) {\n  from(\"${projectDir}/src/test/resources\")\n  into(\"${buildDir}/intermediates/sourceFolderJavaResources/release\")\n}\n\npreBuild.dependsOn copyReleaseTestResources\npreBuild.dependsOn copyDebugTestResources\n\ndependencies {\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-modelfactory')\n  implementation rootProject.deps.paris\n  implementation rootProject.deps.androidRecyclerView\n\n  kapt project(':epoxy-processor')\n\n  // Need to include the processors directly since we create an instance of it in code for testing\n  testImplementation project(':epoxy-processor')\n  testImplementation rootProject.deps.ksp\n  testImplementation rootProject.deps.parisProcessor\n\n  testImplementation project(':epoxy-processortest')\n  testImplementation \"io.github.java-diff-utils:java-diff-utils:4.5\"\n  testImplementation rootProject.deps.kotlinCompileTesting\n  testImplementation \"io.strikt:strikt-core:0.31.0\"\n  testImplementation rootProject.deps.googleTestingCompile\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.robolectric\n  testImplementation files(rootProject.file(\"libs/rt.jar\"))\n  testImplementation files(rootProject.file(\"libs/tools.jar\"))\n\n  // This is included in kotlinCompileTesting, but the version can be out of date with our kotlin\n  // compiler version, so we include it to force the right version\n  testImplementation rootProject.deps.kotlinAnnotationProcessingEmbeddable\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/main/AndroidManifest.xml",
    "content": "<manifest />\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/main/java/com/airbnb/epoxy/TestModelPropertiesKotlinView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport android.widget.FrameLayout\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.RawRes\nimport com.airbnb.epoxy.ModelView.Size\n\n@ModelView(autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\nclass TestModelPropertiesKotlinView(context: Context) : FrameLayout(context) {\n\n    @ModelProp\n    fun setBooleanValue(value: Boolean) {\n    }\n\n    @ModelProp\n    fun setDoubleValue(value: Double) {\n    }\n\n    @ModelProp\n    fun setDrawableRes(@DrawableRes value: Int) {\n    }\n\n    @ModelProp\n    fun setEpoxyModelList(value: List<EpoxyModel<*>>) {\n    }\n\n    @ModelProp\n    fun setIntValue(value: Int) {\n    }\n\n    @ModelProp\n    fun setLongValue(value: Long) {\n    }\n\n    @CallbackProp\n    override fun setOnClickListener(value: View.OnClickListener?) {\n    }\n\n    @ModelProp\n    fun setRawRes(@RawRes value: Int) {\n    }\n\n    @ModelProp\n    fun setStringValue(value: CharSequence) {\n    }\n\n    @ModelProp\n    fun setStringList(value: List<String>) {\n    }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/main/java/com/airbnb/epoxy/TestModelPropertiesView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.RawRes;\n\nimport com.airbnb.epoxy.ModelView.Size;\n\nimport java.util.List;\n\n@ModelView(autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\npublic class TestModelPropertiesView extends FrameLayout {\n\n  public TestModelPropertiesView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setBooleanValue(boolean value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedBooleanValue(Boolean value) {\n\n  }\n\n  @ModelProp\n  public void setDoubleValue(double value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedDoubleValue(Double value) {\n\n  }\n\n  @ModelProp\n  public void setDrawableRes(@DrawableRes int value) {\n\n  }\n\n  @ModelProp\n  public void setEpoxyModelList(List<? extends EpoxyModel<?>> value) {\n\n  }\n\n  @ModelProp\n  public void setIntValue(int value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedIntValue(Integer value) {\n\n  }\n\n  @ModelProp\n  public void setLongValue(long value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedLongValue(Long value) {\n\n  }\n\n  @CallbackProp\n  public void setOnClickListener(@Nullable OnClickListener value) {\n\n  }\n\n  @ModelProp\n  public void setRawRes(@RawRes int value) {\n\n  }\n\n  @ModelProp\n  public void setStringValue(CharSequence value) {\n\n  }\n\n  @ModelProp\n  public void setStringList(List<String> value) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy Model Factory Test</string>\n</resources>\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/java/com/airbnb/epoxy/FromModelPropertiesKotlinTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport com.airbnb.epoxymodelfactory.R\nimport com.airbnb.paris.styles.Style\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertFalse\nimport org.junit.Assert.assertNull\nimport org.junit.Test\n\n/**\n * Asserts that using from(ModelProperties) to create a model applies the property values correctly\n */\nclass FromModelPropertiesKotlinTest {\n\n    @Test\n    fun getId() {\n        val model = TestModelPropertiesKotlinViewModel_.from(\n            TestModelProperties(\n                id = \"100\"\n            )\n        )\n        assertFalse(model.hasDefaultId())\n    }\n\n    @Test\n    fun getBoolean() {\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    booleanValue = true\n                )\n            )\n        assertEquals(true, model.booleanValue())\n    }\n\n    @Test\n    fun getDouble() {\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    doubleValue = 42.0\n                )\n            )\n        assertEquals(42.0, model.doubleValue(), 0.0)\n    }\n\n    @Test\n    fun getDrawableRes() {\n        val drawableRes = android.R.drawable.alert_dark_frame\n        val model = TestModelPropertiesKotlinViewModel_.from(\n            TestModelProperties(\n                drawableRes = drawableRes\n            )\n        )\n        assertEquals(\n            drawableRes, model.drawableRes()\n        )\n    }\n\n    @Test\n    fun getEpoxyModelList() {\n        val epoxyModelList = emptyList<EpoxyModel<*>>()\n        val model = TestModelPropertiesKotlinViewModel_.from(\n            TestModelProperties(\n                epoxyModelList = epoxyModelList\n            )\n        )\n        assertEquals(epoxyModelList, model.epoxyModelList())\n    }\n\n    @Test\n    fun getInt() {\n        val model = TestModelPropertiesKotlinViewModel_.from(\n            TestModelProperties(\n                intValue = 51\n            )\n        )\n        assertEquals(51, model.intValue())\n    }\n\n    @Test\n    fun getLong() {\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    longValue = 3000000L\n                )\n            )\n        assertEquals(3000000L, model.longValue())\n    }\n\n    @Test\n    fun getOnClickListener() {\n        val clickListener = View.OnClickListener { }\n        val model = TestModelPropertiesKotlinViewModel_.from(\n            TestModelProperties(\n                onClickListener = clickListener\n            )\n        )\n        assertEquals(clickListener, model.onClickListener())\n    }\n\n    @Test\n    fun getNullOnClickListener() {\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    onClickListener = null\n                )\n            )\n        assertNull(model.onClickListener())\n    }\n\n    @Test\n    fun getRawRes() {\n        // We use an arbitrary int rather than adding a test-only raw resource, which isn't easy\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    rawRes = 42\n                )\n            )\n        assertEquals(42, model.rawRes())\n    }\n\n    @Test\n    fun getString() {\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    stringValue = \"ModelFactory\"\n                )\n            )\n        assertEquals(\"ModelFactory\", model.stringValue())\n    }\n\n    @Test\n    fun getStringList() {\n        val stringList = listOf(\"Model\", \"Factory\")\n        val model =\n            TestModelPropertiesKotlinViewModel_.from(\n                TestModelProperties(\n                    stringList = stringList\n                )\n            )\n        assertEquals(stringList, model.stringList())\n    }\n\n    class TestModelProperties(\n        private val id: String = \"\",\n        private val booleanValue: Boolean? = null,\n        private val doubleValue: Double? = null,\n        private val drawableRes: Int? = null,\n        private val epoxyModelList: List<EpoxyModel<*>>? = null,\n        private val intValue: Int? = null,\n        private val longValue: Long? = null,\n        private val onClickListener: View.OnClickListener? = null,\n        private val rawRes: Int? = null,\n        private val stringValue: String? = null,\n        private val stringList: List<String>? = null,\n        private val styleValue: Style? = null\n    ) : ModelProperties {\n\n        override fun getId() = id\n\n        override fun has(propertyName: String): Boolean {\n            return mapOf(\n                \"booleanValue\" to booleanValue,\n                \"doubleValue\" to doubleValue,\n                \"drawableRes\" to drawableRes,\n                \"epoxyModelList\" to epoxyModelList,\n                \"longValue\" to longValue,\n                \"intValue\" to intValue,\n                \"onClickListener\" to onClickListener,\n                \"rawRes\" to rawRes,\n                \"stringList\" to stringList,\n                \"stringValue\" to stringValue\n            )[propertyName] != null\n        }\n\n        override fun getBoolean(propertyName: String) = booleanValue!!\n\n        override fun getDouble(propertyName: String) = doubleValue!!\n\n        override fun getDrawableRes(propertyName: String) = drawableRes!!\n\n        override fun getEpoxyModelList(propertyName: String) = epoxyModelList!!\n\n        override fun getInt(propertyName: String) = intValue!!\n\n        override fun getLong(propertyName: String) = longValue!!\n\n        override fun getOnClickListener(propertyName: String) = onClickListener!!\n\n        override fun getRawRes(propertyName: String) = rawRes!!\n\n        override fun getString(propertyName: String) = stringValue!!\n\n        override fun getStringList(propertyName: String) = stringList!!\n\n        override fun getStyle() = styleValue\n    }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/java/com/airbnb/epoxy/FromModelPropertiesTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport com.airbnb.epoxymodelfactory.R\nimport com.airbnb.paris.styles.Style\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertFalse\nimport org.junit.Assert.assertNull\nimport org.junit.Test\n\n/**\n * Asserts that using from(ModelProperties) to create a model applies the property values correctly\n */\nclass FromModelPropertiesTest {\n\n    @Test\n    fun getId() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                id = \"100\"\n            )\n        )\n        assertFalse(model.hasDefaultId())\n    }\n\n    @Test\n    fun getBoolean() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                booleanValue = true\n            )\n        )\n        assertEquals(true, model.booleanValue())\n    }\n\n    @Test\n    fun getBoxedBoolean() {\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    boxedBooleanValue = true\n                )\n            )\n        assertEquals(true, model.boxedBooleanValue())\n    }\n\n    @Test\n    fun getDouble() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                doubleValue = 42.0\n            )\n        )\n        assertEquals(42.0, model.doubleValue(), 0.0)\n    }\n\n    @Test\n    fun getBoxedDouble() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                boxedDoubleValue = 42.0\n            )\n        )\n        assertEquals(42.0, model.boxedDoubleValue(), 0.0)\n    }\n\n    @Test\n    fun getDrawableRes() {\n        val drawableRes = android.R.drawable.alert_dark_frame\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    drawableRes = drawableRes\n                )\n            )\n        assertEquals(drawableRes, model.drawableRes())\n    }\n\n    @Test\n    fun getEpoxyModelList() {\n        val epoxyModelList = emptyList<EpoxyModel<*>>()\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    epoxyModelList = epoxyModelList\n                )\n            )\n        assertEquals(epoxyModelList, model.epoxyModelList())\n    }\n\n    @Test\n    fun getInt() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                intValue = 51\n            )\n        )\n        assertEquals(51, model.intValue())\n    }\n\n    @Test\n    fun getBoxedInt() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                boxedIntValue = 51\n            )\n        )\n        assertEquals(51, model.boxedIntValue())\n    }\n\n    @Test\n    fun getLong() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                longValue = 3000000\n            )\n        )\n        assertEquals(3000000, model.longValue())\n    }\n\n    @Test\n    fun getBoxedLong() {\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    boxedLongValue = 3000000\n                )\n            )\n        assertEquals(3000000, model.boxedLongValue())\n    }\n\n    @Test\n    fun getOnClickListener() {\n        val clickListener = View.OnClickListener { }\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    onClickListener = clickListener\n                )\n            )\n        assertEquals(clickListener, model.onClickListener())\n    }\n\n    @Test\n    fun getNullOnClickListener() {\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                onClickListener = null\n            )\n        )\n        assertNull(model.onClickListener())\n    }\n\n    @Test\n    fun getRawRes() {\n        // We use an arbitrary int rather than adding a test-only raw resource, which isn't easy\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    rawRes = 42\n                )\n            )\n        assertEquals(42, model.rawRes())\n    }\n\n    @Test\n    fun getString() {\n        val model =\n            TestModelPropertiesViewModel_.from(\n                TestModelProperties(\n                    stringValue = \"ModelFactory\"\n                )\n            )\n        assertEquals(\"ModelFactory\", model.stringValue())\n    }\n\n    @Test\n    fun getStringList() {\n        val stringList = listOf(\"Model\", \"Factory\")\n        val model = TestModelPropertiesViewModel_.from(\n            TestModelProperties(\n                stringList = stringList\n            )\n        )\n        assertEquals(stringList, model.stringList())\n    }\n\n    class TestModelProperties(\n        private val id: String = \"\",\n        private val booleanValue: Boolean? = null,\n        private val boxedBooleanValue: Boolean? = null,\n        private val doubleValue: Double? = null,\n        private val boxedDoubleValue: Double? = null,\n        private val drawableRes: Int? = null,\n        private val epoxyModelList: List<EpoxyModel<*>>? = null,\n        private val intValue: Int? = null,\n        private val boxedIntValue: Int? = null,\n        private val longValue: Long? = null,\n        private val boxedLongValue: Long? = null,\n        private val onClickListener: View.OnClickListener? = null,\n        private val rawRes: Int? = null,\n        private val stringValue: String? = null,\n        private val stringList: List<String>? = null,\n        private val styleValue: Style? = null\n    ) : ModelProperties {\n\n        private val propertyNameToValue = mapOf(\n            \"booleanValue\" to booleanValue,\n            \"boxedBooleanValue\" to boxedBooleanValue,\n            \"doubleValue\" to doubleValue,\n            \"boxedDoubleValue\" to boxedDoubleValue,\n            \"drawableRes\" to drawableRes,\n            \"epoxyModelList\" to epoxyModelList,\n            \"intValue\" to intValue,\n            \"boxedIntValue\" to boxedIntValue,\n            \"longValue\" to longValue,\n            \"boxedLongValue\" to boxedLongValue,\n            \"onClickListener\" to onClickListener,\n            \"rawRes\" to rawRes,\n            \"stringList\" to stringList,\n            \"stringValue\" to stringValue\n        )\n\n        @Suppress(\"UNCHECKED_CAST\")\n        private fun <T> getValue(propertyName: String): T = propertyNameToValue[propertyName]!! as T\n\n        override fun getId() = id\n\n        override fun has(propertyName: String) = propertyNameToValue[propertyName] != null\n\n        override fun getBoolean(propertyName: String): Boolean = getValue(propertyName)\n\n        override fun getDouble(propertyName: String): Double = getValue(propertyName)\n\n        override fun getDrawableRes(propertyName: String): Int = getValue(propertyName)\n\n        override fun getEpoxyModelList(propertyName: String): List<EpoxyModel<*>> =\n            getValue(propertyName)\n\n        override fun getInt(propertyName: String): Int = getValue(propertyName)\n\n        override fun getLong(propertyName: String): Long = getValue(propertyName)\n\n        override fun getOnClickListener(propertyName: String): View.OnClickListener =\n            getValue(propertyName)\n\n        override fun getRawRes(propertyName: String): Int = getValue(propertyName)\n\n        override fun getString(propertyName: String): String = getValue(propertyName)\n\n        override fun getStringList(propertyName: String): List<String> = getValue(propertyName)\n\n        override fun getStyle() = styleValue\n    }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/java/com/airbnb/epoxy/ModelFactoryViewProcessorTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\n\n@RunWith(RobolectricTestRunner::class)\nclass ModelFactoryViewProcessorTest {\n\n    @Test\n    fun baseModel() {\n        assertGeneration(\n            \"ModelFactoryBasicModelWithAttribute.java\",\n            \"ModelFactoryBasicModelWithAttribute_.java\"\n        )\n    }\n\n    @Test\n    fun baseModelWithFinalAttribute() {\n        assertGeneration(\n            \"BasicModelWithFinalAttribute.java\",\n            \"BasicModelWithFinalAttribute_.java\"\n        )\n    }\n\n    @Test\n    fun baseModelView() {\n        assertGeneration(\n            \"ModelFactoryBaseModelView.java\",\n            \"ModelFactoryBaseModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun groupPropSingleSupportedAttribute() {\n        assertGeneration(\n            \"GroupPropSingleSupportedAttributeModelView.java\",\n            \"GroupPropSingleSupportedAttributeModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun groupPropMultipleSupportedAttributeDifferentName() {\n        // Should generate a from method for both attributes since they have different names,\n        // despite being in the same group\n        assertGeneration(\n            \"GroupPropMultipleSupportedAttributeDifferentNameModelView.java\",\n            \"GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun groupPropMultipleSupportedAttributeSameName() {\n        // Shouldn't generate a from method, groups with multiple supported attribute types aren't\n        // supported\n        assertGeneration(\n            \"GroupPropMultipleSupportedAttributeSameNameModelView.java\",\n            \"GroupPropMultipleSupportedAttributeSameNameModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun callbackPropModelView() {\n        assertGeneration(\n            \"CallbackPropModelView.java\",\n            \"CallbackPropModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun textPropModelView() {\n        assertGeneration(\n            \"TextPropModelView.java\",\n            \"TextPropModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun allTypesModelView() {\n        assertGeneration(\n            \"AllTypesModelView.java\",\n            \"AllTypesModelViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun listSubtypeModelView() {\n        // Subtypes of List<String> are not supported so no from method should be generated here\n        assertGeneration(\n            \"ListSubtypeModelView.java\",\n            \"ListSubtypeModelViewModel_.java\"\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/java/com/airbnb/epoxy/ParisConfig.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.modelfactorytest.R\nimport com.airbnb.paris.annotations.ParisConfig\n\n@ParisConfig(rClass = R::class)\nobject ParisConfig\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/java/com/airbnb/epoxy/ProcessorTestUtils.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.processor.ControllerProcessor\nimport com.airbnb.epoxy.processor.ControllerProcessorProvider\nimport com.airbnb.epoxy.processor.DataBindingProcessor\nimport com.airbnb.epoxy.processor.DataBindingProcessorProvider\nimport com.airbnb.epoxy.processor.EpoxyProcessor\nimport com.airbnb.epoxy.processor.EpoxyProcessorProvider\nimport com.airbnb.epoxy.processor.ModelViewProcessor\nimport com.airbnb.epoxy.processor.ModelViewProcessorProvider\nimport com.airbnb.paris.processor.ParisProcessor\nimport com.github.difflib.DiffUtils\nimport com.google.common.truth.Truth.assert_\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.google.testing.compile.JavaFileObjects\nimport com.google.testing.compile.JavaSourcesSubject\nimport com.google.testing.compile.JavaSourcesSubjectFactory.javaSources\nimport com.tschuchort.compiletesting.KotlinCompilation\nimport com.tschuchort.compiletesting.SourceFile\nimport com.tschuchort.compiletesting.configureKsp\nimport com.tschuchort.compiletesting.kspProcessorOptions\nimport com.tschuchort.compiletesting.kspSourcesDir\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport strikt.api.expect\nimport strikt.api.expectThat\nimport strikt.assertions.doesNotContain\nimport strikt.assertions.isEmpty\nimport strikt.assertions.isNotNull\nimport java.io.File\nimport javax.annotation.processing.Processor\nimport javax.tools.JavaFileObject\n\ninternal object ProcessorTestUtils {\n\n    fun assertGeneration(\n        inputFile: String,\n        generatedFile: String,\n        useParis: Boolean = false,\n        helperObjects: List<JavaFileObject> = emptyList()\n    ) {\n        val inputFileUrl = inputFile.patchResource()\n        val model = JavaFileObjects.forResource(inputFileUrl)\n\n        val generatedFileUrl = generatedFile.patchResource()\n        val generatedModel = JavaFileObjects.forResource(generatedFileUrl)\n\n        assert_().about(javaSources())\n            .that(helperObjects + listOf(model))\n            .withAnnotationProcessorOptions(\n                \"logEpoxyTimings\" to true,\n                \"disableEpoxyKotlinExtensionGeneration\" to true,\n            )\n            .processedWith(processors(useParis))\n            .compilesWithoutError()\n            .and()\n            .generatesSources(generatedModel)\n\n        val generatedFile = File(generatedFileUrl.file)\n        testCodeGeneration(\n            sourceFiles = listOf(SourceFile.java(inputFile, inputFileUrl.readText())),\n            expectedOutput = listOf(generatedFile),\n            useKsp = false,\n            useParis = useParis\n        )\n\n        // KSP can't capture the original parameter names in java sources so it uses \"p0\"/\"p1\"/etc\n        // placeholders, which differs from kapt behavior. Due to this we can't directly compare them\n        // and instead maintain separate ksp expected sources.\n        val generatedKspFile = File(generatedFile.parent, \"/ksp/${generatedFile.name}\")\n        generatedKspFile.unpatchResource().let {\n            if (!it.exists()) {\n                it.parentFile?.mkdirs()\n                it.createNewFile()\n            }\n        }\n\n        testCodeGeneration(\n            sourceFiles = listOf(SourceFile.java(inputFile, inputFileUrl.readText())),\n            expectedOutput = listOf(generatedKspFile),\n            useKsp = true,\n            useParis = useParis\n        )\n    }\n\n    fun processors(useParis: Boolean = false): MutableList<Processor> {\n        return mutableListOf<Processor>().apply {\n            add(EpoxyProcessor())\n            add(ControllerProcessor())\n            add(DataBindingProcessor())\n            add(ModelViewProcessor())\n            if (useParis) add(ParisProcessor())\n        }\n    }\n\n    fun processorProviders(): List<SymbolProcessorProvider> {\n        return mutableListOf<SymbolProcessorProvider>().apply {\n            add(EpoxyProcessorProvider())\n            add(ControllerProcessorProvider())\n            add(DataBindingProcessorProvider())\n            add(ModelViewProcessorProvider())\n        }\n    }\n\n    /**\n     * Test that [sourceFiles] generate [expectedOutput].\n     * @param useKsp - If true ksp will be used as the annotation processing backend, if false, kapt will be used.\n     *\n     * You can set [UPDATE_TEST_SOURCES_ON_DIFF] to true to have the original sources file updated for the actual generated code.\n     */\n    fun testCodeGeneration(\n        sourceFiles: List<SourceFile>,\n        expectedOutput: List<File> = emptyList(),\n        unexpectedOutputFileName: List<String> = emptyList(),\n        useKsp: Boolean = true,\n        useParis: Boolean = false,\n        args: MutableMap<String, String> = mutableMapOf()\n    ) {\n        println(\"Using ksp: $useKsp\")\n        val compilation = KotlinCompilation().apply {\n            if (useKsp) configureKsp {\n                symbolProcessorProviders += processorProviders()\n                kspProcessorOptions.putAll(args)\n            } else {\n                annotationProcessors = processors(useParis)\n                kaptArgs = args\n            }\n            sources = sourceFiles\n            inheritClassPath = true\n            messageOutputStream = System.out\n        }\n        val result = compilation.compile()\n\n        val generatedSources = if (useKsp) {\n            compilation.kspSourcesDir.walk().filter { it.isFile }.toList()\n        } else {\n            result.sourcesGeneratedByAnnotationProcessor\n        }\n\n        if (result.exitCode != KotlinCompilation.ExitCode.OK) {\n            println(\"Generated:\")\n            generatedSources.forEach { println(it.readText()) }\n            error(\"Compilation failed with ${result.exitCode}.\")\n        }\n\n        println(\"Generated files:\")\n        generatedSources.forEach { println(it.name) }\n\n        expect {\n            expectedOutput.forEach { expectedOutputFile ->\n                val actualOutputFileName = expectedOutputFile.name\n                // Since we may encode output files as txt resources, we need to remove the suffix when comparing\n                // generated filename to expected filename.\n                val expectedOutputFilename = actualOutputFileName.removeSuffix(\".txt\")\n                val generated = generatedSources.find { it.name == expectedOutputFilename }\n                that(generated) {\n                    isNotNull().and {\n                        val patch =\n                            DiffUtils.diff(generated!!.readLines(), expectedOutputFile.readLines())\n                        if (patch.deltas.isNotEmpty()) {\n                            println(\"Found differences for $expectedOutputFilename!\")\n                            println(\"Actual filename in filesystem is $actualOutputFileName\")\n                            println(\"Expected:\\n\")\n                            println(expectedOutputFile.readText())\n                            println(\"Generated:\\n\")\n                            println(generated.readText())\n\n                            println(\"Expected source is at: ${expectedOutputFile.unpatchResource()}\")\n                            val actualFile = File(\n                                expectedOutputFile.parent,\n                                \"actual/${expectedOutputFile.name}\"\n                            ).apply {\n                                parentFile?.mkdirs()\n                                writeText(generated.readText())\n                            }\n                            println(\"Actual source is at: $actualFile\")\n                            if (UPDATE_TEST_SOURCES_ON_DIFF) {\n                                println(\"UPDATE_TEST_SOURCES_ON_DIFF is enabled; updating expected sources with actual sources.\")\n                                expectedOutputFile.unpatchResource().apply {\n                                    parentFile?.mkdirs()\n                                    writeText(generated.readText())\n                                }\n                            }\n                        }\n                        that(patch.deltas).isEmpty()\n                    }\n                }.describedAs(expectedOutputFilename)\n            }\n        }\n        val generatedFileNames = generatedSources.map { it.name }\n        if (unexpectedOutputFileName.isNotEmpty()) {\n            expectThat(generatedFileNames).doesNotContain(unexpectedOutputFileName)\n        }\n    }\n\n    // See epoxy-processortest/src/test/java/com/airbnb/epoxy/GuavaPatch.kt\n    private fun String.patchResource() =\n        File(\"build/intermediates/sourceFolderJavaResources/debug/$this\").toURI().toURL()\n\n    fun File.unpatchResource(): File = File(\n        canonicalPath.replace(\n            \"build/intermediates/sourceFolderJavaResources/debug/\",\n            \"src/test/resources/\"\n        )\n    )\n\n    fun JavaSourcesSubject.withAnnotationProcessorOptions(vararg option: Pair<String, Any>): JavaSourcesSubject {\n        return withCompilerOptions(option.map { it.first setTo it.second })\n    }\n\n    infix fun String.setTo(value: Any) = \"-A$this=$value\"\n}\n\nenum class CompilationMode(val testKapt: Boolean, val testKSP: Boolean) {\n    KSP(testKapt = false, testKSP = true),\n    KAPT(testKapt = true, testKSP = false),\n    ALL(testKapt = true, testKSP = true)\n}\n\n/**\n * Change to true to have tests auto update the expected sources files for easy updating of tests.\n */\nconst val UPDATE_TEST_SOURCES_ON_DIFF = true\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/AllTypesModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.RawRes;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\nimport java.util.List;\n\n@ModelView(defaultLayout = 1)\npublic class AllTypesModelView extends FrameLayout {\n\n  public AllTypesModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setBooleanValue(boolean value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedBooleanValue(Boolean value) {\n\n  }\n\n  @ModelProp\n  public void setCharSequenceValue(CharSequence value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedDoubleValue(Double value) {\n\n  }\n\n  @ModelProp\n  public void setDoubleValue(double value) {\n\n  }\n\n  @ModelProp\n  public void setDrawableRes(@DrawableRes int value) {\n\n  }\n\n  @ModelProp\n  public void setEpoxyModelList(List<? extends EpoxyModel<?>> value) {\n\n  }\n\n  @ModelProp\n  public void setIntValue(int value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedIntValue(Integer value) {\n\n  }\n\n  @ModelProp\n  public void setLongValue(long value) {\n\n  }\n\n  @ModelProp\n  public void setBoxedLongValue(Long value) {\n\n  }\n\n  @ModelProp({ Option.DoNotHash })\n  public void setOnClickListener(OnClickListener value) {\n\n  }\n\n  @ModelProp\n  public void setRawRes(@RawRes int value) {\n\n  }\n\n  @ModelProp\n  public void setStringValue(String value) {\n\n  }\n\n  @ModelProp\n  public void setStringList(List<String> value) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/AllTypesModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.RawRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Double;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> implements GeneratedModel<AllTypesModelView>, AllTypesModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(15);\n\n  private OnModelBoundListener<AllTypesModelViewModel_, AllTypesModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AllTypesModelViewModel_, AllTypesModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AllTypesModelViewModel_, AllTypesModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AllTypesModelViewModel_, AllTypesModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private boolean booleanValue_Boolean = false;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private Boolean boxedBooleanValue_Boolean;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence charSequenceValue_CharSequence;\n\n  /**\n   * Bitset index: 3\n   */\n  @NonNull\n  private Double boxedDoubleValue_Double;\n\n  private double doubleValue_Double = 0.0d;\n\n  @DrawableRes\n  private int drawableRes_Int = 0;\n\n  /**\n   * Bitset index: 6\n   */\n  @NonNull\n  private List<? extends EpoxyModel<?>> epoxyModelList_List;\n\n  private int intValue_Int = 0;\n\n  /**\n   * Bitset index: 8\n   */\n  @NonNull\n  private Integer boxedIntValue_Integer;\n\n  private long longValue_Long = 0L;\n\n  /**\n   * Bitset index: 10\n   */\n  @NonNull\n  private Long boxedLongValue_Long;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private View.OnClickListener onClickListener_OnClickListener;\n\n  @RawRes\n  private int rawRes_Int = 0;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private String stringValue_String;\n\n  /**\n   * Bitset index: 14\n   */\n  @NonNull\n  private List<String> stringList_List;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(8)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedIntValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedBooleanValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(3)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedDoubleValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(6)) {\n    \tthrow new IllegalStateException(\"A value is required for setEpoxyModelList\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(10)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedLongValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(14)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringList\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(11)) {\n    \tthrow new IllegalStateException(\"A value is required for setOnClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setCharSequenceValue\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final AllTypesModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AllTypesModelView object) {\n    super.bind(object);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setBoxedIntValue(boxedIntValue_Integer);\n    object.setBoxedBooleanValue(boxedBooleanValue_Boolean);\n    object.setBoxedDoubleValue(boxedDoubleValue_Double);\n    object.setEpoxyModelList(epoxyModelList_List);\n    object.setBoxedLongValue(boxedLongValue_Long);\n    object.setLongValue(longValue_Long);\n    object.setStringList(stringList_List);\n    object.setStringValue(stringValue_String);\n    object.setOnClickListener(onClickListener_OnClickListener);\n    object.setIntValue(intValue_Int);\n    object.setDrawableRes(drawableRes_Int);\n    object.setDoubleValue(doubleValue_Double);\n    object.setRawRes(rawRes_Int);\n    object.setCharSequenceValue(charSequenceValue_CharSequence);\n  }\n\n  @Override\n  public void bind(final AllTypesModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AllTypesModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    AllTypesModelViewModel_ that = (AllTypesModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((booleanValue_Boolean != that.booleanValue_Boolean)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((boxedIntValue_Integer != null ? !boxedIntValue_Integer.equals(that.boxedIntValue_Integer) : that.boxedIntValue_Integer != null)) {\n      object.setBoxedIntValue(boxedIntValue_Integer);\n    }\n\n    if ((boxedBooleanValue_Boolean != null ? !boxedBooleanValue_Boolean.equals(that.boxedBooleanValue_Boolean) : that.boxedBooleanValue_Boolean != null)) {\n      object.setBoxedBooleanValue(boxedBooleanValue_Boolean);\n    }\n\n    if ((boxedDoubleValue_Double != null ? !boxedDoubleValue_Double.equals(that.boxedDoubleValue_Double) : that.boxedDoubleValue_Double != null)) {\n      object.setBoxedDoubleValue(boxedDoubleValue_Double);\n    }\n\n    if ((epoxyModelList_List != null ? !epoxyModelList_List.equals(that.epoxyModelList_List) : that.epoxyModelList_List != null)) {\n      object.setEpoxyModelList(epoxyModelList_List);\n    }\n\n    if ((boxedLongValue_Long != null ? !boxedLongValue_Long.equals(that.boxedLongValue_Long) : that.boxedLongValue_Long != null)) {\n      object.setBoxedLongValue(boxedLongValue_Long);\n    }\n\n    if ((longValue_Long != that.longValue_Long)) {\n      object.setLongValue(longValue_Long);\n    }\n\n    if ((stringList_List != null ? !stringList_List.equals(that.stringList_List) : that.stringList_List != null)) {\n      object.setStringList(stringList_List);\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      object.setOnClickListener(onClickListener_OnClickListener);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if ((drawableRes_Int != that.drawableRes_Int)) {\n      object.setDrawableRes(drawableRes_Int);\n    }\n\n    if ((Double.compare(that.doubleValue_Double, doubleValue_Double) != 0)) {\n      object.setDoubleValue(doubleValue_Double);\n    }\n\n    if ((rawRes_Int != that.rawRes_Int)) {\n      object.setRawRes(rawRes_Int);\n    }\n\n    if ((charSequenceValue_CharSequence != null ? !charSequenceValue_CharSequence.equals(that.charSequenceValue_CharSequence) : that.charSequenceValue_CharSequence != null)) {\n      object.setCharSequenceValue(charSequenceValue_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AllTypesModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AllTypesModelViewModel_ onBind(\n      OnModelBoundListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AllTypesModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AllTypesModelViewModel_ onUnbind(\n      OnModelUnboundListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final AllTypesModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AllTypesModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AllTypesModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AllTypesModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see AllTypesModelView#setBooleanValue(boolean)\n   */\n  public AllTypesModelViewModel_ booleanValue(boolean booleanValue) {\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  public boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedBooleanValue(Boolean)\n   */\n  public AllTypesModelViewModel_ boxedBooleanValue(@NonNull Boolean boxedBooleanValue) {\n    if (boxedBooleanValue == null) {\n      throw new IllegalArgumentException(\"boxedBooleanValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.boxedBooleanValue_Boolean = boxedBooleanValue;\n    return this;\n  }\n\n  @NonNull\n  public Boolean boxedBooleanValue() {\n    return boxedBooleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setCharSequenceValue(CharSequence)\n   */\n  public AllTypesModelViewModel_ charSequenceValue(@NonNull CharSequence charSequenceValue) {\n    if (charSequenceValue == null) {\n      throw new IllegalArgumentException(\"charSequenceValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.charSequenceValue_CharSequence = charSequenceValue;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence charSequenceValue() {\n    return charSequenceValue_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedDoubleValue(Double)\n   */\n  public AllTypesModelViewModel_ boxedDoubleValue(@NonNull Double boxedDoubleValue) {\n    if (boxedDoubleValue == null) {\n      throw new IllegalArgumentException(\"boxedDoubleValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(3);\n    onMutation();\n    this.boxedDoubleValue_Double = boxedDoubleValue;\n    return this;\n  }\n\n  @NonNull\n  public Double boxedDoubleValue() {\n    return boxedDoubleValue_Double;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0.0d\n   *\n   * @see AllTypesModelView#setDoubleValue(double)\n   */\n  public AllTypesModelViewModel_ doubleValue(double doubleValue) {\n    onMutation();\n    this.doubleValue_Double = doubleValue;\n    return this;\n  }\n\n  public double doubleValue() {\n    return doubleValue_Double;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setDrawableRes(int)\n   */\n  public AllTypesModelViewModel_ drawableRes(@DrawableRes int drawableRes) {\n    onMutation();\n    this.drawableRes_Int = drawableRes;\n    return this;\n  }\n\n  @DrawableRes\n  public int drawableRes() {\n    return drawableRes_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setEpoxyModelList(List<? extends EpoxyModel<?>>)\n   */\n  public AllTypesModelViewModel_ epoxyModelList(\n      @NonNull List<? extends EpoxyModel<?>> epoxyModelList) {\n    if (epoxyModelList == null) {\n      throw new IllegalArgumentException(\"epoxyModelList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    onMutation();\n    this.epoxyModelList_List = epoxyModelList;\n    return this;\n  }\n\n  @NonNull\n  public List<? extends EpoxyModel<?>> epoxyModelList() {\n    return epoxyModelList_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setIntValue(int)\n   */\n  public AllTypesModelViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedIntValue(Integer)\n   */\n  public AllTypesModelViewModel_ boxedIntValue(@NonNull Integer boxedIntValue) {\n    if (boxedIntValue == null) {\n      throw new IllegalArgumentException(\"boxedIntValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    onMutation();\n    this.boxedIntValue_Integer = boxedIntValue;\n    return this;\n  }\n\n  @NonNull\n  public Integer boxedIntValue() {\n    return boxedIntValue_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see AllTypesModelView#setLongValue(long)\n   */\n  public AllTypesModelViewModel_ longValue(long longValue) {\n    onMutation();\n    this.longValue_Long = longValue;\n    return this;\n  }\n\n  public long longValue() {\n    return longValue_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedLongValue(Long)\n   */\n  public AllTypesModelViewModel_ boxedLongValue(@NonNull Long boxedLongValue) {\n    if (boxedLongValue == null) {\n      throw new IllegalArgumentException(\"boxedLongValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.boxedLongValue_Long = boxedLongValue;\n    return this;\n  }\n\n  @NonNull\n  public Long boxedLongValue() {\n    return boxedLongValue_Long;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public AllTypesModelViewModel_ onClickListener(\n      @NonNull final OnModelClickListener<AllTypesModelViewModel_, AllTypesModelView> onClickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    if (onClickListener == null) {\n      this.onClickListener_OnClickListener = null;\n    }\n    else {\n      this.onClickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(onClickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setOnClickListener(View.OnClickListener)\n   */\n  public AllTypesModelViewModel_ onClickListener(@NonNull View.OnClickListener onClickListener) {\n    if (onClickListener == null) {\n      throw new IllegalArgumentException(\"onClickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    this.onClickListener_OnClickListener = onClickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener onClickListener() {\n    return onClickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setRawRes(int)\n   */\n  public AllTypesModelViewModel_ rawRes(@RawRes int rawRes) {\n    onMutation();\n    this.rawRes_Int = rawRes;\n    return this;\n  }\n\n  @RawRes\n  public int rawRes() {\n    return rawRes_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setStringValue(String)\n   */\n  public AllTypesModelViewModel_ stringValue(@NonNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NonNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setStringList(List<String>)\n   */\n  public AllTypesModelViewModel_ stringList(@NonNull List<String> stringList) {\n    if (stringList == null) {\n      throw new IllegalArgumentException(\"stringList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(14);\n    onMutation();\n    this.stringList_List = stringList;\n    return this;\n  }\n\n  @NonNull\n  public List<String> stringList() {\n    return stringList_List;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.booleanValue_Boolean = false;\n    this.boxedBooleanValue_Boolean = null;\n    this.charSequenceValue_CharSequence = null;\n    this.boxedDoubleValue_Double = null;\n    this.doubleValue_Double = 0.0d;\n    this.drawableRes_Int = 0;\n    this.epoxyModelList_List = null;\n    this.intValue_Int = 0;\n    this.boxedIntValue_Integer = null;\n    this.longValue_Long = 0L;\n    this.boxedLongValue_Long = null;\n    this.onClickListener_OnClickListener = null;\n    this.rawRes_Int = 0;\n    this.stringValue_String = null;\n    this.stringList_List = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AllTypesModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AllTypesModelViewModel_ that = (AllTypesModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((booleanValue_Boolean != that.booleanValue_Boolean)) {\n      return false;\n    }\n    if ((boxedBooleanValue_Boolean != null ? !boxedBooleanValue_Boolean.equals(that.boxedBooleanValue_Boolean) : that.boxedBooleanValue_Boolean != null)) {\n      return false;\n    }\n    if ((charSequenceValue_CharSequence != null ? !charSequenceValue_CharSequence.equals(that.charSequenceValue_CharSequence) : that.charSequenceValue_CharSequence != null)) {\n      return false;\n    }\n    if ((boxedDoubleValue_Double != null ? !boxedDoubleValue_Double.equals(that.boxedDoubleValue_Double) : that.boxedDoubleValue_Double != null)) {\n      return false;\n    }\n    if ((Double.compare(that.doubleValue_Double, doubleValue_Double) != 0)) {\n      return false;\n    }\n    if ((drawableRes_Int != that.drawableRes_Int)) {\n      return false;\n    }\n    if ((epoxyModelList_List != null ? !epoxyModelList_List.equals(that.epoxyModelList_List) : that.epoxyModelList_List != null)) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((boxedIntValue_Integer != null ? !boxedIntValue_Integer.equals(that.boxedIntValue_Integer) : that.boxedIntValue_Integer != null)) {\n      return false;\n    }\n    if ((longValue_Long != that.longValue_Long)) {\n      return false;\n    }\n    if ((boxedLongValue_Long != null ? !boxedLongValue_Long.equals(that.boxedLongValue_Long) : that.boxedLongValue_Long != null)) {\n      return false;\n    }\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((rawRes_Int != that.rawRes_Int)) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if ((stringList_List != null ? !stringList_List.equals(that.stringList_List) : that.stringList_List != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + (booleanValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (boxedBooleanValue_Boolean != null ? boxedBooleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + (charSequenceValue_CharSequence != null ? charSequenceValue_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (boxedDoubleValue_Double != null ? boxedDoubleValue_Double.hashCode() : 0);\n    temp = Double.doubleToLongBits(doubleValue_Double);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + drawableRes_Int;\n    _result = 31 * _result + (epoxyModelList_List != null ? epoxyModelList_List.hashCode() : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + (boxedIntValue_Integer != null ? boxedIntValue_Integer.hashCode() : 0);\n    _result = 31 * _result + (int) (longValue_Long ^ (longValue_Long >>> 32));\n    _result = 31 * _result + (boxedLongValue_Long != null ? boxedLongValue_Long.hashCode() : 0);\n    _result = 31 * _result + (onClickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + rawRes_Int;\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (stringList_List != null ? stringList_List.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AllTypesModelViewModel_{\" +\n        \"booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", boxedBooleanValue_Boolean=\" + boxedBooleanValue_Boolean +\n        \", charSequenceValue_CharSequence=\" + charSequenceValue_CharSequence +\n        \", boxedDoubleValue_Double=\" + boxedDoubleValue_Double +\n        \", doubleValue_Double=\" + doubleValue_Double +\n        \", drawableRes_Int=\" + drawableRes_Int +\n        \", epoxyModelList_List=\" + epoxyModelList_List +\n        \", intValue_Int=\" + intValue_Int +\n        \", boxedIntValue_Integer=\" + boxedIntValue_Integer +\n        \", longValue_Long=\" + longValue_Long +\n        \", boxedLongValue_Long=\" + boxedLongValue_Long +\n        \", onClickListener_OnClickListener=\" + onClickListener_OnClickListener +\n        \", rawRes_Int=\" + rawRes_Int +\n        \", stringValue_String=\" + stringValue_String +\n        \", stringList_List=\" + stringList_List +\n        \"}\" + super.toString();\n  }\n\n  public static AllTypesModelViewModel_ from(ModelProperties properties) {\n    AllTypesModelViewModel_ model = new AllTypesModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"booleanValue\")) {\n      model.booleanValue(properties.getBoolean(\"booleanValue\"));\n    }\n    if (properties.has(\"boxedBooleanValue\")) {\n      model.boxedBooleanValue(properties.getBoolean(\"boxedBooleanValue\"));\n    }\n    if (properties.has(\"charSequenceValue\")) {\n      model.charSequenceValue(properties.getString(\"charSequenceValue\"));\n    }\n    if (properties.has(\"boxedDoubleValue\")) {\n      model.boxedDoubleValue(properties.getDouble(\"boxedDoubleValue\"));\n    }\n    if (properties.has(\"doubleValue\")) {\n      model.doubleValue(properties.getDouble(\"doubleValue\"));\n    }\n    if (properties.has(\"drawableRes\")) {\n      model.drawableRes(properties.getDrawableRes(\"drawableRes\"));\n    }\n    if (properties.has(\"epoxyModelList\")) {\n      model.epoxyModelList(properties.getEpoxyModelList(\"epoxyModelList\"));\n    }\n    if (properties.has(\"intValue\")) {\n      model.intValue(properties.getInt(\"intValue\"));\n    }\n    if (properties.has(\"boxedIntValue\")) {\n      model.boxedIntValue(properties.getInt(\"boxedIntValue\"));\n    }\n    if (properties.has(\"longValue\")) {\n      model.longValue(properties.getLong(\"longValue\"));\n    }\n    if (properties.has(\"boxedLongValue\")) {\n      model.boxedLongValue(properties.getLong(\"boxedLongValue\"));\n    }\n    if (properties.has(\"onClickListener\")) {\n      model.onClickListener(properties.getOnClickListener(\"onClickListener\"));\n    }\n    if (properties.has(\"rawRes\")) {\n      model.rawRes(properties.getRawRes(\"rawRes\"));\n    }\n    if (properties.has(\"stringValue\")) {\n      model.stringValue(properties.getString(\"stringValue\"));\n    }\n    if (properties.has(\"stringList\")) {\n      model.stringList(properties.getStringList(\"stringList\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/BasicModelWithFinalAttribute.java",
    "content": "package com.airbnb.epoxy;\n\npublic class BasicModelWithFinalAttribute extends EpoxyModel<Object> {\n  @EpoxyAttribute final int value;\n\n  public BasicModelWithFinalAttribute() {\n    value = 0;\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/BasicModelWithFinalAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BasicModelWithFinalAttribute_ extends BasicModelWithFinalAttribute implements GeneratedModel<Object>, BasicModelWithFinalAttributeBuilder {\n  private OnModelBoundListener<BasicModelWithFinalAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BasicModelWithFinalAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BasicModelWithFinalAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BasicModelWithFinalAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public BasicModelWithFinalAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithFinalAttribute_ onBind(\n      OnModelBoundListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithFinalAttribute_ onUnbind(\n      OnModelUnboundListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithFinalAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithFinalAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BasicModelWithFinalAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BasicModelWithFinalAttribute_ that = (BasicModelWithFinalAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BasicModelWithFinalAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/CallbackPropModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\nimport androidx.annotation.Nullable;\n\n@ModelView(defaultLayout = 1)\npublic class CallbackPropModelView extends FrameLayout {\n\n  public CallbackPropModelView(Context context) {\n    super(context);\n  }\n\n  @CallbackProp\n  public void setOnClickListener(@Nullable OnClickListener listener) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/CallbackPropModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class CallbackPropModelViewModel_ extends EpoxyModel<CallbackPropModelView> implements GeneratedModel<CallbackPropModelView>, CallbackPropModelViewModelBuilder {\n  private OnModelBoundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener onClickListener_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final CallbackPropModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final CallbackPropModelView object) {\n    super.bind(object);\n    object.setOnClickListener(onClickListener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final CallbackPropModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof CallbackPropModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    CallbackPropModelViewModel_ that = (CallbackPropModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      object.setOnClickListener(onClickListener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final CallbackPropModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CallbackPropModelViewModel_ onBind(\n      OnModelBoundListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(CallbackPropModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setOnClickListener((View.OnClickListener) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CallbackPropModelViewModel_ onUnbind(\n      OnModelUnboundListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final CallbackPropModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CallbackPropModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final CallbackPropModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CallbackPropModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public CallbackPropModelViewModel_ onClickListener(\n      @Nullable final OnModelClickListener<CallbackPropModelViewModel_, CallbackPropModelView> onClickListener) {\n    onMutation();\n    if (onClickListener == null) {\n      this.onClickListener_OnClickListener = null;\n    }\n    else {\n      this.onClickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(onClickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see CallbackPropModelView#setOnClickListener(View.OnClickListener)\n   */\n  public CallbackPropModelViewModel_ onClickListener(\n      @Nullable View.OnClickListener onClickListener) {\n    onMutation();\n    this.onClickListener_OnClickListener = onClickListener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener onClickListener() {\n    return onClickListener_OnClickListener;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.onClickListener_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof CallbackPropModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    CallbackPropModelViewModel_ that = (CallbackPropModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onClickListener_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"CallbackPropModelViewModel_{\" +\n        \"onClickListener_OnClickListener=\" + onClickListener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  public static CallbackPropModelViewModel_ from(ModelProperties properties) {\n    CallbackPropModelViewModel_ model = new CallbackPropModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"onClickListener\")) {\n      model.onClickListener(properties.getOnClickListener(\"onClickListener\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropMultipleSupportedAttributeDifferentNameModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class GroupPropMultipleSupportedAttributeDifferentNameModelView extends FrameLayout {\n\n  public GroupPropMultipleSupportedAttributeDifferentNameModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(group = \"title\")\n  public void setTitleString(String title) {\n\n  }\n\n  @ModelProp(group = \"title\")\n  public void setTitleInt(int title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ extends EpoxyModel<GroupPropMultipleSupportedAttributeDifferentNameModelView> implements GeneratedModel<GroupPropMultipleSupportedAttributeDifferentNameModelView>, GroupPropMultipleSupportedAttributeDifferentNameModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String titleString_String;\n\n  /**\n   * Bitset index: 1\n   */\n  private int titleInt_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitleString(titleString_String);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n    else {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n        object.setTitleString(titleString_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((titleInt_Int != that.titleInt_Int)) {\n        object.setTitleInt(titleInt_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropMultipleSupportedAttributeDifferentNameModelView#setTitleString(String)\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ titleString(\n      @NonNull String titleString) {\n    if (titleString == null) {\n      throw new IllegalArgumentException(\"titleString cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.titleInt_Int = 0;\n    onMutation();\n    this.titleString_String = titleString;\n    return this;\n  }\n\n  @NonNull\n  public String titleStringString() {\n    return titleString_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see GroupPropMultipleSupportedAttributeDifferentNameModelView#setTitleInt(int)\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ titleInt(int titleInt) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.titleString_String = null;\n    onMutation();\n    this.titleInt_Int = titleInt;\n    return this;\n  }\n\n  public int titleIntInt() {\n    return titleInt_Int;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ layout(\n      @LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.titleString_String = null;\n    this.titleInt_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n      return false;\n    }\n    if ((titleInt_Int != that.titleInt_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (titleString_String != null ? titleString_String.hashCode() : 0);\n    _result = 31 * _result + titleInt_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_{\" +\n        \"titleString_String=\" + titleString_String +\n        \", titleInt_Int=\" + titleInt_Int +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ from(\n      ModelProperties properties) {\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ model = new GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"titleString\")) {\n      model.titleString(properties.getString(\"titleString\"));\n    } else if (properties.has(\"titleInt\")) {\n      model.titleInt(properties.getInt(\"titleInt\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropMultipleSupportedAttributeSameNameModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class GroupPropMultipleSupportedAttributeSameNameModelView extends FrameLayout {\n\n  public GroupPropMultipleSupportedAttributeSameNameModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(group = \"title\")\n  public void setTitleString(String title) {\n\n  }\n\n  @ModelProp(group = \"title\")\n  public void setTitleInt(int title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropMultipleSupportedAttributeSameNameModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropMultipleSupportedAttributeSameNameModelViewModel_ extends EpoxyModel<GroupPropMultipleSupportedAttributeSameNameModelView> implements GeneratedModel<GroupPropMultipleSupportedAttributeSameNameModelView>, GroupPropMultipleSupportedAttributeSameNameModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String titleString_String;\n\n  /**\n   * Bitset index: 1\n   */\n  private int titleInt_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitleString(titleString_String);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n    else {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeSameNameModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropMultipleSupportedAttributeSameNameModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeSameNameModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n        object.setTitleString(titleString_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((titleInt_Int != that.titleInt_Int)) {\n        object.setTitleInt(titleInt_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropMultipleSupportedAttributeSameNameModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropMultipleSupportedAttributeSameNameModelView#setTitleString(String)\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ titleString(\n      @NonNull String titleString) {\n    if (titleString == null) {\n      throw new IllegalArgumentException(\"titleString cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.titleInt_Int = 0;\n    onMutation();\n    this.titleString_String = titleString;\n    return this;\n  }\n\n  @NonNull\n  public String titleStringString() {\n    return titleString_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see GroupPropMultipleSupportedAttributeSameNameModelView#setTitleInt(int)\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ titleInt(int titleInt) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.titleString_String = null;\n    onMutation();\n    this.titleInt_Int = titleInt;\n    return this;\n  }\n\n  public int titleIntInt() {\n    return titleInt_Int;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ layout(\n      @LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.titleString_String = null;\n    this.titleInt_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropMultipleSupportedAttributeSameNameModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeSameNameModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n      return false;\n    }\n    if ((titleInt_Int != that.titleInt_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (titleString_String != null ? titleString_String.hashCode() : 0);\n    _result = 31 * _result + titleInt_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropMultipleSupportedAttributeSameNameModelViewModel_{\" +\n        \"titleString_String=\" + titleString_String +\n        \", titleInt_Int=\" + titleInt_Int +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropMultipleSupportedAttributeSameNameModelViewModel_ from(\n      ModelProperties properties) {\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ model = new GroupPropMultipleSupportedAttributeSameNameModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"titleString\")) {\n      model.titleString(properties.getString(\"titleString\"));\n    } else if (properties.has(\"titleInt\")) {\n      model.titleInt(properties.getInt(\"titleInt\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropSingleSupportedAttributeModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class GroupPropSingleSupportedAttributeModelView extends FrameLayout {\n\n  public GroupPropSingleSupportedAttributeModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(String title) {\n\n  }\n\n  @ModelProp({ Option.IgnoreRequireHashCode })\n  public void setTitle(Object title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/GroupPropSingleSupportedAttributeModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropSingleSupportedAttributeModelViewModel_ extends EpoxyModel<GroupPropSingleSupportedAttributeModelView> implements GeneratedModel<GroupPropSingleSupportedAttributeModelView>, GroupPropSingleSupportedAttributeModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String title_String;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private Object title_Object;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0) && !assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropSingleSupportedAttributeModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropSingleSupportedAttributeModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitle(title_String);\n    }\n    else {\n      object.setTitle(title_Object);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropSingleSupportedAttributeModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropSingleSupportedAttributeModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropSingleSupportedAttributeModelViewModel_ that = (GroupPropSingleSupportedAttributeModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n        object.setTitle(title_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(1) || (title_Object != null ? !title_Object.equals(that.title_Object) : that.title_Object != null)) {\n        object.setTitle(title_Object);\n      }\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropSingleSupportedAttributeModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropSingleSupportedAttributeModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropSingleSupportedAttributeModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropSingleSupportedAttributeModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropSingleSupportedAttributeModelView#setTitle(String)\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ title(@NonNull String title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.title_Object = null;\n    onMutation();\n    this.title_String = title;\n    return this;\n  }\n\n  @NonNull\n  public String titleString() {\n    return title_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropSingleSupportedAttributeModelView#setTitle(Object)\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ title(@NonNull Object title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.title_String = null;\n    onMutation();\n    this.title_Object = title;\n    return this;\n  }\n\n  @NonNull\n  public Object titleObject() {\n    return title_Object;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_String = null;\n    this.title_Object = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropSingleSupportedAttributeModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropSingleSupportedAttributeModelViewModel_ that = (GroupPropSingleSupportedAttributeModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      return false;\n    }\n    if ((title_Object != null ? !title_Object.equals(that.title_Object) : that.title_Object != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_String != null ? title_String.hashCode() : 0);\n    _result = 31 * _result + (title_Object != null ? title_Object.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropSingleSupportedAttributeModelViewModel_{\" +\n        \"title_String=\" + title_String +\n        \", title_Object=\" + title_Object +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropSingleSupportedAttributeModelViewModel_ from(ModelProperties properties) {\n    GroupPropSingleSupportedAttributeModelViewModel_ model = new GroupPropSingleSupportedAttributeModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ListSubtypeModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\nimport androidx.annotation.Nullable;\nimport java.util.ArrayList;\n\n@ModelView(defaultLayout = 1)\npublic class ListSubtypeModelView extends FrameLayout {\n\n  public ListSubtypeModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setStringArrayList(ArrayList<String> value) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ListSubtypeModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.ArrayList;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ListSubtypeModelViewModel_ extends EpoxyModel<ListSubtypeModelView> implements GeneratedModel<ListSubtypeModelView>, ListSubtypeModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private ArrayList<String> stringArrayList_ArrayList;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringArrayList\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ListSubtypeModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ListSubtypeModelView object) {\n    super.bind(object);\n    object.setStringArrayList(stringArrayList_ArrayList);\n  }\n\n  @Override\n  public void bind(final ListSubtypeModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ListSubtypeModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    ListSubtypeModelViewModel_ that = (ListSubtypeModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((stringArrayList_ArrayList != null ? !stringArrayList_ArrayList.equals(that.stringArrayList_ArrayList) : that.stringArrayList_ArrayList != null)) {\n      object.setStringArrayList(stringArrayList_ArrayList);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ListSubtypeModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ListSubtypeModelViewModel_ onBind(\n      OnModelBoundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ListSubtypeModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ListSubtypeModelViewModel_ onUnbind(\n      OnModelUnboundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ListSubtypeModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ListSubtypeModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ListSubtypeModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ListSubtypeModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see ListSubtypeModelView#setStringArrayList(ArrayList<String>)\n   */\n  public ListSubtypeModelViewModel_ stringArrayList(@NonNull ArrayList<String> stringArrayList) {\n    if (stringArrayList == null) {\n      throw new IllegalArgumentException(\"stringArrayList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.stringArrayList_ArrayList = stringArrayList;\n    return this;\n  }\n\n  @NonNull\n  public ArrayList<String> stringArrayList() {\n    return stringArrayList_ArrayList;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.stringArrayList_ArrayList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ListSubtypeModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ListSubtypeModelViewModel_ that = (ListSubtypeModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringArrayList_ArrayList != null ? !stringArrayList_ArrayList.equals(that.stringArrayList_ArrayList) : that.stringArrayList_ArrayList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringArrayList_ArrayList != null ? stringArrayList_ArrayList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ListSubtypeModelViewModel_{\" +\n        \"stringArrayList_ArrayList=\" + stringArrayList_ArrayList +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ModelFactoryBaseModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\n@ModelView(defaultLayout = 1)\npublic class ModelFactoryBaseModelView extends FrameLayout {\n\n  public ModelFactoryBaseModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ModelFactoryBaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelFactoryBaseModelViewModel_ extends EpoxyModel<ModelFactoryBaseModelView> implements GeneratedModel<ModelFactoryBaseModelView>, ModelFactoryBaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String title_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelFactoryBaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelFactoryBaseModelView object) {\n    super.bind(object);\n    object.setTitle(title_String);\n  }\n\n  @Override\n  public void bind(final ModelFactoryBaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelFactoryBaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    ModelFactoryBaseModelViewModel_ that = (ModelFactoryBaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      object.setTitle(title_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelFactoryBaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBaseModelViewModel_ onBind(\n      OnModelBoundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelFactoryBaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final ModelFactoryBaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelFactoryBaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see ModelFactoryBaseModelView#setTitle(String)\n   */\n  public ModelFactoryBaseModelViewModel_ title(@NonNull String title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_String = title;\n    return this;\n  }\n\n  @NonNull\n  public String title() {\n    return title_String;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelFactoryBaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelFactoryBaseModelViewModel_ that = (ModelFactoryBaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_String != null ? title_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelFactoryBaseModelViewModel_{\" +\n        \"title_String=\" + title_String +\n        \"}\" + super.toString();\n  }\n\n  public static ModelFactoryBaseModelViewModel_ from(ModelProperties properties) {\n    ModelFactoryBaseModelViewModel_ model = new ModelFactoryBaseModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ModelFactoryBasicModelWithAttribute.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelFactoryBasicModelWithAttribute extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ModelFactoryBasicModelWithAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelFactoryBasicModelWithAttribute_ extends ModelFactoryBasicModelWithAttribute implements GeneratedModel<Object>, ModelFactoryBasicModelWithAttributeBuilder {\n  private OnModelBoundListener<ModelFactoryBasicModelWithAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelFactoryBasicModelWithAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelFactoryBasicModelWithAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelFactoryBasicModelWithAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelFactoryBasicModelWithAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBasicModelWithAttribute_ onBind(\n      OnModelBoundListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBasicModelWithAttribute_ onUnbind(\n      OnModelUnboundListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBasicModelWithAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBasicModelWithAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelFactoryBasicModelWithAttribute_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelFactoryBasicModelWithAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelFactoryBasicModelWithAttribute_ that = (ModelFactoryBasicModelWithAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelFactoryBasicModelWithAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n\n  public static ModelFactoryBasicModelWithAttribute_ from(ModelProperties properties) {\n    ModelFactoryBasicModelWithAttribute_ model = new ModelFactoryBasicModelWithAttribute_();\n    model.id(properties.getId());\n    if (properties.has(\"value\")) {\n      model.value(properties.getInt(\"value\"));\n    }\n    return model;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/StyleableModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\nimport com.airbnb.paris.annotations.Styleable;\n\n@Styleable\n@ModelView\npublic class StyleableModelView extends FrameLayout {\n\n  public StyleableModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/StyleableModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.AsyncTask;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport com.airbnb.paris.StyleApplierUtils;\nimport com.airbnb.paris.styles.Style;\nimport com.airbnb.viewmodeladapter.R;\nimport java.lang.AssertionError;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Runnable;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.lang.ref.WeakReference;\nimport java.util.BitSet;\nimport java.util.Objects;\n\n/**\n * Generated file. Do not modify! */\npublic class StyleableModelViewModel_ extends EpoxyModel<StyleableModelView> implements GeneratedModel<StyleableModelView>, StyleableModelViewModelBuilder {\n  private static final Style DEFAULT_PARIS_STYLE = new StyleableModelViewStyleApplier.StyleBuilder().addDefault().build();\n\n  private static WeakReference<Style> parisStyleReference_default;\n\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<StyleableModelViewModel_, StyleableModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<StyleableModelViewModel_, StyleableModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<StyleableModelViewModel_, StyleableModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<StyleableModelViewModel_, StyleableModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0 */\n  @NonNull\n  private String title_String;\n\n  /**\n   * Bitset index: 1 */\n  private Style style = DEFAULT_PARIS_STYLE;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public StyleableModelView buildView(ViewGroup parent) {\n    StyleableModelView v = new StyleableModelView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final StyleableModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {\n        public void run() {\n          try {\n            StyleApplierUtils.Companion.assertSameAttributes(new StyleableModelViewStyleApplier(object), style, DEFAULT_PARIS_STYLE);\n          }\n          catch(AssertionError e) {\n            throw new IllegalStateException(\"StyleableModelViewModel_ model at position \" + position + \" has an invalid style:\\n\\n\" + e.getMessage());\n          }\n        }\n      } );\n    }\n  }\n\n  @Override\n  public void bind(final StyleableModelView object) {\n\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      StyleableModelViewStyleApplier styleApplier = new StyleableModelViewStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n    object.setTitle(title_String);\n  }\n\n  @Override\n  public void bind(final StyleableModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof StyleableModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    StyleableModelViewModel_ that = (StyleableModelViewModel_) previousModel;\n\n    if (!Objects.equals(style, that.style)) {\n      StyleableModelViewStyleApplier styleApplier = new StyleableModelViewStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      object.setTitle(title_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final StyleableModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public StyleableModelViewModel_ onBind(\n      OnModelBoundListener<StyleableModelViewModel_, StyleableModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(StyleableModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public StyleableModelViewModel_ onUnbind(\n      OnModelUnboundListener<StyleableModelViewModel_, StyleableModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final StyleableModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public StyleableModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<StyleableModelViewModel_, StyleableModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final StyleableModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public StyleableModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<StyleableModelViewModel_, StyleableModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public StyleableModelViewModel_ style(Style style) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.style = style;\n    return this;\n  }\n\n  public StyleableModelViewModel_ styleBuilder(\n      StyleBuilderCallback<StyleableModelViewStyleApplier.StyleBuilder> builderCallback) {\n    StyleableModelViewStyleApplier.StyleBuilder builder = new StyleableModelViewStyleApplier.StyleBuilder();\n    builderCallback.buildStyle(builder.addDefault());\n    return style(builder.build());\n  }\n\n  /**\n   *  Empty style  */\n  public StyleableModelViewModel_ withDefaultStyle() {\n    Style style = parisStyleReference_default != null ? parisStyleReference_default.get() : null;\n    if (style == null) {\n      style =  new StyleableModelViewStyleApplier.StyleBuilder().addDefault().build();\n      parisStyleReference_default = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see StyleableModelView#setTitle(String)\n   */\n  public StyleableModelViewModel_ title(@NonNull String title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_String = title;\n    return this;\n  }\n\n  @NonNull\n  public String title() {\n    return title_String;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(@Nullable Number... arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(@Nullable CharSequence arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(@Nullable CharSequence arg0, @Nullable CharSequence... arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ id(@Nullable CharSequence arg0, long arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ layout(@LayoutRes int arg0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public StyleableModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback arg0) {\n    super.spanSizeOverride(arg0);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public StyleableModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public StyleableModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_String = null;\n    this.style = DEFAULT_PARIS_STYLE;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof StyleableModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    StyleableModelViewModel_ that = (StyleableModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      return false;\n    }\n    if ((style != null ? !style.equals(that.style) : that.style != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int result = super.hashCode();\n    result = 31 * result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    result = 31 * result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    result = 31 * result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    result = 31 * result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    result = 31 * result + (title_String != null ? title_String.hashCode() : 0);\n    result = 31 * result + (style != null ? style.hashCode() : 0);\n    return result;\n  }\n\n  @Override\n  public String toString() {\n    return \"StyleableModelViewModel_{\" +\n        \"title_String=\" + title_String +\n        \", style=\" + style +\n        \"}\" + super.toString();\n  }\n\n  public static StyleableModelViewModel_ from(ModelProperties properties) {\n    StyleableModelViewModel_ model = new StyleableModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    Style style = properties.getStyle();\n    if (style != null) {\n      model.style(style);\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/TextPropModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\n@ModelView(defaultLayout = 1)\npublic class TextPropModelView extends FrameLayout {\n\n  public TextPropModelView(Context context) {\n    super(context);\n  }\n\n  @TextProp\n  public void setTitle(CharSequence title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/TextPropModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TextPropModelViewModel_ extends EpoxyModel<TextPropModelView> implements GeneratedModel<TextPropModelView>, TextPropModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TextPropModelViewModel_, TextPropModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TextPropModelViewModel_, TextPropModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TextPropModelViewModel_, TextPropModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TextPropModelViewModel_, TextPropModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TextPropModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TextPropModelView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TextPropModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TextPropModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    TextPropModelViewModel_ that = (TextPropModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TextPropModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropModelViewModel_ onBind(\n      OnModelBoundListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TextPropModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropModelViewModel_ onUnbind(\n      OnModelUnboundListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TextPropModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TextPropModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TextPropModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TextPropModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TextPropModelViewModel_ that = (TextPropModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TextPropModelViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  public static TextPropModelViewModel_ from(ModelProperties properties) {\n    TextPropModelViewModel_ model = new TextPropModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/AllTypesModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.RawRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Double;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> implements GeneratedModel<AllTypesModelView>, AllTypesModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(15);\n\n  private OnModelBoundListener<AllTypesModelViewModel_, AllTypesModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AllTypesModelViewModel_, AllTypesModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AllTypesModelViewModel_, AllTypesModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AllTypesModelViewModel_, AllTypesModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private boolean booleanValue_Boolean = false;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private Boolean boxedBooleanValue_Boolean;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence charSequenceValue_CharSequence;\n\n  /**\n   * Bitset index: 3\n   */\n  @NonNull\n  private Double boxedDoubleValue_Double;\n\n  private double doubleValue_Double = 0.0d;\n\n  @DrawableRes\n  private int drawableRes_Int = 0;\n\n  /**\n   * Bitset index: 6\n   */\n  @NonNull\n  private List<? extends EpoxyModel<?>> epoxyModelList_List;\n\n  private int intValue_Int = 0;\n\n  /**\n   * Bitset index: 8\n   */\n  @NonNull\n  private Integer boxedIntValue_Integer;\n\n  private long longValue_Long = 0L;\n\n  /**\n   * Bitset index: 10\n   */\n  @NonNull\n  private Long boxedLongValue_Long;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private View.OnClickListener onClickListener_OnClickListener;\n\n  @RawRes\n  private int rawRes_Int = 0;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private String stringValue_String;\n\n  /**\n   * Bitset index: 14\n   */\n  @NonNull\n  private List<String> stringList_List;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(8)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedIntValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedBooleanValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(3)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedDoubleValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(6)) {\n    \tthrow new IllegalStateException(\"A value is required for setEpoxyModelList\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(10)) {\n    \tthrow new IllegalStateException(\"A value is required for setBoxedLongValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(14)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringList\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(11)) {\n    \tthrow new IllegalStateException(\"A value is required for setOnClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setCharSequenceValue\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final AllTypesModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AllTypesModelView object) {\n    super.bind(object);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setBoxedIntValue(boxedIntValue_Integer);\n    object.setBoxedBooleanValue(boxedBooleanValue_Boolean);\n    object.setBoxedDoubleValue(boxedDoubleValue_Double);\n    object.setEpoxyModelList(epoxyModelList_List);\n    object.setBoxedLongValue(boxedLongValue_Long);\n    object.setLongValue(longValue_Long);\n    object.setStringList(stringList_List);\n    object.setStringValue(stringValue_String);\n    object.setOnClickListener(onClickListener_OnClickListener);\n    object.setIntValue(intValue_Int);\n    object.setDrawableRes(drawableRes_Int);\n    object.setDoubleValue(doubleValue_Double);\n    object.setRawRes(rawRes_Int);\n    object.setCharSequenceValue(charSequenceValue_CharSequence);\n  }\n\n  @Override\n  public void bind(final AllTypesModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AllTypesModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    AllTypesModelViewModel_ that = (AllTypesModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((booleanValue_Boolean != that.booleanValue_Boolean)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((boxedIntValue_Integer != null ? !boxedIntValue_Integer.equals(that.boxedIntValue_Integer) : that.boxedIntValue_Integer != null)) {\n      object.setBoxedIntValue(boxedIntValue_Integer);\n    }\n\n    if ((boxedBooleanValue_Boolean != null ? !boxedBooleanValue_Boolean.equals(that.boxedBooleanValue_Boolean) : that.boxedBooleanValue_Boolean != null)) {\n      object.setBoxedBooleanValue(boxedBooleanValue_Boolean);\n    }\n\n    if ((boxedDoubleValue_Double != null ? !boxedDoubleValue_Double.equals(that.boxedDoubleValue_Double) : that.boxedDoubleValue_Double != null)) {\n      object.setBoxedDoubleValue(boxedDoubleValue_Double);\n    }\n\n    if ((epoxyModelList_List != null ? !epoxyModelList_List.equals(that.epoxyModelList_List) : that.epoxyModelList_List != null)) {\n      object.setEpoxyModelList(epoxyModelList_List);\n    }\n\n    if ((boxedLongValue_Long != null ? !boxedLongValue_Long.equals(that.boxedLongValue_Long) : that.boxedLongValue_Long != null)) {\n      object.setBoxedLongValue(boxedLongValue_Long);\n    }\n\n    if ((longValue_Long != that.longValue_Long)) {\n      object.setLongValue(longValue_Long);\n    }\n\n    if ((stringList_List != null ? !stringList_List.equals(that.stringList_List) : that.stringList_List != null)) {\n      object.setStringList(stringList_List);\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      object.setOnClickListener(onClickListener_OnClickListener);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if ((drawableRes_Int != that.drawableRes_Int)) {\n      object.setDrawableRes(drawableRes_Int);\n    }\n\n    if ((Double.compare(that.doubleValue_Double, doubleValue_Double) != 0)) {\n      object.setDoubleValue(doubleValue_Double);\n    }\n\n    if ((rawRes_Int != that.rawRes_Int)) {\n      object.setRawRes(rawRes_Int);\n    }\n\n    if ((charSequenceValue_CharSequence != null ? !charSequenceValue_CharSequence.equals(that.charSequenceValue_CharSequence) : that.charSequenceValue_CharSequence != null)) {\n      object.setCharSequenceValue(charSequenceValue_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AllTypesModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AllTypesModelViewModel_ onBind(\n      OnModelBoundListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AllTypesModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AllTypesModelViewModel_ onUnbind(\n      OnModelUnboundListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final AllTypesModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AllTypesModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AllTypesModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AllTypesModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AllTypesModelViewModel_, AllTypesModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see AllTypesModelView#setBooleanValue(boolean)\n   */\n  public AllTypesModelViewModel_ booleanValue(boolean booleanValue) {\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  public boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedBooleanValue(Boolean)\n   */\n  public AllTypesModelViewModel_ boxedBooleanValue(@NonNull Boolean boxedBooleanValue) {\n    if (boxedBooleanValue == null) {\n      throw new IllegalArgumentException(\"boxedBooleanValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.boxedBooleanValue_Boolean = boxedBooleanValue;\n    return this;\n  }\n\n  @NonNull\n  public Boolean boxedBooleanValue() {\n    return boxedBooleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setCharSequenceValue(CharSequence)\n   */\n  public AllTypesModelViewModel_ charSequenceValue(@NonNull CharSequence charSequenceValue) {\n    if (charSequenceValue == null) {\n      throw new IllegalArgumentException(\"charSequenceValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.charSequenceValue_CharSequence = charSequenceValue;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence charSequenceValue() {\n    return charSequenceValue_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedDoubleValue(Double)\n   */\n  public AllTypesModelViewModel_ boxedDoubleValue(@NonNull Double boxedDoubleValue) {\n    if (boxedDoubleValue == null) {\n      throw new IllegalArgumentException(\"boxedDoubleValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(3);\n    onMutation();\n    this.boxedDoubleValue_Double = boxedDoubleValue;\n    return this;\n  }\n\n  @NonNull\n  public Double boxedDoubleValue() {\n    return boxedDoubleValue_Double;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0.0d\n   *\n   * @see AllTypesModelView#setDoubleValue(double)\n   */\n  public AllTypesModelViewModel_ doubleValue(double doubleValue) {\n    onMutation();\n    this.doubleValue_Double = doubleValue;\n    return this;\n  }\n\n  public double doubleValue() {\n    return doubleValue_Double;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setDrawableRes(int)\n   */\n  public AllTypesModelViewModel_ drawableRes(@DrawableRes int drawableRes) {\n    onMutation();\n    this.drawableRes_Int = drawableRes;\n    return this;\n  }\n\n  @DrawableRes\n  public int drawableRes() {\n    return drawableRes_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setEpoxyModelList(List<? extends EpoxyModel<?>>)\n   */\n  public AllTypesModelViewModel_ epoxyModelList(\n      @NonNull List<? extends EpoxyModel<?>> epoxyModelList) {\n    if (epoxyModelList == null) {\n      throw new IllegalArgumentException(\"epoxyModelList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    onMutation();\n    this.epoxyModelList_List = epoxyModelList;\n    return this;\n  }\n\n  @NonNull\n  public List<? extends EpoxyModel<?>> epoxyModelList() {\n    return epoxyModelList_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setIntValue(int)\n   */\n  public AllTypesModelViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedIntValue(Integer)\n   */\n  public AllTypesModelViewModel_ boxedIntValue(@NonNull Integer boxedIntValue) {\n    if (boxedIntValue == null) {\n      throw new IllegalArgumentException(\"boxedIntValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    onMutation();\n    this.boxedIntValue_Integer = boxedIntValue;\n    return this;\n  }\n\n  @NonNull\n  public Integer boxedIntValue() {\n    return boxedIntValue_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see AllTypesModelView#setLongValue(long)\n   */\n  public AllTypesModelViewModel_ longValue(long longValue) {\n    onMutation();\n    this.longValue_Long = longValue;\n    return this;\n  }\n\n  public long longValue() {\n    return longValue_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setBoxedLongValue(Long)\n   */\n  public AllTypesModelViewModel_ boxedLongValue(@NonNull Long boxedLongValue) {\n    if (boxedLongValue == null) {\n      throw new IllegalArgumentException(\"boxedLongValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.boxedLongValue_Long = boxedLongValue;\n    return this;\n  }\n\n  @NonNull\n  public Long boxedLongValue() {\n    return boxedLongValue_Long;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public AllTypesModelViewModel_ onClickListener(\n      @NonNull final OnModelClickListener<AllTypesModelViewModel_, AllTypesModelView> onClickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    if (onClickListener == null) {\n      this.onClickListener_OnClickListener = null;\n    }\n    else {\n      this.onClickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(onClickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setOnClickListener(View.OnClickListener)\n   */\n  public AllTypesModelViewModel_ onClickListener(@NonNull View.OnClickListener onClickListener) {\n    if (onClickListener == null) {\n      throw new IllegalArgumentException(\"onClickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    this.onClickListener_OnClickListener = onClickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener onClickListener() {\n    return onClickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AllTypesModelView#setRawRes(int)\n   */\n  public AllTypesModelViewModel_ rawRes(@RawRes int rawRes) {\n    onMutation();\n    this.rawRes_Int = rawRes;\n    return this;\n  }\n\n  @RawRes\n  public int rawRes() {\n    return rawRes_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setStringValue(String)\n   */\n  public AllTypesModelViewModel_ stringValue(@NonNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NonNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see AllTypesModelView#setStringList(List<String>)\n   */\n  public AllTypesModelViewModel_ stringList(@NonNull List<String> stringList) {\n    if (stringList == null) {\n      throw new IllegalArgumentException(\"stringList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(14);\n    onMutation();\n    this.stringList_List = stringList;\n    return this;\n  }\n\n  @NonNull\n  public List<String> stringList() {\n    return stringList_List;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public AllTypesModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.booleanValue_Boolean = false;\n    this.boxedBooleanValue_Boolean = null;\n    this.charSequenceValue_CharSequence = null;\n    this.boxedDoubleValue_Double = null;\n    this.doubleValue_Double = 0.0d;\n    this.drawableRes_Int = 0;\n    this.epoxyModelList_List = null;\n    this.intValue_Int = 0;\n    this.boxedIntValue_Integer = null;\n    this.longValue_Long = 0L;\n    this.boxedLongValue_Long = null;\n    this.onClickListener_OnClickListener = null;\n    this.rawRes_Int = 0;\n    this.stringValue_String = null;\n    this.stringList_List = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AllTypesModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AllTypesModelViewModel_ that = (AllTypesModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((booleanValue_Boolean != that.booleanValue_Boolean)) {\n      return false;\n    }\n    if ((boxedBooleanValue_Boolean != null ? !boxedBooleanValue_Boolean.equals(that.boxedBooleanValue_Boolean) : that.boxedBooleanValue_Boolean != null)) {\n      return false;\n    }\n    if ((charSequenceValue_CharSequence != null ? !charSequenceValue_CharSequence.equals(that.charSequenceValue_CharSequence) : that.charSequenceValue_CharSequence != null)) {\n      return false;\n    }\n    if ((boxedDoubleValue_Double != null ? !boxedDoubleValue_Double.equals(that.boxedDoubleValue_Double) : that.boxedDoubleValue_Double != null)) {\n      return false;\n    }\n    if ((Double.compare(that.doubleValue_Double, doubleValue_Double) != 0)) {\n      return false;\n    }\n    if ((drawableRes_Int != that.drawableRes_Int)) {\n      return false;\n    }\n    if ((epoxyModelList_List != null ? !epoxyModelList_List.equals(that.epoxyModelList_List) : that.epoxyModelList_List != null)) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((boxedIntValue_Integer != null ? !boxedIntValue_Integer.equals(that.boxedIntValue_Integer) : that.boxedIntValue_Integer != null)) {\n      return false;\n    }\n    if ((longValue_Long != that.longValue_Long)) {\n      return false;\n    }\n    if ((boxedLongValue_Long != null ? !boxedLongValue_Long.equals(that.boxedLongValue_Long) : that.boxedLongValue_Long != null)) {\n      return false;\n    }\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((rawRes_Int != that.rawRes_Int)) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if ((stringList_List != null ? !stringList_List.equals(that.stringList_List) : that.stringList_List != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + (booleanValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (boxedBooleanValue_Boolean != null ? boxedBooleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + (charSequenceValue_CharSequence != null ? charSequenceValue_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (boxedDoubleValue_Double != null ? boxedDoubleValue_Double.hashCode() : 0);\n    temp = Double.doubleToLongBits(doubleValue_Double);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + drawableRes_Int;\n    _result = 31 * _result + (epoxyModelList_List != null ? epoxyModelList_List.hashCode() : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + (boxedIntValue_Integer != null ? boxedIntValue_Integer.hashCode() : 0);\n    _result = 31 * _result + (int) (longValue_Long ^ (longValue_Long >>> 32));\n    _result = 31 * _result + (boxedLongValue_Long != null ? boxedLongValue_Long.hashCode() : 0);\n    _result = 31 * _result + (onClickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + rawRes_Int;\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (stringList_List != null ? stringList_List.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AllTypesModelViewModel_{\" +\n        \"booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", boxedBooleanValue_Boolean=\" + boxedBooleanValue_Boolean +\n        \", charSequenceValue_CharSequence=\" + charSequenceValue_CharSequence +\n        \", boxedDoubleValue_Double=\" + boxedDoubleValue_Double +\n        \", doubleValue_Double=\" + doubleValue_Double +\n        \", drawableRes_Int=\" + drawableRes_Int +\n        \", epoxyModelList_List=\" + epoxyModelList_List +\n        \", intValue_Int=\" + intValue_Int +\n        \", boxedIntValue_Integer=\" + boxedIntValue_Integer +\n        \", longValue_Long=\" + longValue_Long +\n        \", boxedLongValue_Long=\" + boxedLongValue_Long +\n        \", onClickListener_OnClickListener=\" + onClickListener_OnClickListener +\n        \", rawRes_Int=\" + rawRes_Int +\n        \", stringValue_String=\" + stringValue_String +\n        \", stringList_List=\" + stringList_List +\n        \"}\" + super.toString();\n  }\n\n  public static AllTypesModelViewModel_ from(ModelProperties properties) {\n    AllTypesModelViewModel_ model = new AllTypesModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"booleanValue\")) {\n      model.booleanValue(properties.getBoolean(\"booleanValue\"));\n    }\n    if (properties.has(\"boxedBooleanValue\")) {\n      model.boxedBooleanValue(properties.getBoolean(\"boxedBooleanValue\"));\n    }\n    if (properties.has(\"charSequenceValue\")) {\n      model.charSequenceValue(properties.getString(\"charSequenceValue\"));\n    }\n    if (properties.has(\"boxedDoubleValue\")) {\n      model.boxedDoubleValue(properties.getDouble(\"boxedDoubleValue\"));\n    }\n    if (properties.has(\"doubleValue\")) {\n      model.doubleValue(properties.getDouble(\"doubleValue\"));\n    }\n    if (properties.has(\"drawableRes\")) {\n      model.drawableRes(properties.getDrawableRes(\"drawableRes\"));\n    }\n    if (properties.has(\"epoxyModelList\")) {\n      model.epoxyModelList(properties.getEpoxyModelList(\"epoxyModelList\"));\n    }\n    if (properties.has(\"intValue\")) {\n      model.intValue(properties.getInt(\"intValue\"));\n    }\n    if (properties.has(\"boxedIntValue\")) {\n      model.boxedIntValue(properties.getInt(\"boxedIntValue\"));\n    }\n    if (properties.has(\"longValue\")) {\n      model.longValue(properties.getLong(\"longValue\"));\n    }\n    if (properties.has(\"boxedLongValue\")) {\n      model.boxedLongValue(properties.getLong(\"boxedLongValue\"));\n    }\n    if (properties.has(\"onClickListener\")) {\n      model.onClickListener(properties.getOnClickListener(\"onClickListener\"));\n    }\n    if (properties.has(\"rawRes\")) {\n      model.rawRes(properties.getRawRes(\"rawRes\"));\n    }\n    if (properties.has(\"stringValue\")) {\n      model.stringValue(properties.getString(\"stringValue\"));\n    }\n    if (properties.has(\"stringList\")) {\n      model.stringList(properties.getStringList(\"stringList\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/BasicModelWithFinalAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BasicModelWithFinalAttribute_ extends BasicModelWithFinalAttribute implements GeneratedModel<Object>, BasicModelWithFinalAttributeBuilder {\n  private OnModelBoundListener<BasicModelWithFinalAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BasicModelWithFinalAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BasicModelWithFinalAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BasicModelWithFinalAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public BasicModelWithFinalAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithFinalAttribute_ onBind(\n      OnModelBoundListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithFinalAttribute_ onUnbind(\n      OnModelUnboundListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithFinalAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithFinalAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BasicModelWithFinalAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithFinalAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BasicModelWithFinalAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BasicModelWithFinalAttribute_ that = (BasicModelWithFinalAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BasicModelWithFinalAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/CallbackPropModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class CallbackPropModelViewModel_ extends EpoxyModel<CallbackPropModelView> implements GeneratedModel<CallbackPropModelView>, CallbackPropModelViewModelBuilder {\n  private OnModelBoundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener onClickListener_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final CallbackPropModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final CallbackPropModelView object) {\n    super.bind(object);\n    object.setOnClickListener(onClickListener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final CallbackPropModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof CallbackPropModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    CallbackPropModelViewModel_ that = (CallbackPropModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      object.setOnClickListener(onClickListener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final CallbackPropModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CallbackPropModelViewModel_ onBind(\n      OnModelBoundListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(CallbackPropModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setOnClickListener((View.OnClickListener) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CallbackPropModelViewModel_ onUnbind(\n      OnModelUnboundListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final CallbackPropModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CallbackPropModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final CallbackPropModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CallbackPropModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public CallbackPropModelViewModel_ onClickListener(\n      @Nullable final OnModelClickListener<CallbackPropModelViewModel_, CallbackPropModelView> onClickListener) {\n    onMutation();\n    if (onClickListener == null) {\n      this.onClickListener_OnClickListener = null;\n    }\n    else {\n      this.onClickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(onClickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see CallbackPropModelView#setOnClickListener(View.OnClickListener)\n   */\n  public CallbackPropModelViewModel_ onClickListener(\n      @Nullable View.OnClickListener onClickListener) {\n    onMutation();\n    this.onClickListener_OnClickListener = onClickListener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener onClickListener() {\n    return onClickListener_OnClickListener;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public CallbackPropModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.onClickListener_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof CallbackPropModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    CallbackPropModelViewModel_ that = (CallbackPropModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onClickListener_OnClickListener == null) != (that.onClickListener_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onClickListener_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"CallbackPropModelViewModel_{\" +\n        \"onClickListener_OnClickListener=\" + onClickListener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  public static CallbackPropModelViewModel_ from(ModelProperties properties) {\n    CallbackPropModelViewModel_ model = new CallbackPropModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"onClickListener\")) {\n      model.onClickListener(properties.getOnClickListener(\"onClickListener\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ extends EpoxyModel<GroupPropMultipleSupportedAttributeDifferentNameModelView> implements GeneratedModel<GroupPropMultipleSupportedAttributeDifferentNameModelView>, GroupPropMultipleSupportedAttributeDifferentNameModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String titleString_String;\n\n  /**\n   * Bitset index: 1\n   */\n  private int titleInt_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitleString(titleString_String);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n    else {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n        object.setTitleString(titleString_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((titleInt_Int != that.titleInt_Int)) {\n        object.setTitleInt(titleInt_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropMultipleSupportedAttributeDifferentNameModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropMultipleSupportedAttributeDifferentNameModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_, GroupPropMultipleSupportedAttributeDifferentNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropMultipleSupportedAttributeDifferentNameModelView#setTitleString(String)\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ titleString(\n      @NonNull String titleString) {\n    if (titleString == null) {\n      throw new IllegalArgumentException(\"titleString cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.titleInt_Int = 0;\n    onMutation();\n    this.titleString_String = titleString;\n    return this;\n  }\n\n  @NonNull\n  public String titleStringString() {\n    return titleString_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see GroupPropMultipleSupportedAttributeDifferentNameModelView#setTitleInt(int)\n   */\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ titleInt(int titleInt) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.titleString_String = null;\n    onMutation();\n    this.titleInt_Int = titleInt;\n    return this;\n  }\n\n  public int titleIntInt() {\n    return titleInt_Int;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ id(\n      @Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.titleString_String = null;\n    this.titleInt_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n      return false;\n    }\n    if ((titleInt_Int != that.titleInt_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (titleString_String != null ? titleString_String.hashCode() : 0);\n    _result = 31 * _result + titleInt_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_{\" +\n        \"titleString_String=\" + titleString_String +\n        \", titleInt_Int=\" + titleInt_Int +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ from(\n      ModelProperties properties) {\n    GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_ model = new GroupPropMultipleSupportedAttributeDifferentNameModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"titleString\")) {\n      model.titleString(properties.getString(\"titleString\"));\n    } else if (properties.has(\"titleInt\")) {\n      model.titleInt(properties.getInt(\"titleInt\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/GroupPropMultipleSupportedAttributeSameNameModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropMultipleSupportedAttributeSameNameModelViewModel_ extends EpoxyModel<GroupPropMultipleSupportedAttributeSameNameModelView> implements GeneratedModel<GroupPropMultipleSupportedAttributeSameNameModelView>, GroupPropMultipleSupportedAttributeSameNameModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String titleString_String;\n\n  /**\n   * Bitset index: 1\n   */\n  private int titleInt_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitleString(titleString_String);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n    else {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropMultipleSupportedAttributeSameNameModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropMultipleSupportedAttributeSameNameModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeSameNameModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n        object.setTitleString(titleString_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((titleInt_Int != that.titleInt_Int)) {\n        object.setTitleInt(titleInt_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitleInt(titleInt_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropMultipleSupportedAttributeSameNameModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropMultipleSupportedAttributeSameNameModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropMultipleSupportedAttributeSameNameModelViewModel_, GroupPropMultipleSupportedAttributeSameNameModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropMultipleSupportedAttributeSameNameModelView#setTitleString(String)\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ titleString(\n      @NonNull String titleString) {\n    if (titleString == null) {\n      throw new IllegalArgumentException(\"titleString cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.titleInt_Int = 0;\n    onMutation();\n    this.titleString_String = titleString;\n    return this;\n  }\n\n  @NonNull\n  public String titleStringString() {\n    return titleString_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see GroupPropMultipleSupportedAttributeSameNameModelView#setTitleInt(int)\n   */\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ titleInt(int titleInt) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.titleString_String = null;\n    onMutation();\n    this.titleInt_Int = titleInt;\n    return this;\n  }\n\n  public int titleIntInt() {\n    return titleInt_Int;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropMultipleSupportedAttributeSameNameModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.titleString_String = null;\n    this.titleInt_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropMultipleSupportedAttributeSameNameModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ that = (GroupPropMultipleSupportedAttributeSameNameModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((titleString_String != null ? !titleString_String.equals(that.titleString_String) : that.titleString_String != null)) {\n      return false;\n    }\n    if ((titleInt_Int != that.titleInt_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (titleString_String != null ? titleString_String.hashCode() : 0);\n    _result = 31 * _result + titleInt_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropMultipleSupportedAttributeSameNameModelViewModel_{\" +\n        \"titleString_String=\" + titleString_String +\n        \", titleInt_Int=\" + titleInt_Int +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropMultipleSupportedAttributeSameNameModelViewModel_ from(\n      ModelProperties properties) {\n    GroupPropMultipleSupportedAttributeSameNameModelViewModel_ model = new GroupPropMultipleSupportedAttributeSameNameModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"titleString\")) {\n      model.titleString(properties.getString(\"titleString\"));\n    } else if (properties.has(\"titleInt\")) {\n      model.titleInt(properties.getInt(\"titleInt\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/GroupPropSingleSupportedAttributeModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GroupPropSingleSupportedAttributeModelViewModel_ extends EpoxyModel<GroupPropSingleSupportedAttributeModelView> implements GeneratedModel<GroupPropSingleSupportedAttributeModelView>, GroupPropSingleSupportedAttributeModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String title_String;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private Object title_Object;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0) && !assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final GroupPropSingleSupportedAttributeModelView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GroupPropSingleSupportedAttributeModelView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitle(title_String);\n    }\n    else {\n      object.setTitle(title_Object);\n    }\n  }\n\n  @Override\n  public void bind(final GroupPropSingleSupportedAttributeModelView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof GroupPropSingleSupportedAttributeModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    GroupPropSingleSupportedAttributeModelViewModel_ that = (GroupPropSingleSupportedAttributeModelViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n        object.setTitle(title_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(1) || (title_Object != null ? !title_Object.equals(that.title_Object) : that.title_Object != null)) {\n        object.setTitle(title_Object);\n      }\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GroupPropSingleSupportedAttributeModelView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onBind(\n      OnModelBoundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GroupPropSingleSupportedAttributeModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onUnbind(\n      OnModelUnboundListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final GroupPropSingleSupportedAttributeModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final GroupPropSingleSupportedAttributeModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GroupPropSingleSupportedAttributeModelViewModel_, GroupPropSingleSupportedAttributeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropSingleSupportedAttributeModelView#setTitle(String)\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ title(@NonNull String title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.title_Object = null;\n    onMutation();\n    this.title_String = title;\n    return this;\n  }\n\n  @NonNull\n  public String titleString() {\n    return title_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GroupPropSingleSupportedAttributeModelView#setTitle(Object)\n   */\n  public GroupPropSingleSupportedAttributeModelViewModel_ title(@NonNull Object title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.title_String = null;\n    onMutation();\n    this.title_Object = title;\n    return this;\n  }\n\n  @NonNull\n  public Object titleObject() {\n    return title_Object;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GroupPropSingleSupportedAttributeModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_String = null;\n    this.title_Object = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GroupPropSingleSupportedAttributeModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GroupPropSingleSupportedAttributeModelViewModel_ that = (GroupPropSingleSupportedAttributeModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      return false;\n    }\n    if ((title_Object != null ? !title_Object.equals(that.title_Object) : that.title_Object != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_String != null ? title_String.hashCode() : 0);\n    _result = 31 * _result + (title_Object != null ? title_Object.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GroupPropSingleSupportedAttributeModelViewModel_{\" +\n        \"title_String=\" + title_String +\n        \", title_Object=\" + title_Object +\n        \"}\" + super.toString();\n  }\n\n  public static GroupPropSingleSupportedAttributeModelViewModel_ from(ModelProperties properties) {\n    GroupPropSingleSupportedAttributeModelViewModel_ model = new GroupPropSingleSupportedAttributeModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/ListSubtypeModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.ArrayList;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ListSubtypeModelViewModel_ extends EpoxyModel<ListSubtypeModelView> implements GeneratedModel<ListSubtypeModelView>, ListSubtypeModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private ArrayList<String> stringArrayList_ArrayList;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringArrayList\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ListSubtypeModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ListSubtypeModelView object) {\n    super.bind(object);\n    object.setStringArrayList(stringArrayList_ArrayList);\n  }\n\n  @Override\n  public void bind(final ListSubtypeModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ListSubtypeModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    ListSubtypeModelViewModel_ that = (ListSubtypeModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((stringArrayList_ArrayList != null ? !stringArrayList_ArrayList.equals(that.stringArrayList_ArrayList) : that.stringArrayList_ArrayList != null)) {\n      object.setStringArrayList(stringArrayList_ArrayList);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ListSubtypeModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ListSubtypeModelViewModel_ onBind(\n      OnModelBoundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ListSubtypeModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ListSubtypeModelViewModel_ onUnbind(\n      OnModelUnboundListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ListSubtypeModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ListSubtypeModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ListSubtypeModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ListSubtypeModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ListSubtypeModelViewModel_, ListSubtypeModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see ListSubtypeModelView#setStringArrayList(ArrayList<String>)\n   */\n  public ListSubtypeModelViewModel_ stringArrayList(@NonNull ArrayList<String> stringArrayList) {\n    if (stringArrayList == null) {\n      throw new IllegalArgumentException(\"stringArrayList cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.stringArrayList_ArrayList = stringArrayList;\n    return this;\n  }\n\n  @NonNull\n  public ArrayList<String> stringArrayList() {\n    return stringArrayList_ArrayList;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public ListSubtypeModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.stringArrayList_ArrayList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ListSubtypeModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ListSubtypeModelViewModel_ that = (ListSubtypeModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringArrayList_ArrayList != null ? !stringArrayList_ArrayList.equals(that.stringArrayList_ArrayList) : that.stringArrayList_ArrayList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringArrayList_ArrayList != null ? stringArrayList_ArrayList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ListSubtypeModelViewModel_{\" +\n        \"stringArrayList_ArrayList=\" + stringArrayList_ArrayList +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/ModelFactoryBaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelFactoryBaseModelViewModel_ extends EpoxyModel<ModelFactoryBaseModelView> implements GeneratedModel<ModelFactoryBaseModelView>, ModelFactoryBaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String title_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelFactoryBaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelFactoryBaseModelView object) {\n    super.bind(object);\n    object.setTitle(title_String);\n  }\n\n  @Override\n  public void bind(final ModelFactoryBaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelFactoryBaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    ModelFactoryBaseModelViewModel_ that = (ModelFactoryBaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      object.setTitle(title_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelFactoryBaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBaseModelViewModel_ onBind(\n      OnModelBoundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelFactoryBaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final ModelFactoryBaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelFactoryBaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelFactoryBaseModelViewModel_, ModelFactoryBaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see ModelFactoryBaseModelView#setTitle(String)\n   */\n  public ModelFactoryBaseModelViewModel_ title(@NonNull String title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_String = title;\n    return this;\n  }\n\n  @NonNull\n  public String title() {\n    return title_String;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public ModelFactoryBaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelFactoryBaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelFactoryBaseModelViewModel_ that = (ModelFactoryBaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_String != null ? !title_String.equals(that.title_String) : that.title_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_String != null ? title_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelFactoryBaseModelViewModel_{\" +\n        \"title_String=\" + title_String +\n        \"}\" + super.toString();\n  }\n\n  public static ModelFactoryBaseModelViewModel_ from(ModelProperties properties) {\n    ModelFactoryBaseModelViewModel_ model = new ModelFactoryBaseModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/ModelFactoryBasicModelWithAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelFactoryBasicModelWithAttribute_ extends ModelFactoryBasicModelWithAttribute implements GeneratedModel<Object>, ModelFactoryBasicModelWithAttributeBuilder {\n  private OnModelBoundListener<ModelFactoryBasicModelWithAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelFactoryBasicModelWithAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelFactoryBasicModelWithAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelFactoryBasicModelWithAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelFactoryBasicModelWithAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBasicModelWithAttribute_ onBind(\n      OnModelBoundListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelFactoryBasicModelWithAttribute_ onUnbind(\n      OnModelUnboundListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBasicModelWithAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelFactoryBasicModelWithAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelFactoryBasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelFactoryBasicModelWithAttribute_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelFactoryBasicModelWithAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelFactoryBasicModelWithAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelFactoryBasicModelWithAttribute_ that = (ModelFactoryBasicModelWithAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelFactoryBasicModelWithAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n\n  public static ModelFactoryBasicModelWithAttribute_ from(ModelProperties properties) {\n    ModelFactoryBasicModelWithAttribute_ model = new ModelFactoryBasicModelWithAttribute_();\n    model.id(properties.getId());\n    if (properties.has(\"value\")) {\n      model.value(properties.getInt(\"value\"));\n    }\n    return model;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/ksp/TextPropModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TextPropModelViewModel_ extends EpoxyModel<TextPropModelView> implements GeneratedModel<TextPropModelView>, TextPropModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TextPropModelViewModel_, TextPropModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TextPropModelViewModel_, TextPropModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TextPropModelViewModel_, TextPropModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TextPropModelViewModel_, TextPropModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TextPropModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TextPropModelView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TextPropModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TextPropModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    TextPropModelViewModel_ that = (TextPropModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TextPropModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropModelViewModel_ onBind(\n      OnModelBoundListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TextPropModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropModelViewModel_ onUnbind(\n      OnModelUnboundListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TextPropModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TextPropModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TextPropModelViewModel_, TextPropModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropModelView#setTitle(CharSequence)\n   */\n  public TextPropModelViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TextPropModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TextPropModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TextPropModelViewModel_ that = (TextPropModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TextPropModelViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  public static TextPropModelViewModel_ from(ModelProperties properties) {\n    TextPropModelViewModel_ model = new TextPropModelViewModel_();\n    model.id(properties.getId());\n    if (properties.has(\"title\")) {\n      model.title(properties.getString(\"title\"));\n    }\n    return model;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-modelfactorytest/src/test/resources/test.json",
    "content": "{}"
  },
  {
    "path": "epoxy-paging3/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-paging3/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxy.paging3'\n\n  defaultConfig {\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n  api rootProject.deps.androidPaging3Component\n  api project(':epoxy-annotations')\n  api project(':epoxy-adapter')\n\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.robolectric\n  testImplementation rootProject.deps.mockito\n  testImplementation rootProject.deps.kotlinCoroutinesTest\n  androidTestImplementation rootProject.deps.junit\n  androidTestImplementation rootProject.deps.androidArchCoreTesting\n  androidTestImplementation rootProject.deps.androidTestRunner\n\n  kaptAndroidTest project(\":epoxy-processor\")\n}\n"
  },
  {
    "path": "epoxy-paging3/gradle.properties",
    "content": "POM_NAME=Epoxy Paging3 Support\nPOM_ARTIFACT_ID=epoxy-paging3\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-paging3/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "epoxy-paging3/src/androidTest/java/com/airbnb/epoxy/paging3/Item.kt",
    "content": "/*\n * Copyright 2018 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.airbnb.epoxy.paging3\n\nimport androidx.recyclerview.widget.DiffUtil\n\n/**\n * Dummy item for testing.\n */\ndata class Item(val id: Int, val value: String) {\n    companion object {\n        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Item>() {\n            override fun areItemsTheSame(oldItem: Item, newItem: Item) = oldItem.id == newItem.id\n\n            override fun areContentsTheSame(oldItem: Item, newItem: Item) = oldItem == newItem\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/androidTest/java/com/airbnb/epoxy/paging3/ListDataSource.kt",
    "content": "/*\n * Copyright 2018 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.airbnb.epoxy.paging3\n\nimport androidx.paging.PositionalDataSource\n\n/**\n * Simple data source that works with a given list and its loading can be stopped / started.\n */\nclass ListDataSource<T : Any>(\n    private val data: List<T>\n) : PositionalDataSource<T>() {\n    private var pendingActions = arrayListOf<() -> Unit>()\n    private var running = true\n\n    private fun compute(f: () -> Unit) {\n        if (running) {\n            f()\n        } else {\n            pendingActions.add(f)\n        }\n    }\n\n    fun start() {\n        running = true\n        val pending = pendingActions\n        pendingActions = arrayListOf()\n        pending.forEach(this::compute)\n    }\n\n    fun stop() {\n        running = false\n    }\n\n    override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<T>) {\n        compute {\n            callback.onResult(\n                data.subList(\n                    params.startPosition,\n                    Math.min(data.size, params.startPosition + params.loadSize)\n                )\n            )\n        }\n    }\n\n    override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<T>) {\n        val start = computeInitialLoadPosition(params, data.size)\n        val itemCnt = computeInitialLoadSize(params, start, data.size)\n        callback.onResult(\n            data.subList(start, start + itemCnt),\n            start,\n            data.size\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/androidTest/java/com/airbnb/epoxy/paging3/PagedListModelCacheTest.kt",
    "content": "/*\n * Copyright 2018 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.airbnb.epoxy.paging3\n\nimport android.arch.core.executor.testing.CountingTaskExecutorRule\nimport android.support.test.InstrumentationRegistry\nimport android.support.test.runner.AndroidJUnit4\nimport android.view.View\nimport androidx.paging.PagedList\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport org.hamcrest.CoreMatchers\nimport org.hamcrest.CoreMatchers.`is`\nimport org.hamcrest.MatcherAssert.assertThat\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport java.util.concurrent.Executor\nimport java.util.concurrent.TimeUnit\n\n@RunWith(AndroidJUnit4::class)\nclass PagedListModelCacheTest {\n    @Rule\n    @JvmField\n    val archExecutor = CountingTaskExecutorRule()\n\n    /**\n     * Simple mode builder for [Item]\n     */\n    private var modelBuildCounter = 0\n    private val modelBuilder: (Int, Item?) -> EpoxyModel<*> = { pos, item ->\n        modelBuildCounter++\n        if (item == null) {\n            FakePlaceholderModel(\n                pos\n            )\n        } else {\n            FakeModel(item)\n        }\n    }\n\n    /**\n     * Number of times a rebuild is requested\n     */\n    private var rebuildCounter = 0\n    private val rebuildCallback: () -> Unit = {\n        rebuildCounter++\n    }\n\n    private val pagedListModelCache =\n        PagedListModelCache(\n            modelBuilder = modelBuilder,\n            rebuildCallback = rebuildCallback,\n            itemDiffCallback = Item.DIFF_CALLBACK,\n            diffExecutor = Executor {\n                it.run()\n            },\n            modelBuildingHandler = EpoxyController.defaultModelBuildingHandler\n        )\n\n    @Test\n    fun empty() {\n        assertThat(pagedListModelCache.getModels(), `is`(emptyList()))\n    }\n\n    @Test\n    fun simple() {\n        val items = createItems(PAGE_SIZE)\n        val (pagedList, _) = createPagedList(items)\n        pagedListModelCache.submitList(pagedList)\n        assertModelItems(items)\n        assertAndResetRebuildModels()\n    }\n\n    @Test\n    fun partialLoad() {\n        val items = createItems(INITIAL_LOAD_SIZE + 2)\n        val (pagedList, dataSource) = createPagedList(items)\n        dataSource.stop()\n        pagedListModelCache.submitList(pagedList)\n        assertModelItems(\n            items.subList(\n                0,\n                INITIAL_LOAD_SIZE\n            ) + listOf(20, 21)\n        )\n        assertAndResetRebuildModels()\n        pagedListModelCache.loadAround(INITIAL_LOAD_SIZE)\n        assertModelItems(\n            items.subList(\n                0,\n                INITIAL_LOAD_SIZE\n            ) + listOf(20, 21)\n        )\n        assertThat(rebuildCounter, `is`(0))\n        dataSource.start()\n        assertModelItems(items)\n        assertAndResetRebuildModels()\n    }\n\n    @Test\n    fun partialLoad_jumpToPosition() {\n        val items = createItems(PAGE_SIZE * 10)\n        val (pagedList, _) = createPagedList(items)\n        pagedListModelCache.submitList(pagedList)\n        drain()\n        assertAndResetRebuildModels()\n        pagedListModelCache.loadAround(PAGE_SIZE * 8)\n        drain()\n        val models = collectModelItems()\n        assertAndResetRebuildModels()\n        // We cannot be sure what will be loaded but we can be sure that\n        // a ) around PAGE_SIZE * 8 will be loaded\n        // b ) there will be null items in between\n        assertThat(models[PAGE_SIZE * 8], `is`(items[PAGE_SIZE * 8] as Any))\n        assertThat(models[PAGE_SIZE * 5], `is`((PAGE_SIZE * 5) as Any))\n    }\n\n    @Test\n    fun deletion() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.removeAt(3)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.removeAt(3)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun deletion_range() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.removeAll(items.subList(3, 5))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.removeAll(models.subList(3, 5))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun append() {\n        val newItem = Item(id = 100, value = \"newItem\")\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.add(newItem)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(newItem)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun append_many() {\n        val newItems = (100 until 105).map {\n            Item(id = it, value = \"newItem $it\")\n        }\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.addAll(newItems)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.addAll(newItems)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun insert() {\n        testListUpdate { items, models ->\n            val newItem =\n                Item(id = 100, value = \"item x\")\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.add(5, newItem)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(5, newItem)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun insert_many() {\n        testListUpdate { items, models ->\n            val newItems = (100 until 105).map {\n                Item(id = it, value = \"newItem $it\")\n            }\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.addAll(5, newItems)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.addAll(5, newItems)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun move() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun move_multiple() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                    it.add(1, it.removeAt(8))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                    it.add(1, it.removeAt(8))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun clear() {\n        val items = createItems(PAGE_SIZE)\n        val (pagedList, _) = createPagedList(items)\n        pagedListModelCache.submitList(pagedList)\n        drain()\n        pagedListModelCache.getModels()\n        assertAndResetModelBuild()\n        pagedListModelCache.clearModels()\n        pagedListModelCache.getModels()\n        assertAndResetModelBuild()\n    }\n\n    private fun assertAndResetModelBuild() {\n        assertThat(modelBuildCounter > 0, CoreMatchers.`is`(true))\n        modelBuildCounter = 0\n    }\n\n    private fun assertAndResetRebuildModels() {\n        assertThat(rebuildCounter > 0, CoreMatchers.`is`(true))\n        rebuildCounter = 0\n    }\n\n    /**\n     * Helper method to verify multiple list update scenarios\n     */\n    private fun testListUpdate(update: (items: List<Item>, models: List<Any?>) -> Modification) {\n        val items = createItems(PAGE_SIZE)\n        val (pagedList, _) = createPagedList(items)\n        pagedListModelCache.submitList(pagedList)\n        val (updatedList, expectedModels) = update(items, collectModelItems())\n        pagedListModelCache.submitList(createPagedList(updatedList).first)\n\n        val updatedModels = collectModelItems()\n        assertThat(updatedModels.size, `is`(expectedModels.size))\n        updatedModels.forEachIndexed { index, item ->\n            when (item) {\n                is Item -> {\n                    assertThat(item, CoreMatchers.sameInstance(expectedModels[index]))\n                }\n                else -> {\n                    assertThat(item, `is`(expectedModels[index]))\n                }\n            }\n        }\n    }\n\n    private fun assertModelItems(expected: List<Any?>) {\n        assertThat(collectModelItems(), `is`(expected))\n    }\n\n    @Suppress(\"IMPLICIT_CAST_TO_ANY\")\n    private fun collectModelItems(): List<Any?> {\n        drain()\n        return pagedListModelCache.getModels().map {\n            when (it) {\n                is FakeModel -> it.item\n                is FakePlaceholderModel -> it.pos\n                else -> null\n            }\n        }\n    }\n\n    private fun drain() {\n        archExecutor.drainTasks(4, TimeUnit.SECONDS)\n        InstrumentationRegistry.getInstrumentation().runOnMainSync { }\n        archExecutor.drainTasks(4, TimeUnit.SECONDS)\n        InstrumentationRegistry.getInstrumentation().runOnMainSync { }\n    }\n\n    private fun createItems(cnt: Int): List<Item> {\n        return (0 until cnt).map {\n            Item(id = it, value = \"Item $it\")\n        }\n    }\n\n    private fun createPagedList(items: List<Item>): Pair<PagedList<Item>, ListDataSource<Item>> {\n        val dataSource = ListDataSource(items)\n        val pagedList = PagedList.Builder<Int, Item>(\n            dataSource,\n            PagedList.Config.Builder()\n                .setEnablePlaceholders(true)\n                .setInitialLoadSizeHint(PAGE_SIZE * 2)\n                .setPageSize(PAGE_SIZE)\n                .build()\n        ).setFetchExecutor(Executor { it.run() })\n            .setNotifyExecutor(Executor { it.run() })\n            .build()\n        return pagedList to dataSource\n    }\n\n    class FakePlaceholderModel(val pos: Int) : EpoxyModel<View>(-pos.toLong()) {\n        override fun getDefaultLayout() = throw NotImplementedError(\"not needed for this test\")\n    }\n\n    class FakeModel(val item: Item) : EpoxyModel<View>(item.id.toLong()) {\n        override fun getDefaultLayout() = throw NotImplementedError(\"not needed for this test\")\n    }\n\n    data class Modification(\n        val newList: List<Item>,\n        val expectedModels: List<Any?>\n    )\n\n    private fun List<Item>.copyToMutable(): MutableList<Item> {\n        return mapTo(arrayListOf()) {\n            it.copy()\n        }\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 10\n        private const val INITIAL_LOAD_SIZE = PAGE_SIZE * 2\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/main/AndroidManifest.xml",
    "content": "<manifest />\n"
  },
  {
    "path": "epoxy-paging3/src/main/java/com/airbnb/epoxy/paging3/PagedDataModelCache.kt",
    "content": "package com.airbnb.epoxy.paging3\n\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.paging.AsyncPagingDataDiffer\nimport androidx.paging.CombinedLoadStates\nimport androidx.paging.ItemSnapshotList\nimport androidx.paging.PagingData\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListUpdateCallback\nimport com.airbnb.epoxy.EpoxyModel\nimport kotlinx.coroutines.android.asCoroutineDispatcher\nimport kotlinx.coroutines.flow.Flow\n\n/**\n * A pagingData stream wrapper that caches models built for each item. It tracks changes in paged Data and caches\n * models for each item when they are invalidated to avoid rebuilding models for the whole list when pagingData is\n * updated.\n *\n * The pagingData submitted to this cache must be kept in sync with the model cache. To do this,\n * the executor of the pagingData differ is set to the same thread as the model building handler.\n * However, change notifications from the PageList happen on that list's notify executor which is\n * out of our control, and we require the user to configure that properly, or an error is thrown.\n *\n * There are two special cases:\n *\n * 1. The first time models are built happens synchronously for immediate UI. In this case we don't\n * use the model cache (to avoid data synchronization issues), but attempt to fill the cache with\n * the models later.\n *\n * 2. When a pagingData is submitted it can trigger update callbacks synchronously. Since we don't control\n * that thread we allow a special case of cache modification when a new list is being submitted,\n * and all cache access is marked with @Synchronize to ensure safety when this happens.\n */\nclass PagedDataModelCache<T : Any>(\n    private val modelBuilder: (itemIndex: Int, item: T?) -> EpoxyModel<*>,\n    private val rebuildCallback: () -> Unit,\n    itemDiffCallback: DiffUtil.ItemCallback<T>,\n    private val modelBuildingHandler: Handler\n) {\n    /**\n     * Backing list for built models. This is a full array list that has null items for not yet build models.\n     */\n    private val modelCache = arrayListOf<EpoxyModel<*>?>()\n\n    /**\n     * Tracks the last accessed position so that we can report it back to the paged list when models are built.\n     */\n    private var lastPosition: Int? = null\n\n    /**\n     * Set to true while a new list is being submitted, so that we can ignore the update callback\n     * thread restriction.\n     */\n    private var inSubmitList: Boolean = false\n\n    /**\n     * Observer for the PagedList changes that invalidates the model cache when data is updated.\n     */\n    private val updateCallback = object : ListUpdateCallback {\n        override fun onChanged(position: Int, count: Int, payload: Any?) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            (position until (position + count)).forEach {\n                modelCache[it] = null\n            }\n            rebuildCallback()\n        }\n\n        override fun onMoved(fromPosition: Int, toPosition: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            val model = modelCache.removeAt(fromPosition)\n            modelCache.add(toPosition, model)\n            rebuildCallback()\n        }\n\n        override fun onInserted(position: Int, count: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            repeat(count) {\n                modelCache.add(position, null)\n            }\n            rebuildCallback()\n        }\n\n        override fun onRemoved(position: Int, count: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            repeat(count) {\n                modelCache.removeAt(position)\n            }\n            rebuildCallback()\n        }\n\n        private fun synchronizedWithCache(block: () -> Unit) {\n            synchronized(this@PagedDataModelCache) {\n                block()\n            }\n        }\n    }\n\n    /**\n     * Changes to the paged list must happen on the same thread as changes to the model cache to\n     * ensure they stay in sync.\n     *\n     * We can't force this to happen, and must instead rely on user's configuration, but we can alert\n     * when it is not configured correctly.\n     *\n     * An exception is thrown if the callback happens due to a new paged list being submitted, which can\n     * trigger a synchronous callback if the list goes from null to non null, or vice versa.\n     *\n     * Synchronization on [submitData] and other model cache access methods prevent issues when\n     * that happens.\n     */\n    private fun assertUpdateCallbacksAllowed() {\n        require(inSubmitList || Looper.myLooper() == modelBuildingHandler.looper) {\n            \"The notify executor for your PagedList must use the same thread as the model building handler set in PagedListEpoxyController.modelBuildingHandler\"\n        }\n    }\n\n    private val dispatcher = modelBuildingHandler.asCoroutineDispatcher()\n    private val asyncDiffer = AsyncPagingDataDiffer(\n        diffCallback = itemDiffCallback,\n        updateCallback = updateCallback,\n        mainDispatcher = dispatcher,\n        workerDispatcher = dispatcher\n    )\n\n    val loadStateFlow: Flow<CombinedLoadStates> get() = asyncDiffer.loadStateFlow\n\n    suspend fun submitData(pagingData: PagingData<T>) {\n        inSubmitList = true\n        asyncDiffer.submitData(pagingData)\n        inSubmitList = false\n    }\n\n    @Synchronized\n    fun getModels(): List<EpoxyModel<*>> {\n        val currentList = asyncDiffer.snapshot()\n\n        // The first time models are built the EpoxyController does so synchronously, so that\n        // the UI can be ready immediately. To avoid concurrent modification issues with the PagedList\n        // and model cache we can't allow that first build to touch the cache.\n        if (Looper.myLooper() != modelBuildingHandler.looper) {\n            return currentList.mapIndexed { position, item ->\n                modelBuilder(position, item)\n            }\n        }\n\n        (0 until modelCache.size).forEach { position ->\n            if (modelCache[position] == null) {\n                modelCache[position] = modelBuilder(position, currentList[position])\n            }\n        }\n\n        lastPosition?.let {\n            triggerLoadAround(it)\n        }\n        @Suppress(\"UNCHECKED_CAST\")\n        return modelCache as List<EpoxyModel<*>>\n    }\n\n    /**\n     * Clears all cached models to force them to be rebuilt next time models are retrieved.\n     * This is posted to the model building thread to maintain data synchronicity.\n     */\n    fun clearModels() {\n        modelBuildingHandler.post {\n            clearModelsSynchronized()\n        }\n    }\n\n    fun retry() {\n        asyncDiffer.retry()\n    }\n\n    fun refresh() {\n        asyncDiffer.refresh()\n    }\n\n    fun addLoadStateListener(listener: (CombinedLoadStates) -> Unit) {\n        asyncDiffer.addLoadStateListener(listener)\n    }\n\n    fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit) {\n        asyncDiffer.removeLoadStateListener(listener)\n    }\n\n    fun snapshot(): ItemSnapshotList<T> {\n        return asyncDiffer.snapshot()\n    }\n\n    @Synchronized\n    private fun clearModelsSynchronized() {\n        modelCache.fill(null)\n    }\n\n    fun loadAround(position: Int) {\n        triggerLoadAround(position)\n        lastPosition = position\n    }\n\n    private fun triggerLoadAround(position: Int) {\n        if (asyncDiffer.itemCount > 0) {\n            asyncDiffer.getItem(position.coerceIn(0, asyncDiffer.itemCount - 1))\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/main/java/com/airbnb/epoxy/paging3/PagedListEpoxyController.kt",
    "content": "/*\n * Copyright 2018 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.airbnb.epoxy.paging3\n\nimport android.annotation.SuppressLint\nimport android.os.Handler\nimport androidx.paging.PagedList\nimport androidx.recyclerview.widget.DiffUtil\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyViewHolder\n\n/**\n * An [EpoxyController] that can work with a [PagedList].\n *\n * Internally, it caches the model for each item in the [PagedList]. You should override\n * [buildItemModel] method to build the model for the given item. Since [PagedList] might include\n * `null` items if placeholders are enabled, this method needs to handle `null` values in the list.\n *\n * By default, the model for each item is added  to the model list. To change this behavior (to\n * filter items or inject extra items), you can override [addModels] function and manually add built\n * models.\n *\n * @param T The type of the items in the [PagedList].\n */\nabstract class PagedListEpoxyController<T : Any>(\n    /**\n     * The handler to use for building models. By default this uses the main thread, but you can use\n     * [EpoxyAsyncUtil.getAsyncBackgroundHandler] to do model building in the background.\n     *\n     * The notify thread of your PagedList (from setNotifyExecutor in the PagedList Builder) must be\n     * the same as this thread. Otherwise Epoxy will crash.\n     */\n    modelBuildingHandler: Handler = EpoxyController.defaultModelBuildingHandler,\n    /**\n     * The handler to use when calculating the diff between built model lists.\n     * By default this uses the main thread, but you can use\n     * [EpoxyAsyncUtil.getAsyncBackgroundHandler] to do diffing in the background.\n     */\n    diffingHandler: Handler = EpoxyController.defaultDiffingHandler,\n    /**\n     * [PagedListEpoxyController] uses an [DiffUtil.ItemCallback] to detect changes between\n     * [PagedList]s. By default, it relies on simple object equality but you can provide a custom\n     * one if you don't use all fields in the object in your models.\n     */\n    itemDiffCallback: DiffUtil.ItemCallback<T> = DEFAULT_ITEM_DIFF_CALLBACK as DiffUtil.ItemCallback<T>\n) : EpoxyController(modelBuildingHandler, diffingHandler) {\n    // this is where we keep the already built models\n    val modelCache = PagedListModelCache(\n        modelBuilder = { pos, item ->\n            buildItemModel(pos, item)\n        },\n        rebuildCallback = {\n            requestModelBuild()\n        },\n        itemDiffCallback = itemDiffCallback,\n        modelBuildingHandler = modelBuildingHandler\n    )\n\n    final override fun buildModels() {\n        addModels(modelCache.getModels())\n    }\n\n    /**\n     * This function adds all built models to the adapter. You can override this method to add extra\n     * items into the model list or remove some.\n     */\n    open fun addModels(models: List<EpoxyModel<*>>) {\n        super.add(models)\n    }\n\n    /**\n     * Builds the model for a given item. This must return a single model for each item. If you want\n     * to inject headers etc, you can override [addModels] function.\n     *\n     * If the `item` is `null`, you should provide the placeholder. If your [PagedList] is\n     * configured without placeholders, you don't need to handle the `null` case.\n     */\n    abstract fun buildItemModel(currentPosition: Int, item: T?): EpoxyModel<*>\n\n    override fun onModelBound(\n        holder: EpoxyViewHolder,\n        boundModel: EpoxyModel<*>,\n        position: Int,\n        previouslyBoundModel: EpoxyModel<*>?\n    ) {\n        // TODO the position may not be a good value if there are too many injected items.\n        modelCache.loadAround(position)\n    }\n\n    /**\n     * Submit a new paged list.\n     *\n     * A diff will be calculated between this list and the previous list so you may still get calls\n     * to [buildItemModel] with items from the previous list.\n     */\n    fun submitList(newList: PagedList<T>?) {\n        modelCache.submitList(newList)\n    }\n\n    /**\n     * Requests a model build that will run for every model, including the ones created for the paged\n     * list.\n     *\n     * Clears the current model cache to make sure that happens.\n     */\n    fun requestForcedModelBuild() {\n        modelCache.clearModels()\n        requestModelBuild()\n    }\n\n    companion object {\n        /**\n         * [PagedListEpoxyController] calculates a diff on top of the PagedList to check which\n         * models are invalidated.\n         * This is the default [DiffUtil.ItemCallback] which uses object equality.\n         */\n        val DEFAULT_ITEM_DIFF_CALLBACK = object : DiffUtil.ItemCallback<Any>() {\n            override fun areItemsTheSame(oldItem: Any, newItem: Any) = oldItem == newItem\n\n            @SuppressLint(\"DiffUtilEquals\")\n            override fun areContentsTheSame(oldItem: Any, newItem: Any) = oldItem == newItem\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/main/java/com/airbnb/epoxy/paging3/PagedListModelCache.kt",
    "content": "/*\n * Copyright 2018 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.airbnb.epoxy.paging3\n\nimport android.annotation.SuppressLint\nimport android.os.Handler\nimport android.os.Looper\nimport android.util.Log\nimport androidx.paging.AsyncPagedListDiffer\nimport androidx.paging.PagedList\nimport androidx.recyclerview.widget.AsyncDifferConfig\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListUpdateCallback\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport java.util.concurrent.Executor\n\n/**\n * A PagedList stream wrapper that caches models built for each item. It tracks changes in paged lists and caches\n * models for each item when they are invalidated to avoid rebuilding models for the whole list when PagedList is\n * updated.\n *\n * The PagedList submitted to this cache must be kept in sync with the model cache. To do this,\n * the executor of the PagedList differ is set to the same thread as the model building handler.\n * However, change notifications from the PageList happen on that list's notify executor which is\n * out of our control, and we require the user to configure that properly, or an error is thrown.\n *\n * There are two special cases:\n *\n * 1. The first time models are built happens synchronously for immediate UI. In this case we don't\n * use the model cache (to avoid data synchronization issues), but attempt to fill the cache with\n * the models later.\n *\n * 2. When a list is submitted it can trigger update callbacks synchronously. Since we don't control\n * that thread we allow a special case of cache modification when a new list is being submitted,\n * and all cache access is marked with @Synchronize to ensure safety when this happens.\n */\nclass PagedListModelCache<T : Any>(\n    private val modelBuilder: (itemIndex: Int, item: T?) -> EpoxyModel<*>,\n    private val rebuildCallback: () -> Unit,\n    private val itemDiffCallback: DiffUtil.ItemCallback<T>,\n    private val diffExecutor: Executor? = null,\n    private val modelBuildingHandler: Handler\n) {\n    /**\n     * Backing list for built models. This is a full array list that has null items for not yet build models.\n     */\n    private val modelCache = arrayListOf<EpoxyModel<*>?>()\n    /**\n     * Tracks the last accessed position so that we can report it back to the paged list when models are built.\n     */\n    private var lastPosition: Int? = null\n\n    /**\n     * Set to true while a new list is being submitted, so that we can ignore the update callback\n     * thread restriction.\n     */\n    private var inSubmitList: Boolean = false\n\n    /**\n     * Observer for the PagedList changes that invalidates the model cache when data is updated.\n     */\n    private val updateCallback = object : ListUpdateCallback {\n        override fun onChanged(position: Int, count: Int, payload: Any?) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            (position until (position + count)).forEach {\n                modelCache[it] = null\n            }\n            rebuildCallback()\n        }\n\n        override fun onMoved(fromPosition: Int, toPosition: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            val model = modelCache.removeAt(fromPosition)\n            modelCache.add(toPosition, model)\n            rebuildCallback()\n        }\n\n        override fun onInserted(position: Int, count: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            (0 until count).forEach {\n                modelCache.add(position, null)\n            }\n            rebuildCallback()\n        }\n\n        override fun onRemoved(position: Int, count: Int) = synchronizedWithCache {\n            assertUpdateCallbacksAllowed()\n            (0 until count).forEach {\n                modelCache.removeAt(position)\n            }\n            rebuildCallback()\n        }\n\n        private fun synchronizedWithCache(block: () -> Unit) {\n            synchronized(this@PagedListModelCache) {\n                block()\n            }\n        }\n    }\n\n    /**\n     * Changes to the paged list must happen on the same thread as changes to the model cache to\n     * ensure they stay in sync.\n     *\n     * We can't force this to happen, and must instead rely on user's configuration, but we can alert\n     * when it is not configured correctly.\n     *\n     * An exception is thrown if the callback happens due to a new paged list being submitted, which can\n     * trigger a synchronous callback if the list goes from null to non null, or vice versa.\n     *\n     * Synchronization on [submitList] and other model cache access methods prevent issues when\n     * that happens.\n     */\n    private fun assertUpdateCallbacksAllowed() {\n        require(inSubmitList || Looper.myLooper() == modelBuildingHandler.looper) {\n            \"The notify executor for your PagedList must use the same thread as the model building handler set in PagedListEpoxyController.modelBuildingHandler\"\n        }\n    }\n\n    @SuppressLint(\"RestrictedApi\")\n    private val asyncDiffer = object : AsyncPagedListDiffer<T>(\n        updateCallback,\n        AsyncDifferConfig.Builder<T>(\n            itemDiffCallback\n        ).also { builder ->\n            if (diffExecutor != null) {\n                builder.setBackgroundThreadExecutor(diffExecutor)\n            }\n\n            // we have to reply on this private API, otherwise, paged list might be changed when models are being built,\n            // potentially creating concurrent modification problems.\n            builder.setMainThreadExecutor { runnable: Runnable ->\n                modelBuildingHandler.post(runnable)\n            }\n        }.build()\n    ) {\n        init {\n            if (modelBuildingHandler != EpoxyController.defaultModelBuildingHandler) {\n                try {\n                    // looks like AsyncPagedListDiffer in 1.x ignores the config.\n                    // Reflection to the rescue.\n                    val mainThreadExecutorField =\n                        AsyncPagedListDiffer::class.java.getDeclaredField(\"mainThreadExecutor\")\n                    mainThreadExecutorField.isAccessible = true\n                    mainThreadExecutorField.set(\n                        this,\n                        Executor {\n                            modelBuildingHandler.post(it)\n                        }\n                    )\n                } catch (t: Throwable) {\n                    val msg = \"Failed to hijack update handler in AsyncPagedListDiffer.\" +\n                        \"You can only build models on the main thread\"\n                    Log.e(\"PagedListModelCache\", msg, t)\n                    throw IllegalStateException(msg, t)\n                }\n            }\n        }\n    }\n\n    @Synchronized\n    fun submitList(pagedList: PagedList<T>?) {\n        inSubmitList = true\n        asyncDiffer.submitList(pagedList)\n        inSubmitList = false\n    }\n\n    @Synchronized\n    fun getModels(): List<EpoxyModel<*>> {\n        val currentList = asyncDiffer.currentList ?: emptyList<T>()\n\n        // The first time models are built the EpoxyController does so synchronously, so that\n        // the UI can be ready immediately. To avoid concurrent modification issues with the PagedList\n        // and model cache we can't allow that first build to touch the cache.\n        if (Looper.myLooper() != modelBuildingHandler.looper) {\n            val initialModels = currentList.mapIndexed { position, item ->\n                modelBuilder(position, item)\n            }\n\n            // If the paged list still hasn't changed then we can populate the cache\n            // with the models we built to avoid needing to rebuild them later.\n            modelBuildingHandler.post {\n                setCacheValues(currentList, initialModels)\n            }\n\n            return initialModels\n        }\n\n        (0 until modelCache.size).forEach { position ->\n            if (modelCache[position] == null) {\n                modelCache[position] = modelBuilder(position, currentList[position])\n            }\n        }\n\n        lastPosition?.let {\n            triggerLoadAround(it)\n        }\n        @Suppress(\"UNCHECKED_CAST\")\n        return modelCache as List<EpoxyModel<*>>\n    }\n\n    @Synchronized\n    private fun setCacheValues(\n        originatingList: List<T>,\n        initialModels: List<EpoxyModel<*>>\n    ) {\n        if (asyncDiffer.currentList === originatingList) {\n            modelCache.clear()\n            modelCache.addAll(initialModels)\n        }\n    }\n\n    /**\n     * Clears all cached models to force them to be rebuilt next time models are retrieved.\n     * This is posted to the model building thread to maintain data synchronicity.\n     */\n    fun clearModels() {\n        modelBuildingHandler.post {\n            clearModelsSynchronized()\n        }\n    }\n\n    @Synchronized\n    private fun clearModelsSynchronized() {\n        modelCache.fill(null)\n    }\n\n    fun loadAround(position: Int) {\n        triggerLoadAround(position)\n        lastPosition = position\n    }\n\n    private fun triggerLoadAround(position: Int) {\n        asyncDiffer.currentList?.let {\n            if (it.size > 0) {\n                it.loadAround(Math.min(position, it.size - 1))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/main/java/com/airbnb/epoxy/paging3/PagingDataEpoxyController.kt",
    "content": "package com.airbnb.epoxy.paging3\n\nimport android.annotation.SuppressLint\nimport android.os.Handler\nimport androidx.paging.CombinedLoadStates\nimport androidx.paging.ItemSnapshotList\nimport androidx.paging.LoadState\nimport androidx.paging.LoadType.REFRESH\nimport androidx.paging.PagingData\nimport androidx.paging.PagingSource\nimport androidx.paging.RemoteMediator\nimport androidx.recyclerview.widget.DiffUtil\nimport com.airbnb.epoxy.EpoxyAsyncUtil\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyViewHolder\nimport kotlinx.coroutines.flow.Flow\n\n/**\n * An [EpoxyController] that can work with a [PagingData].\n *\n * Internally, it caches the model for each item in the [PagingData]. You must override\n * [buildItemModel] method to build the model for the given item. Since [PagingData] might include\n * `null` items if placeholders are enabled, this method needs to handle `null` values in the list.\n *\n * By default, the model for each item is added  to the model list. To change this behavior (to\n * filter items or inject extra items), you can override [addModels] function and manually add built\n * models.\n *\n * @param T The type of the item in the [PagingData].\n */\nabstract class PagingDataEpoxyController<T : Any>(\n    /**\n     * The handler to use for building models. By default this uses the main thread, but you can use\n     * [EpoxyAsyncUtil.getAsyncBackgroundHandler] to do model building in the background.\n     *\n     * The notify thread of your PagedList (from setNotifyExecutor in the pagingData Builder) must be\n     * the same as this thread. Otherwise Epoxy will crash.\n     */\n    modelBuildingHandler: Handler = defaultModelBuildingHandler,\n    /**\n     * The handler to use when calculating the diff between built model lists.\n     * By default this uses the main thread, but you can use\n     * [EpoxyAsyncUtil.getAsyncBackgroundHandler] to do diffing in the background.\n     */\n    diffingHandler: Handler = defaultDiffingHandler,\n    /**\n     * [PagingDataEpoxyController] uses an [DiffUtil.ItemCallback] to detect changes between\n     * [PagingData]s. By default, it relies on simple object equality but you can provide a custom\n     * one if you don't use all fields in the object in your models.\n     */\n    itemDiffCallback: DiffUtil.ItemCallback<T> = DEFAULT_ITEM_DIFF_CALLBACK as DiffUtil.ItemCallback<T>\n) : EpoxyController(modelBuildingHandler, diffingHandler) {\n    // this is where we keep the already built models\n    val modelCache = PagedDataModelCache(\n        modelBuilder = { pos, item ->\n            buildItemModel(pos, item)\n        },\n        rebuildCallback = {\n            requestModelBuild()\n        },\n        itemDiffCallback = itemDiffCallback,\n        modelBuildingHandler = modelBuildingHandler\n    )\n\n    /**\n     * A hot [Flow] of [CombinedLoadStates] that emits a snapshot whenever the loading state of the\n     * current [PagingData] changes.\n     *\n     * This flow is conflated, so it buffers the last update to [CombinedLoadStates] and\n     * immediately delivers the current load states on collection.\n     */\n    val loadStateFlow: Flow<CombinedLoadStates> get() = modelCache.loadStateFlow\n\n    final override fun buildModels() {\n        addModels(modelCache.getModels())\n    }\n\n    /**\n     * This function adds all built models to the adapter. You can override this method to add extra\n     * items into the model list or remove some.\n     */\n    open fun addModels(models: List<EpoxyModel<*>>) {\n        super.add(models)\n    }\n\n    /**\n     * Builds the model for a given item. This must return a single model for each item. If you want\n     * to inject headers etc, you can override [addModels] function.\n     *\n     * If the `item` is `null`, you should provide the placeholder. If your [PagingData] is\n     * configured without placeholders, you don't need to handle the `null` case.\n     */\n    abstract fun buildItemModel(currentPosition: Int, item: T?): EpoxyModel<*>\n\n    override fun onModelBound(\n        holder: EpoxyViewHolder,\n        boundModel: EpoxyModel<*>,\n        position: Int,\n        previouslyBoundModel: EpoxyModel<*>?\n    ) {\n        // TODO the position may not be a good value if there are too many injected items.\n        modelCache.loadAround(position)\n    }\n\n    /**\n     * Submit a new pagingData.\n     *\n     * A diff will be calculated between this pagingData and the previous pagingData so you may still get calls\n     * to [buildItemModel] with items from the previous PagingData.\n     */\n    open suspend fun submitData(pagingData: PagingData<T>) {\n        modelCache.submitData(pagingData)\n    }\n\n    /**\n     * Retry any failed load requests that would result in a [LoadState.Error] update to this\n     * [PagingDataEpoxyController]\n     *\n     * [LoadState.Error] can be generated from two types of load requests:\n     *  * [PagingSource.load] returning [PagingSource.LoadResult.Error]\n     *  * [RemoteMediator.load] returning [RemoteMediator.MediatorResult.Error]\n     */\n    fun retry() {\n        modelCache.retry()\n    }\n\n    /**\n     * Refresh the data presented by this [PagingDataEpoxyController].\n     *\n     * [refresh] triggers the creation of a new [PagingData] with a new instance of [PagingSource]\n     * to represent an updated snapshot of the backing dataset. If a [RemoteMediator] is set,\n     * calling [refresh] will also trigger a call to [RemoteMediator.load] with\n     * [LoadType.REFRESH][REFRESH] to allow [RemoteMediator] to check for updates to the dataset\n     * backing [PagingSource].\n     */\n    fun refresh() {\n        modelCache.refresh()\n    }\n\n    /**\n     * Add a [CombinedLoadStates] listener to observe the loading state of the current [PagingData].\n     *\n     * As new [PagingData] generations are submitted and displayed, the listener will be notified to\n     * reflect the current [CombinedLoadStates].\n     */\n    fun addLoadStateListener(listener: (CombinedLoadStates) -> Unit) {\n        modelCache.addLoadStateListener(listener)\n    }\n\n    /**\n     * Remove a previously registered [CombinedLoadStates] listener.\n     */\n    fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit) {\n        modelCache.removeLoadStateListener(listener)\n    }\n\n    /**\n     * Returns a new [ItemSnapshotList] representing the currently presented items, including any\n     * placeholders if they are enabled.\n     */\n    fun snapshot(): ItemSnapshotList<T> {\n        return modelCache.snapshot()\n    }\n\n    /**\n     * Requests a model build that will run for every model, including the ones created for the paged\n     * list.\n     *\n     * Clears the current model cache to make sure that happens.\n     */\n    fun requestForcedModelBuild() {\n        modelCache.clearModels()\n        requestModelBuild()\n    }\n\n    companion object {\n        /**\n         * [PagingDataEpoxyController] calculates a diff on top of the PagingData to check which\n         * models are invalidated.\n         * This is the default [DiffUtil.ItemCallback] which uses object equality.\n         */\n        val DEFAULT_ITEM_DIFF_CALLBACK = object : DiffUtil.ItemCallback<Any>() {\n            override fun areItemsTheSame(oldItem: Any, newItem: Any) = oldItem == newItem\n\n            @SuppressLint(\"DiffUtilEquals\")\n            override fun areContentsTheSame(oldItem: Any, newItem: Any) = oldItem == newItem\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/test/java/com/airbnb/epoxy/paging3/DummyItem.kt",
    "content": "package com.airbnb.epoxy.paging3\n\nimport androidx.recyclerview.widget.DiffUtil\n\n/**\n * Dummy item for testing.\n */\ndata class DummyItem(val id: Int, val value: String) {\n    companion object {\n        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DummyItem>() {\n            override fun areItemsTheSame(oldItem: DummyItem, newItem: DummyItem) = oldItem.id == newItem.id\n\n            override fun areContentsTheSame(oldItem: DummyItem, newItem: DummyItem) = oldItem == newItem\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-paging3/src/test/java/com/airbnb/epoxy/paging3/ListPagingSource.kt",
    "content": "package com.airbnb.epoxy.paging3\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.withContext\nimport kotlin.coroutines.CoroutineContext\n\nclass ListPagingSource<T : Any>(\n    private val coroutineContext: CoroutineContext,\n    private val defaultDelay: Long,\n    private val data: List<T>\n) :\n    PagingSource<Int, T>() {\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {\n        return withContext(coroutineContext) {\n            delay(defaultDelay)\n            val key = params.key ?: 0\n            LoadResult.Page(data.subList(key, key + params.loadSize), null, key + params.loadSize)\n        }\n    }\n\n    override fun getRefreshKey(state: PagingState<Int, T>): Int? = null\n\n    override val jumpingSupported: Boolean\n        get() = super.jumpingSupported\n}\n"
  },
  {
    "path": "epoxy-paging3/src/test/java/com/airbnb/epoxy/paging3/PagedDataModelCacheTest.kt",
    "content": "package com.airbnb.epoxy.paging3\n\nimport android.view.View\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.EpoxyModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.ObsoleteCoroutinesApi\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.test.advanceTimeBy\nimport kotlinx.coroutines.test.runTest\nimport org.hamcrest.CoreMatchers\nimport org.hamcrest.MatcherAssert\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\nimport org.robolectric.annotation.LooperMode\nimport kotlin.coroutines.CoroutineContext\n\n@ExperimentalCoroutinesApi\n@ObsoleteCoroutinesApi\n@RunWith(RobolectricTestRunner::class)\n@LooperMode(LooperMode.Mode.LEGACY)\nclass PagedDataModelCacheTest {\n\n    /**\n     * Simple mode builder for [DummyItem]\n     */\n    private var modelBuildCounter = 0\n    private val modelBuilder: (Int, DummyItem?) -> EpoxyModel<*> = { pos, item ->\n        modelBuildCounter++\n        if (item == null) {\n            FakePlaceholderModel(pos)\n        } else {\n            FakeModel(item)\n        }\n    }\n\n    /**\n     * Number of times a rebuild is requested\n     */\n    private var rebuildCounter = 0\n    private val rebuildCallback: () -> Unit = {\n        rebuildCounter++\n    }\n\n    private val pagedDataModelCache =\n        PagedDataModelCache(\n            modelBuilder = modelBuilder,\n            rebuildCallback = rebuildCallback,\n            itemDiffCallback = DummyItem.DIFF_CALLBACK,\n            modelBuildingHandler = EpoxyController.defaultModelBuildingHandler\n        )\n\n    @Test\n    fun empty() {\n        MatcherAssert.assertThat(pagedDataModelCache.getModels(), CoreMatchers.`is`(emptyList()))\n    }\n\n    @Test\n    fun simple() = runBlocking {\n        val items = createDummyItems(PAGE_SIZE)\n        val pagedData = createPagedData(items)\n        pagedDataModelCache.submitData(pagedData)\n        assertModelDummyItems(items)\n        assertAndResetRebuildModels()\n    }\n\n    @Test\n    fun partialLoad() = runTest {\n        val items = createDummyItems(INITIAL_LOAD_SIZE + PAGE_SIZE)\n        val pager = createPager(this.coroutineContext, items)\n        val deferred = async {\n            pager.flow.collectLatest {\n                pagedDataModelCache.submitData(it)\n            }\n        }\n        // advance in time to create first page of data\n        advanceTimeBy(DEFAULT_DELAY)\n\n        // wait for pagedDataModelCache submits data\n        delay(2000)\n\n        assertModelDummyItems(items.subList(0, INITIAL_LOAD_SIZE))\n        assertAndResetRebuildModels()\n        pagedDataModelCache.loadAround(INITIAL_LOAD_SIZE - 1)\n        assertModelDummyItems(items.subList(0, INITIAL_LOAD_SIZE))\n        MatcherAssert.assertThat(rebuildCounter, CoreMatchers.`is`(0))\n        // advance in time to create second page of data\n        advanceTimeBy(DEFAULT_DELAY)\n        delay(2000)\n        assertModelDummyItems(items)\n        assertAndResetRebuildModels()\n\n        deferred.cancel()\n    }\n\n    @Test\n    fun deletion() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.removeAt(3)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.removeAt(3)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun deletion_range() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.removeAll(items.subList(3, 5))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.removeAll(models.subList(3, 5))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun append() {\n        val newDummyItem = DummyItem(id = 100, value = \"newDummyItem\")\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.add(newDummyItem)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(newDummyItem)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun append_many() {\n        val newDummyItems = (100 until 105).map {\n            DummyItem(id = it, value = \"newDummyItem $it\")\n        }\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.addAll(newDummyItems)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.addAll(newDummyItems)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun insert() {\n        testListUpdate { items, models ->\n            val newDummyItem =\n                DummyItem(id = 100, value = \"item x\")\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.add(5, newDummyItem)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(5, newDummyItem)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun insert_many() {\n        testListUpdate { items, models ->\n            val newDummyItems = (100 until 105).map {\n                DummyItem(id = it, value = \"newDummyItem $it\")\n            }\n            Modification(\n                newList = items.copyToMutable().also {\n                    it.addAll(5, newDummyItems)\n                },\n                expectedModels = models.toMutableList().also {\n                    it.addAll(5, newDummyItems)\n                }\n            )\n        }\n    }\n\n    @Test\n    fun move() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun move_multiple() {\n        testListUpdate { items, models ->\n            Modification(\n                newList = items.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                    it.add(1, it.removeAt(8))\n                },\n                expectedModels = models.toMutableList().also {\n                    it.add(3, it.removeAt(5))\n                    it.add(1, it.removeAt(8))\n                }\n            )\n        }\n    }\n\n    @Test\n    fun clear() = runBlocking {\n        val items = createDummyItems(PAGE_SIZE)\n        val pagedData = createPagedData(items)\n        pagedDataModelCache.submitData(pagedData)\n        pagedDataModelCache.getModels()\n        assertAndResetModelBuild()\n        pagedDataModelCache.clearModels()\n        pagedDataModelCache.getModels()\n        assertAndResetModelBuild()\n    }\n\n    private fun assertAndResetModelBuild() {\n        MatcherAssert.assertThat(modelBuildCounter > 0, CoreMatchers.`is`(true))\n        modelBuildCounter = 0\n    }\n\n    private fun assertAndResetRebuildModels() {\n        MatcherAssert.assertThat(rebuildCounter > 0, CoreMatchers.`is`(true))\n        rebuildCounter = 0\n    }\n\n    /**\n     * Helper method to verify multiple list update scenarios\n     */\n    private fun testListUpdate(update: (items: List<DummyItem>, models: List<Any?>) -> Modification) =\n        runBlocking {\n            val items = createDummyItems(PAGE_SIZE)\n            pagedDataModelCache.submitData(createPagedData(items))\n            val (updatedList, expectedModels) = update(items, collectModelDummyItems())\n            pagedDataModelCache.submitData(createPagedData(updatedList))\n\n            val updatedModels = collectModelDummyItems()\n            MatcherAssert.assertThat(updatedModels.size, CoreMatchers.`is`(expectedModels.size))\n            updatedModels.forEachIndexed { index, item ->\n                when (item) {\n                    is DummyItem -> {\n                        assertEquals(item, expectedModels[index])\n                    }\n                    else -> {\n                        MatcherAssert.assertThat(item, CoreMatchers.`is`(expectedModels[index]))\n                    }\n                }\n            }\n        }\n\n    private fun assertModelDummyItems(expected: List<Any?>) {\n        MatcherAssert.assertThat(collectModelDummyItems(), CoreMatchers.`is`(expected))\n    }\n\n    @Suppress(\"IMPLICIT_CAST_TO_ANY\")\n    private fun collectModelDummyItems(): List<Any?> {\n        return pagedDataModelCache.getModels().map {\n            when (it) {\n                is FakeModel -> it.item\n                is FakePlaceholderModel -> it.pos\n                else -> null\n            }\n        }\n    }\n\n    private fun createDummyItems(cnt: Int): List<DummyItem> {\n        return (0 until cnt).map {\n            DummyItem(id = it, value = \"DummyItem $it\")\n        }\n    }\n\n    private fun createPagedData(items: List<DummyItem>): PagingData<DummyItem> {\n        return PagingData.from(items)\n    }\n\n    private fun createPager(\n        coroutineContext: CoroutineContext,\n        items: List<DummyItem>\n    ): Pager<Int, DummyItem> {\n        return Pager(\n            config = PagingConfig(\n                pageSize = PAGE_SIZE,\n                initialLoadSize = INITIAL_LOAD_SIZE,\n                enablePlaceholders = true,\n            ),\n            initialKey = null,\n            pagingSourceFactory = {\n                ListPagingSource(coroutineContext, DEFAULT_DELAY, items)\n            }\n        )\n    }\n\n    class FakePlaceholderModel(val pos: Int) : EpoxyModel<View>(-pos.toLong()) {\n        override fun getDefaultLayout() = throw NotImplementedError(\"not needed for this test\")\n    }\n\n    class FakeModel(val item: DummyItem) : EpoxyModel<View>(item.id.toLong()) {\n        override fun getDefaultLayout() = throw NotImplementedError(\"not needed for this test\")\n    }\n\n    data class Modification(\n        val newList: List<DummyItem>,\n        val expectedModels: List<Any?>\n    )\n\n    private fun List<DummyItem>.copyToMutable(): MutableList<DummyItem> {\n        return mapTo(arrayListOf()) {\n            it.copy()\n        }\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 10\n        private const val INITIAL_LOAD_SIZE = PAGE_SIZE * 2\n        private const val DEFAULT_DELAY = 10000L\n    }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-preloadersample/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.preloadersample'\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.preloadersample\"\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    versionCode 1\n    versionName \"1.0\"\n\n    testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n\n  buildFeatures {\n    viewBinding true\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-glide-preloader')\n  kapt project(':epoxy-processor')\n\n  implementation rootProject.deps.glide\n\n  implementation rootProject.deps.androidRecyclerView\n  implementation rootProject.deps.androidCardView\n  implementation rootProject.deps.androidAppcompat\n  testImplementation rootProject.deps.junit\n  androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0-alpha2', {\n    exclude group: 'com.android.support', module: 'support-annotations'\n  })\n}\n"
  },
  {
    "path": "epoxy-preloadersample/gradle.properties",
    "content": "# Remove once glide is updated to androidx\nandroid.enableJetifier=true"
  },
  {
    "path": "epoxy-preloadersample/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <application\n            android:icon=\"@drawable/ic_launcher_background\"\n            android:label=\"@string/app_name\"\n            android:supportsRtl=\"true\"\n            android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity android:name=\".PreloadActivity\"></activity>\n        <activity android:name=\".NoPreloadActivity\"></activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/ImageModel.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport android.view.View\nimport android.view.ViewParent\nimport android.widget.ImageView\nimport android.widget.TextView\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.preload.Preloadable\nimport com.bumptech.glide.Glide\n\n@EpoxyModelClass(layout = R.layout.list_item)\nabstract class ImageModel : EpoxyModelWithHolder<ImageHolder>() {\n\n    @EpoxyAttribute\n    lateinit var imageUrl: String\n    @EpoxyAttribute\n    lateinit var text: String\n\n    @EpoxyAttribute\n    var preloading: Boolean = false\n\n    override fun bind(holder: ImageHolder) {\n        holder.glide.loadImage(imageUrl, preloading).into(holder.image)\n        holder.text.text = text\n    }\n\n    override fun unbind(holder: ImageHolder) {\n        holder.glide.clear(holder.image)\n        holder.image.setImageDrawable(null)\n    }\n}\n\nclass ImageHolder(parent: ViewParent) : KotlinHolder(), Preloadable {\n    val image by bind<ImageView>(R.id.image_view)\n    val text by bind<TextView>(R.id.text_view)\n    val glide = Glide.with((parent as View).context)\n    override val viewsToPreload by lazy { listOf(image) }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/ImagesController.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport com.airbnb.epoxy.TypedEpoxyController\n\nclass ImagesController(private val isPreloading: Boolean) : TypedEpoxyController<Array<String>>() {\n\n    override fun buildModels(data: Array<String>) {\n\n        data.forEachIndexed { index, url ->\n\n            image {\n                id(\"image_id_$url\")\n                imageUrl(url)\n                text(\"Image Number: $index\")\n                preloading(this@ImagesController.isPreloading)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/KotlinHolder.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyHolder\nimport kotlin.properties.ReadOnlyProperty\nimport kotlin.reflect.KProperty\n\n/**\n * A pattern for easier view binding with an [EpoxyHolder]\n *\n * See SampleKotlinModelWithHolder for a usage example.\n */\nabstract class KotlinHolder : EpoxyHolder() {\n\n    private lateinit var view: View\n\n    override fun bindView(itemView: View) {\n        view = itemView\n    }\n\n    protected fun <V : View> bind(id: Int): ReadOnlyProperty<KotlinHolder, V> =\n        Lazy { holder: KotlinHolder, prop ->\n            holder.view.findViewById(id) as V?\n                ?: throw IllegalStateException(\"View ID $id for '${prop.name}' not found.\")\n        }\n\n    /**\n     * Taken from Kotterknife.\n     * https://github.com/JakeWharton/kotterknife\n     */\n    private class Lazy<V>(\n        private val initializer: (KotlinHolder, KProperty<*>) -> V\n    ) : ReadOnlyProperty<KotlinHolder, V> {\n        private object EMPTY\n\n        private var value: Any? = EMPTY\n\n        override fun getValue(thisRef: KotlinHolder, property: KProperty<*>): V {\n            if (value == EMPTY) {\n                value = initializer(thisRef, property)\n            }\n            @Suppress(\"UNCHECKED_CAST\")\n            return value as V\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/MainActivity.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport android.annotation.SuppressLint\nimport android.content.Intent\nimport android.os.AsyncTask\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.preloadersample.databinding.ActivityMainBinding\nimport com.bumptech.glide.Glide\n\nclass MainActivity : AppCompatActivity() {\n\n    companion object {\n        const val IMAGES_LIST_TAG = \"images_list_tag_extra\"\n    }\n\n    private val images = arrayOf(\n        \"https://i.redd.it/nbju2rir9xp11.jpg\",\n        \"https://i.redditmedia.com/pA8syU4qzqyqn8ggXxZntuM-JIvBWGQvRo1c44yIvPs.jpg?s=b92a768940b1fa07b54e47d5dbe95f99\",\n        \"https://i.redd.it/g7cv0byl5wp11.jpg\",\n        \"https://i.redd.it/c2ozz6pdhyp11.jpg\",\n        \"https://i.redd.it/y20c2oi9myp11.jpg\",\n        \"https://i.redd.it/6b740x7ptyp11.jpg\",\n        \"https://i.redd.it/qqi87wl8uup11.jpg\",\n        \"https://i.redditmedia.com/7PuRyOWNt8vu4uygz0Xajlms9URmNp2_9z4xC-jSseA.jpg?s=3ddfadc3de602db2d98985470b36aa00\",\n        \"https://i.redd.it/hpz1lhk1jzp11.jpg\",\n        \"https://i.redd.it/kkzgwnb0rtt11.jpg\",\n        \"https://i.redd.it/hosvfvb7yxp11.jpg\",\n        \"https://i.redd.it/x0v1ixpp3yp11.jpg\",\n        \"https://i.redd.it/u4ofokaxuyp11.jpg\",\n        \"https://i.redditmedia.com/OHQZkFAaBOP-PNiQB-reJojV37CGu-TIa7wtoci0hXU.jpg?s=e2f84c1fc171090229a566104e7c77b0\"\n    )\n\n    @SuppressLint(\"StaticFieldLeak\")\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        val binding = ActivityMainBinding.inflate(layoutInflater)\n        setContentView(binding.root)\n\n        // Memory and disk cache is cleared to give accurate representation of load times\n        Glide.get(this).clearMemory()\n\n        object : AsyncTask<Unit, Unit, Unit>() {\n            override fun doInBackground(vararg params: Unit?) {\n                Glide.get(applicationContext).clearDiskCache()\n            }\n        }.execute()\n\n        binding.buttonNoPreload.setOnClickListener {\n            val intent = Intent(this, NoPreloadActivity::class.java)\n            intent.putExtra(IMAGES_LIST_TAG, images)\n\n            startActivity(intent)\n        }\n\n        binding.buttonPreload.setOnClickListener {\n            val intent = Intent(this, PreloadActivity::class.java)\n            intent.putExtra(IMAGES_LIST_TAG, images)\n\n            startActivity(intent)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/NoPreloadActivity.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.preloadersample.databinding.ListActivityBinding\n\nclass NoPreloadActivity : AppCompatActivity() {\n\n    private val images by lazy { intent.getStringArrayExtra(MainActivity.IMAGES_LIST_TAG) }\n    private val controller by lazy { ImagesController(false) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        val binding = ListActivityBinding.inflate(layoutInflater)\n        setContentView(binding.root)\n\n        binding.recyclerView.apply {\n            setController(controller)\n            setHasFixedSize(true)\n        }\n\n        controller.setFilterDuplicates(true)\n        controller.setData(images)\n    }\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/java/com/airbnb/epoxy/preloadersample/PreloadActivity.kt",
    "content": "package com.airbnb.epoxy.preloadersample\n\nimport android.graphics.Bitmap\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.addGlidePreloader\nimport com.airbnb.epoxy.glidePreloader\nimport com.airbnb.epoxy.preloadersample.databinding.ListActivityBinding\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.RequestBuilder\nimport com.bumptech.glide.RequestManager\nimport com.bumptech.glide.load.engine.DiskCacheStrategy\nimport com.bumptech.glide.request.RequestOptions\nimport com.bumptech.glide.signature.ObjectKey\n\nclass PreloadActivity : AppCompatActivity() {\n\n    private val images by lazy { intent.getStringArrayExtra(MainActivity.IMAGES_LIST_TAG) }\n    private val controller by lazy { ImagesController(true) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        val binding = ListActivityBinding.inflate(layoutInflater)\n        setContentView(binding.root)\n\n        val recyclerView = binding.recyclerView\n        recyclerView.setHasFixedSize(true)\n        recyclerView.setController(controller)\n\n        controller.setFilterDuplicates(true)\n        controller.setData(images)\n\n        recyclerView.addGlidePreloader(\n            Glide.with(this),\n            preloader = glidePreloader { requestManager, model: ImageModel_, _ ->\n                requestManager.loadImage(model.imageUrl, true)\n            }\n        )\n    }\n}\n\nfun RequestManager.loadImage(url: String, isPreloading: Boolean): RequestBuilder<Bitmap> {\n\n    val options = RequestOptions\n        .diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC)\n        .dontAnimate()\n        .signature(ObjectKey(url.plus(if (isPreloading) \"_preloading\" else \"_not_preloading\")))\n\n    return asBitmap()\n        .apply(options)\n        .load(url)\n}\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"108.0\"\n    android:viewportWidth=\"108.0\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#66FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:id=\"@+id/main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n    <Button android:id=\"@+id/button_no_preload\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"16dp\"\n            android:text=\"@string/without_preload\" />\n\n    <Button android:id=\"@+id/button_preload\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"16dp\"\n            android:text=\"@string/with_preload\" />\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/layout/list_activity.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.EpoxyRecyclerView android:id=\"@+id/recycler_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"/>"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/layout/list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/image_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"200dp\"\n            android:scaleType=\"centerCrop\" />\n\n        <TextView\n            android:id=\"@+id/text_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"16dp\"\n            android:textSize=\"18sp\"\n            tools:text=\"test\" />\n\n    </LinearLayout>\n\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">epoxy-preloadersample</string>\n\n    <string name=\"with_preload\">With Preload</string>\n    <string name=\"without_preload\">Without Preload</string>\n</resources>\n"
  },
  {
    "path": "epoxy-preloadersample/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "epoxy-processor/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-processor/build.gradle",
    "content": "apply plugin: 'org.jetbrains.kotlin.jvm'\napply plugin: 'org.jetbrains.kotlin.kapt'\napply from: '../publishing.gradle'\n\nconfigurations.all { strategy ->\n    strategy.resolutionStrategy.force rootProject.deps.assertj, rootProject.deps.googleTestingCompile\n}\n\ndependencies {\n    implementation deps.squareJavaPoet\n    implementation deps.squareKotlinPoet\n    implementation deps.kotlinPoetJavaInterop\n    implementation deps.kotlinPoetKspInterop\n    implementation deps.androidAnnotations\n    implementation rootProject.deps.kotlinxMetadata\n    implementation rootProject.deps.kotlinCoroutines\n    implementation rootProject.deps.ksp\n    implementation rootProject.deps.kspAaEmbeddable\n\n    // we shouldn't be including this technically, as it can cause issues with backwards compatibility,\n    // but we use it for custom parsing of kotlin files to do resource scanning :(\n    implementation rootProject.deps.kspImpl\n\n    // Compiler needed to resolve resource references in annotations\n    implementation \"org.jetbrains.kotlin:kotlin-compiler-embeddable:$KOTLIN_VERSION\"\n    // This is included in kotlinCompileTesting, but the version can be out of date with our kotlin\n    // compiler version, so we include it to force the right version\n    testImplementation rootProject.deps.kotlinAnnotationProcessingEmbeddable\n    implementation rootProject.deps.xProcessing\n\n    testImplementation rootProject.deps.xProcessingTesting\n    testImplementation \"io.strikt:strikt-core:0.34.1\"\n\n    /** Provides the sun javac tools for looking up the R class trees. */\n    compileOnly files(rootProject.file(\"libs/rt.jar\"))\n    compileOnly files(rootProject.file(\"libs/tools.jar\"))\n    // Allow us to use android support library annotations (@LayoutRes) in this project.\n    // Since this isn't an android module normally we couldn't access them otherwise.\n    compileOnly rootProject.deps.androidRuntime\n\n    implementation project(':epoxy-annotations')\n    compileOnly deps.incapRuntime\n    kapt deps.incapProcessor\n\n    testImplementation rootProject.deps.junit\n}\n\nkotlin {\n    jvmToolchain(11)\n}\n\ntasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {\n    compilerOptions {\n        jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)\n        optIn.addAll(\n            \"kotlin.RequiresOptIn\",\n            \"kotlin.contracts.ExperimentalContracts\",\n            \"androidx.room.compiler.processing.ExperimentalProcessingApi\",\n            \"com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview\",\n            \"com.squareup.kotlinpoet.ksp.KotlinPoetKspPreview\"\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/gradle.properties",
    "content": "POM_NAME=Epoxy annotation processor\nPOM_ARTIFACT_ID=epoxy-processor\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Asyncable.kt",
    "content": "package com.airbnb.epoxy.processor\n\ninterface Asyncable {\n    val logger: Logger\n\n    fun <T, R : Any> Iterable<T>.mapNotNull(\n        tag: String,\n        parallel: Boolean = true,\n        transform: (T) -> R?\n    ): List<R> {\n        return logger.measure(tag, numItems = count()) {\n            this@mapNotNull.mapNotNull {\n                try {\n                    transform(it)\n                } catch (e: Exception) {\n                    logger.logError(e, \"$tag failed\")\n                    null\n                }\n            }\n        }\n    }\n\n    fun <T> Iterable<T>.forEach(\n        tag: String,\n        parallel: Boolean = true,\n        block: (T) -> Unit\n    ) {\n        logger.measure(tag, numItems = count()) {\n            forEach {\n                try {\n                    block(it)\n                } catch (e: Exception) {\n                    logger.logError(e, \"$tag failed\")\n                }\n            }\n        }\n    }\n\n    fun <T : Any> Iterable<T>.filter(\n        tag: String,\n        parallel: Boolean = true,\n        block: (T) -> Boolean\n    ): List<T> {\n        return logger.measure(tag, numItems = count()) {\n            filter {\n                try {\n                    block(it)\n                } catch (e: Exception) {\n                    logger.logError(e, \"$tag failed\")\n                    false\n                }\n            }\n        }\n    }\n\n    fun <K, V> Map<K, V>.forEach(\n        tag: String,\n        parallel: Boolean = true,\n        block: (K, V) -> Any?\n    ) {\n        logger.measure(tag, numItems = size) {\n            forEach {\n                try {\n                    block(it.key, it.value)\n                } catch (e: Exception) {\n                    logger.logError(e, \"$tag failed\")\n                }\n            }\n        }\n    }\n\n    fun <K, V, R : Any> Map<K, V>.mapNotNull(\n        tag: String,\n        parallel: Boolean = true,\n        transform: (K, V) -> R?\n    ): List<R> {\n        return logger.measure(tag, numItems = count()) {\n            this@mapNotNull.mapNotNull {\n                try {\n                    transform(it.key, it.value)\n                } catch (e: Exception) {\n                    logger.logError(e, \"$tag failed\")\n                    null\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/AttributeInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XType\nimport com.airbnb.epoxy.processor.Type.TypeEnum\nimport com.squareup.javapoet.AnnotationSpec\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.TypeName\n\nabstract class AttributeInfo(val memoizer: Memoizer) : Comparable<AttributeInfo> {\n\n    lateinit var fieldName: String\n        protected set\n\n    lateinit var type: Type\n        private set\n\n    lateinit var xType: XType\n        private set\n\n    protected fun setXType(xType: XType, memoizer: Memoizer) {\n        this.xType = xType\n        type = memoizer.getType(xType)\n    }\n\n    lateinit var rootClass: String\n        protected set\n    var packageName: String? = null\n        protected set\n    var useInHash: Boolean = false\n        protected set\n    var ignoreRequireHashCode: Boolean = false\n        protected set\n    var doNotUseInToString: Boolean = false\n        protected set\n        get() {\n            if (field) {\n                return true\n            }\n\n            // Do not include Kotlin lambdas in toString because there is a bug where they sometimes\n            // crash.\n            // see https://github.com/airbnb/epoxy/issues/455\n            // Avoid type lookup as it is expensive in KSP, so just check for the functions package.\n            return \"kotlin.jvm.functions\" in typeName.toString()\n        }\n\n    var generateSetter: Boolean = false\n        protected set\n    var setterAnnotations: MutableList<AnnotationSpec> = mutableListOf()\n        protected set\n    var generateGetter: Boolean = false\n        protected set\n    var getterAnnotations: MutableList<AnnotationSpec> = mutableListOf()\n        protected set\n    var hasFinalModifier: Boolean = false\n        protected set\n    var isPackagePrivate: Boolean = false\n        protected set\n    var javaDoc: CodeBlock? = null\n        protected set\n\n    /** If this attribute is in an attribute group this is the name of the group.  */\n    var groupKey: String? = null\n\n    /**\n     * Track whether there is a setter method for this attribute on a super class so that we can\n     * call through to super.\n     */\n    var hasSuperSetter: Boolean = false\n\n    // for private fields (Kotlin case)\n    var isPrivate: Boolean = false\n    protected var getterMethodName: String? = null\n\n    protected var setterMethodName: String? = null\n\n    /**\n     * True if this attribute is completely generated as a field on the generated model. False if it\n     * exists as a user defined attribute in a model super class.\n     */\n    var isGenerated: Boolean = false\n        protected set\n\n    /** If [.isGenerated] is true, a default value for the field can be set here.  */\n    val codeToSetDefault = DefaultValue()\n\n    /**\n     * If [isGenerated] is true, this represents whether null is a valid value to set on the\n     * attribute. If this is true, then the [codeToSetDefault] should be null unless a\n     * different default value is explicitly set.\n     *\n     *\n     * This is Boolean to have null represent that nullability was not explicitly set, eg for\n     * primitives or legacy attributes that weren't made with nullability support in mind.\n     */\n    var isNullable: Boolean? = null\n        protected set(value) {\n            check(!isPrimitive) {\n                \"Primitives cannot be nullable\"\n            }\n            field = value\n        }\n\n    val isPrimitive: Boolean\n        get() = typeName.isPrimitive\n\n    open val isRequired: Boolean\n        get() = isGenerated && codeToSetDefault.isEmpty\n\n    val typeName: TypeName get() = type.typeName\n\n    val isViewClickListener: Boolean get() = type.typeEnum == TypeEnum.ViewClickListener\n\n    val isViewLongClickListener: Boolean get() = type.typeEnum == TypeEnum.ViewLongClickListener\n\n    val isViewCheckedChangeListener: Boolean get() = type.typeEnum == TypeEnum.ViewCheckedChangeListener\n\n    val isBoolean: Boolean get() = type.typeEnum == TypeEnum.Boolean\n\n    val isCharSequenceOrString: Boolean get() = type.typeEnum == TypeEnum.StringOrCharSequence\n\n    val isStringList: Boolean\n        get() = type.typeEnum == TypeEnum.StringList\n\n    val isEpoxyModelList: Boolean\n        get() = type.typeEnum == TypeEnum.EpoxyModelList\n\n    val isInt: Boolean\n        get() = type.typeEnum == TypeEnum.Int\n\n    val isLong: Boolean\n        get() = type.typeEnum == TypeEnum.Long\n\n    val isStringAttributeData: Boolean\n        get() = type.typeEnum == TypeEnum.StringAttributeData\n\n    val isDouble: Boolean get() = type.typeEnum == TypeEnum.Double\n\n    val isDrawableRes: Boolean get() = isInt && hasAnnotation(\"DrawableRes\")\n\n    val isRawRes: Boolean get() = isInt && hasAnnotation(\"RawRes\")\n\n    private fun hasAnnotation(annotationSimpleName: String): Boolean {\n        return setterAnnotations\n            .map { it.type }\n            .filterIsInstance<ClassName>()\n            .any { it.simpleName() == annotationSimpleName }\n    }\n\n    class DefaultValue {\n        /** An explicitly defined default via the default param in the prop annotation.  */\n        var explicit: CodeBlock? = null\n\n        /**\n         * An implicitly assumed default, either via an @Nullable annotation or a primitive's default\n         * value. This is overridden if an explicit value is set.\n         */\n        var implicit: CodeBlock? = null\n\n        val isPresent: Boolean\n            get() = explicit != null || implicit != null\n\n        val isEmpty: Boolean\n            get() = !isPresent\n\n        fun value(): CodeBlock? = explicit ?: implicit\n    }\n\n    protected fun setJavaDocString(docComment: String?) {\n        javaDoc = docComment?.trim()\n            ?.let { if (it.isNotEmpty()) CodeBlock.of(it) else null }\n    }\n\n    fun isNullable(): Boolean {\n        if (!hasSetNullability()) {\n            throw IllegalStateException(\"Nullability has not been set\")\n        }\n\n        return isNullable == true\n    }\n\n    fun hasSetNullability(): Boolean = isNullable != null\n\n    fun getterCode(): String = if (isPrivate) getterMethodName!! + \"()\" else fieldName\n\n    // Special case to avoid generating recursive getter if field and its getter names are the same\n    fun superGetterCode(): String =\n        if (isPrivate) String.format(\"super.%s()\", getterMethodName) else fieldName\n\n    fun setterCode(): String =\n        (if (isGenerated) \"this.\" else \"super.\") +\n            if (isPrivate)\n                setterMethodName!! + \"(\\$L)\"\n            else\n                \"$fieldName = \\$L\"\n\n    open fun generatedSetterName(): String = fieldName\n\n    open fun generatedGetterName(isOverload: Boolean): String = fieldName\n\n    override fun toString(): String {\n        return (\n            \"Attribute {\" +\n                \"model='\" + rootClass + '\\''.toString() +\n                \", name='\" + fieldName + '\\''.toString() +\n                \", type=\" + typeName +\n                '}'.toString()\n            )\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) {\n            return true\n        }\n        if (other !is AttributeInfo) {\n            return false\n        }\n\n        val that = other as AttributeInfo?\n\n        return if (fieldName != that!!.fieldName) {\n            false\n        } else typeName == that.typeName\n    }\n\n    override fun hashCode(): Int {\n        var result = fieldName.hashCode()\n        result = 31 * result + typeName.hashCode()\n        return result\n    }\n\n    override fun compareTo(other: AttributeInfo): Int {\n        // sort attributes alphabetically for consistent code generation when attributes\n        // are added concurrently.\n        return fieldName.compareTo(other.fieldName)\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/BaseModelAttributeInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XAnnotation\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XNullability\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.processor.Utils.capitalizeFirstLetter\nimport com.airbnb.epoxy.processor.Utils.isFieldPackagePrivate\nimport com.airbnb.epoxy.processor.Utils.startsWithIs\nimport com.google.devtools.ksp.symbol.Origin\nimport com.squareup.javapoet.ClassName\nimport java.lang.annotation.ElementType\nimport java.lang.annotation.Target\n\ninternal class BaseModelAttributeInfo(\n    attribute: XFieldElement,\n    logger: Logger,\n    memoizer: Memoizer\n) : AttributeInfo(memoizer) {\n\n    private val classElement: XTypeElement = attribute.enclosingElement as XTypeElement\n\n    init {\n        fieldName = attribute.name\n        setXType(attribute.type, memoizer)\n        setJavaDocString(attribute.docComment)\n        rootClass = classElement.name\n        packageName = classElement.packageName\n        hasSuperSetter = classElement.hasSuperMethod(attribute)\n\n        hasFinalModifier = if (memoizer.environment.backend == XProcessingEnv.Backend.KSP) {\n            // Kotlin properties don't have a \"final\" modifier like Java, and the final modifier\n            // is incorrectly reported as true from java classpath classes,\n            // even when they are mutable. so we check it like this.\n            val declaration = attribute.declaration\n            if (declaration.origin == Origin.JAVA) {\n                attribute.isFinal()\n            } else {\n                !declaration.isMutable\n            }\n        } else {\n            attribute.isFinal()\n        }\n\n        isPackagePrivate = isFieldPackagePrivate(attribute)\n        val xAnnotation = attribute.requireAnnotation(EpoxyAttribute::class)\n        val options: Set<EpoxyAttribute.Option> = xAnnotation.getAsEnumList(\"value\")\n            .map { EpoxyAttribute.Option.valueOf(it.name) }.toSet()\n        val hash = xAnnotation.getAsBoolean(\"hash\")\n        val setter = xAnnotation.getAsBoolean(\"setter\")\n        validateAnnotationOptions(logger, hash, setter, options)\n        useInHash = hash && !options.contains(EpoxyAttribute.Option.DoNotHash)\n        ignoreRequireHashCode = options.contains(EpoxyAttribute.Option.IgnoreRequireHashCode)\n        doNotUseInToString = options.contains(EpoxyAttribute.Option.DoNotUseInToString)\n        generateSetter = setter && !options.contains(EpoxyAttribute.Option.NoSetter)\n        generateGetter = !options.contains(EpoxyAttribute.Option.NoGetter)\n        isPrivate = attribute.isPrivate()\n        if (isPrivate) {\n            findGetterAndSetterForPrivateField(logger)\n        }\n        buildAnnotationLists(attribute, attribute.getAllAnnotations())\n    }\n\n    /**\n     * Check if the given class or any of its super classes have a super method with the given name.\n     * Private methods are ignored since the generated subclass can't call super on those.\n     */\n    private fun XTypeElement.hasSuperMethod(attribute: XFieldElement): Boolean {\n        if (!type.isEpoxyModel(memoizer)) {\n            return false\n        }\n        val hasImplementation = getDeclaredMethods().any { method ->\n            !method.isPrivate() &&\n                method.name == attribute.name &&\n                method.parameters.singleOrNull()?.type == attribute.type\n        }\n\n        return hasImplementation || superClass?.typeElement?.hasSuperMethod(attribute) == true\n    }\n\n    private fun validateAnnotationOptions(\n        logger: Logger,\n        hash: Boolean,\n        setter: Boolean,\n        options: Set<EpoxyAttribute.Option>\n    ) {\n        if (options.contains(EpoxyAttribute.Option.IgnoreRequireHashCode) && options.contains(\n                EpoxyAttribute.Option.DoNotHash\n            )\n        ) {\n            logger.logError(\n                \"Illegal to use both %s and %s options in an %s annotation. (%s#%s)\",\n                EpoxyAttribute.Option.DoNotHash,\n                EpoxyAttribute.Option.IgnoreRequireHashCode,\n                EpoxyAttribute::class.java.simpleName,\n                classElement.name,\n                fieldName\n            )\n        }\n\n        // Don't let legacy values be mixed with the new Options values\n        if (options.isNotEmpty()) {\n            if (!hash) {\n                logger.logError(\n                    \"Don't use hash=false in an %s if you are using options. Instead, use the\" +\n                        \" %s option. (%s#%s)\",\n                    EpoxyAttribute::class.java.simpleName,\n                    EpoxyAttribute.Option.DoNotHash,\n                    classElement.name,\n                    fieldName\n                )\n            }\n            if (!setter) {\n                logger.logError(\n                    \"Don't use setter=false in an %s if you are using options. Instead, use the\" +\n                        \" %s option. (%s#%s)\",\n                    EpoxyAttribute::class.java.simpleName,\n                    EpoxyAttribute.Option.NoSetter,\n                    classElement.name,\n                    fieldName\n                )\n            }\n        }\n    }\n\n    /**\n     * Checks if the given private field has getter and setter for access to it\n     */\n    private fun findGetterAndSetterForPrivateField(logger: Logger) {\n        classElement.getDeclaredMethods().forEach { method ->\n            val methodName = method.name\n            val parameters = method.parameters\n\n            // check if it is a valid getter\n            if ((\n                methodName == String.format(\n                        \"get%s\",\n                        capitalizeFirstLetter(fieldName)\n                    ) || methodName == String.format(\n                        \"is%s\",\n                        capitalizeFirstLetter(fieldName)\n                    ) || methodName == fieldName && startsWithIs(fieldName)\n                ) &&\n                !method.isPrivate() &&\n                !method.isStatic() &&\n                parameters.isEmpty()\n            ) {\n                getterMethodName = methodName\n            }\n            // check if it is a valid setter\n            if ((\n                methodName == String.format(\n                        \"set%s\",\n                        capitalizeFirstLetter(fieldName)\n                    ) || startsWithIs(fieldName) && methodName == String.format(\n                        \"set%s\",\n                        fieldName.substring(2, fieldName.length)\n                    )\n                ) &&\n                !method.isPrivate() &&\n                !method.isStatic() &&\n                parameters.size == 1\n            ) {\n                setterMethodName = methodName\n            }\n        }\n        if (getterMethodName == null || setterMethodName == null) {\n            // We disable the \"private\" field setting so that we can still generate\n            // some code that compiles in an ok manner (ie via direct field access)\n            isPrivate = false\n            logger\n                .logError(\n                    \"%s annotations must not be on private fields\" +\n                        \" without proper getter and setter methods. (class: %s, field: %s)\",\n                    EpoxyAttribute::class.java.simpleName,\n                    classElement.name,\n                    fieldName\n                )\n        }\n    }\n\n    /**\n     * Keeps track of annotations on the attribute so that they can be used in the generated setter\n     * and getter method. Setter and getter annotations are stored separately since the annotation may\n     * not target both method and parameter types.\n     */\n    private fun buildAnnotationLists(attribute: XFieldElement, annotations: List<XAnnotation>) {\n        for (annotation in annotations) {\n            if (annotation.annotationValues.isNotEmpty()) {\n                // Not supporting annotations with values for now\n                continue\n            }\n            if (annotation.type.isTypeOf(EpoxyAttribute::class)) {\n                // Don't include our own annotation\n                continue\n            }\n            val annotationType = annotation.type\n            // A target may exist on an annotation type to specify where the annotation can\n            // be used, for example fields, methods, or parameters.\n            val targetAnnotation = annotationType.typeElement?.getAnnotation(Target::class)\n\n            // Allow all target types if no target was specified on the annotation\n            val elementTypes = targetAnnotation?.getAsEnumList(\"value\")\n                ?.map { ElementType.valueOf(it.name) }\n                ?.toTypedArray() ?: ElementType.entries.toTypedArray()\n            val annotationSpec = annotation.toAnnotationSpec(memoizer)\n            if (elementTypes.contains(ElementType.PARAMETER)) {\n                setterAnnotations.add(annotationSpec)\n            }\n            if (elementTypes.contains(ElementType.METHOD)) {\n                getterAnnotations.add(annotationSpec)\n            }\n        }\n\n        // When KAPT processes kotlin sources it sees java intermediary, which has automatically\n        // generated nullability annotations which we inherit. However, with\n        // KSP we see the kotlin code directly so we don't get those annotations by default\n        // and we lose nullability info, so we add it manually in that case.\n        if (memoizer.environment.backend == XProcessingEnv.Backend.KSP && attribute.declaration.isKotlinOrigin()) {\n            if (!attribute.type.typeName.isPrimitive) {\n\n                // Look at just simple name of annotation as there are many packages providing them (eg androidx, jetbrains)\n                val annotationSimpleNames = setterAnnotations.map { annotation ->\n                    when (val type = annotation.type) {\n                        is ClassName -> type.simpleName()\n                        else -> annotation.toString().substringAfterLast(\".\")\n                    }\n                }\n\n                if (attribute.type.nullability == XNullability.NULLABLE) {\n                    if (annotationSimpleNames.none { it == \"Nullable\" }) {\n                        setterAnnotations.add(NULLABLE_ANNOTATION_SPEC)\n                        getterAnnotations.add(NULLABLE_ANNOTATION_SPEC)\n                    }\n                } else if (attribute.type.nullability == XNullability.NONNULL) {\n                    if (annotationSimpleNames.none { it == \"NotNull\" || it == \"NonNull\" }) {\n                        setterAnnotations.add(NON_NULL_ANNOTATION_SPEC)\n                        getterAnnotations.add(NON_NULL_ANNOTATION_SPEC)\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/BaseProcessor.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XFiler\nimport androidx.room.compiler.processing.XMessager\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_RESET\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_LOG_TIMINGS\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_REQUIRE_HASHCODE\nimport com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_VALIDATE_MODEL_USAGE\nimport com.airbnb.epoxy.processor.resourcescanning.JavacResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.KspResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.getFieldWithReflectionOrNull\nimport com.google.devtools.ksp.processing.Resolver\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.symbol.KSAnnotated\nimport javax.annotation.processing.AbstractProcessor\nimport javax.annotation.processing.ProcessingEnvironment\nimport javax.annotation.processing.RoundEnvironment\nimport javax.lang.model.SourceVersion\nimport javax.lang.model.element.TypeElement\nimport javax.tools.Diagnostic\nimport kotlin.reflect.KClass\n\nabstract class BaseProcessor(val kspEnvironment: SymbolProcessorEnvironment? = null) :\n    AbstractProcessor(),\n    Asyncable,\n    SymbolProcessor {\n\n    val processorName = this@BaseProcessor::class.java.simpleName\n\n    lateinit var environment: XProcessingEnv\n        private set\n\n    val messager: XMessager\n        get() = environment.messager\n\n    val filer: XFiler\n        get() = environment.filer\n\n    private lateinit var options: Map<String, String>\n\n    private var roundNumber = 1\n    fun isKsp(): Boolean = kspEnvironment != null\n\n    init {\n        if (kspEnvironment != null) {\n            options = kspEnvironment.options\n            initOptions(kspEnvironment.options)\n        }\n    }\n\n    val configManager: ConfigManager by lazy {\n        ConfigManager(options, environment)\n    }\n    val resourceProcessor: ResourceScanner by lazy {\n        if (kspEnvironment != null) {\n            KspResourceScanner(environmentProvider = { environment })\n        } else {\n            JavacResourceScanner(\n                processingEnv = processingEnv,\n                environmentProvider = { environment }\n            )\n        }\n    }\n\n    /**\n     * Unified place to handle any compiler processor options that are passed to either javac processor or KSP processor,\n     * before any rounds are processed.\n     */\n    open fun initOptions(options: Map<String, String>) {}\n\n    val dataBindingModuleLookup by lazy {\n        DataBindingModuleLookup(\n            environment,\n            logger,\n            resourceProcessor\n        )\n    }\n\n    fun createModelWriter(memoizer: Memoizer): GeneratedModelWriter {\n        return GeneratedModelWriter(\n            filer,\n            environment,\n            logger,\n            resourceProcessor,\n            configManager,\n            dataBindingModuleLookup,\n            this,\n            memoizer\n        )\n    }\n\n    private val kotlinExtensionWriter: KotlinModelBuilderExtensionWriter by lazy {\n        KotlinModelBuilderExtensionWriter(filer, this)\n    }\n\n    override val logger by lazy { Logger(messager, configManager.logTimings) }\n\n    val generatedModels: MutableList<GeneratedModelInfo> = mutableListOf()\n\n    override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported()\n\n    override fun getSupportedAnnotationTypes(): Set<String> =\n        supportedAnnotations().map { it.java.canonicalName }.toSet()\n\n    abstract fun supportedAnnotations(): List<KClass<*>>\n\n    override fun getSupportedOptions(): Set<String> = setOf(\n        PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS,\n        PROCESSOR_OPTION_VALIDATE_MODEL_USAGE,\n        PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS,\n        PROCESSOR_OPTION_REQUIRE_HASHCODE,\n        PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION,\n        PROCESSOR_OPTION_LOG_TIMINGS,\n        PROCESSOR_OPTION_DISABLE_GENERATE_RESET,\n        PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS,\n        PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS\n    )\n\n    override fun init(processingEnv: ProcessingEnvironment) {\n        super.init(processingEnv)\n\n        environment = XProcessingEnv.create(processingEnv)\n        options = processingEnv.options\n        initOptions(processingEnv.options)\n    }\n\n    final override fun process(\n        resolver: Resolver\n    ): List<KSAnnotated> {\n        val roundNumber = roundNumber++\n        val timer = Timer(\"$processorName round $roundNumber\")\n        timer.start()\n\n        val kspEnvironment = requireNotNull(kspEnvironment)\n        environment = XProcessingEnv.create(\n            kspEnvironment,\n            resolver,\n        )\n        return processRoundInternal(\n            environment,\n            XRoundEnv.create(environment),\n            timer,\n            roundNumber\n        )\n            .mapNotNull { xElement ->\n                xElement.run {\n                    // All xprocessing implementations are internal so we need to use reflection :(\n                    // KspElement class uses the \"declaration property for its original element.\n                    getFieldWithReflectionOrNull<KSAnnotated>(\"declaration\")\n                } ?: run {\n                    messager.printMessage(\n                        Diagnostic.Kind.WARNING,\n                        \"Unable to get symbol for deferred element $xElement\"\n                    )\n                    null\n                }\n            }.also {\n                if (configManager.logTimings) {\n                    timer.finishAndPrint(messager)\n                }\n            }\n    }\n\n    final override fun process(\n        annotations: Set<TypeElement?>,\n        roundEnv: RoundEnvironment\n    ): Boolean {\n        val roundNumber = roundNumber++\n        val timer = Timer(\"$processorName round $roundNumber\")\n        timer.start()\n\n        processRoundInternal(\n            environment,\n            XRoundEnv.create(environment, roundEnv),\n            timer,\n            roundNumber\n        )\n\n        if (roundEnv.processingOver()) {\n            finish()\n            timer.markStepCompleted(\"finish\")\n        }\n\n        if (configManager.logTimings) {\n            timer.finishAndPrint(messager)\n        }\n\n        // Let any other annotation processors use our annotations if they want to\n        return false\n    }\n\n    final override fun finish() {\n        // We wait until the very end to log errors so that all the generated classes are still\n        // created.\n        // Otherwise the compiler error output is clogged with lots of errors from the generated\n        // classes  not existing, which makes it hard to see the actual errors.\n        logger.writeExceptions()\n    }\n\n    private fun processRoundInternal(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        // Memoizer should not be used across rounds because KSP symbols are not valid\n        // for reuse.\n        val memoizer = Memoizer(environment, logger)\n\n        // Clear resource scanner caches to avoid holding stale KSP element references.\n        // In KSP2, accessing elements from previous rounds triggers \"PSI has changed since creation\" errors.\n        resourceProcessor.clearCachesForNewRound()\n\n        val deferredElements: List<XElement> = try {\n            tryOrPrintError<List<XElement>?> {\n                timer.markStepCompleted(\"round initialization\")\n                processRound(environment, round, memoizer, timer, roundNumber)\n            } ?: emptyList()\n        } catch (e: Exception) {\n            logger.logError(e)\n            emptyList()\n        }\n\n        // Validate items after, so if any fail we've generated as much of the models\n        // as possible to avoid weird errors.\n        // Note that we have to be VERY careful referencing symbols across rounds\n        // as they types can rely on === checks and instances may not be the same,\n        // so behavior may break in strange ways.\n        // So we do this check now, instead of waiting for \"finish\", and then clear\n        // the models.\n        validateAttributesImplementHashCode(memoizer, generatedModels)\n        timer.markStepCompleted(\"validateAttributesImplementHashCode\")\n\n        if (!configManager.disableKotlinExtensionGeneration()) {\n            // TODO: Potentially generate a single file per model to allow for an isolating processor\n            kotlinExtensionWriter.generateExtensionsForModels(\n                generatedModels,\n                processorName,\n                memoizer\n            )\n            timer.markStepCompleted(\"generateKotlinExtensions\")\n        }\n\n        generatedModels.clear()\n\n        return deferredElements\n    }\n\n    private inline fun <T> tryOrPrintError(block: () -> T): T? {\n        @Suppress(\"Detekt.TooGenericExceptionCaught\")\n        return try {\n            block()\n        } catch (e: Throwable) {\n            // Errors thrown from within KSP can get lost, making the root cause of an issue hidden.\n            // This helps to surface all thrown errors.\n            messager.printMessage(Diagnostic.Kind.ERROR, e.stackTraceToString())\n            null\n        }\n    }\n\n    protected abstract fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        /**\n         * A memoizer to help cache types looked up in this round. Note that KSP must NOT use\n         * symbols across rounds, so this memoizer should only be used during this round.\n         */\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int,\n    ): List<XElement>\n\n    private fun validateAttributesImplementHashCode(\n        memoizer: Memoizer,\n        generatedClasses: Collection<GeneratedModelInfo>\n    ) {\n        if (generatedClasses.isEmpty()) return\n\n        val hashCodeValidator = HashCodeValidator(environment, memoizer, logger)\n\n        generatedClasses\n            .flatMap { it.attributeInfo }\n            .map { attributeInfo ->\n                if (configManager.requiresHashCode(attributeInfo) &&\n                    attributeInfo.useInHash &&\n                    !attributeInfo.ignoreRequireHashCode\n                ) {\n                    hashCodeValidator.validate(attributeInfo)\n                }\n            }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/BaseProcessorWithPackageConfigs.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport com.airbnb.epoxy.PackageEpoxyConfig\nimport com.airbnb.epoxy.PackageModelViewConfig\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport kotlin.reflect.KClass\n\nabstract class BaseProcessorWithPackageConfigs(kspEnvironment: SymbolProcessorEnvironment?) :\n    BaseProcessor(kspEnvironment) {\n\n    abstract val usesPackageEpoxyConfig: Boolean\n    abstract val usesModelViewConfig: Boolean\n\n    final override fun supportedAnnotations(): List<KClass<*>> = mutableListOf<KClass<*>>().apply {\n        if (usesPackageEpoxyConfig) {\n            add(PackageEpoxyConfig::class)\n        }\n        if (usesModelViewConfig) {\n            add(PackageModelViewConfig::class)\n        }\n    }.plus(additionalSupportedAnnotations())\n\n    abstract fun additionalSupportedAnnotations(): List<KClass<*>>\n\n    /**\n     * Returns all of the package config elements applicable to this processor.\n     */\n    fun originatingConfigElements(): List<XElement> = mutableListOf<XElement>().apply {\n        // TODO: Be more discerning about which config elements are returned here, eg\n        // only if they apply to a specific model or package. Perhaps support an isolated processor\n        // if a user knows they don't have any package config elements (ie the setting\n        // can be provided via an annotation processor option instead.)\n\n        if (usesPackageEpoxyConfig) {\n            addAll(configManager.packageEpoxyConfigElements)\n        }\n\n        if (usesModelViewConfig) {\n            addAll(configManager.packageModelViewConfigElements)\n        }\n    }\n\n    override fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        // We don't expect package configs to be generated, so they should all be picked up in\n        // the first round. This is because the configs greatly influence the settings of the generated\n        // models, and if models in the first round are created with different configs that models\n        // in later rounds (if more configs are picked up) then it would be confusing and potentially\n        // buggy.\n        // This also is a slight optimization to not do extra lookups.\n        if (roundNumber > 1) return emptyList()\n\n        if (usesPackageEpoxyConfig) {\n            val errors = configManager.processPackageEpoxyConfig(round)\n            logger.logErrors(errors)\n        }\n\n        if (usesModelViewConfig) {\n            val errors = configManager.processPackageModelViewConfig(round)\n            logger.logErrors(errors)\n        }\n\n        timer.markStepCompleted(\"process package configs\")\n\n        return emptyList()\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/BasicGeneratedModelInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.processor.Utils.getEpoxyObjectType\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeVariableName\n\ninternal class BasicGeneratedModelInfo(\n    superClassElement: XTypeElement,\n    logger: Logger,\n    memoizer: Memoizer\n) : GeneratedModelInfo(memoizer) {\n\n    val boundObjectTypeElement: XTypeElement?\n\n    init {\n        this.superClassName = superClassElement.type.typeNameWithWorkaround(memoizer)\n        this.superClassElement = superClassElement\n        generatedName = buildGeneratedModelName(superClassElement)\n\n        for (typeParam in superClassElement.type.typeArguments) {\n            val defaultTypeName = typeParam.typeNameWithWorkaround(memoizer)\n\n            if (defaultTypeName is TypeVariableName) {\n                typeVariableNames.add(defaultTypeName)\n            } else {\n                logger.logError(\n                    superClassElement,\n                    \"Unable to get type variable name for $superClassElement. Found $defaultTypeName\"\n                )\n            }\n        }\n\n        constructors.addAll(getClassConstructors(superClassElement))\n        collectMethodsReturningClassType(superClassElement)\n\n        if (typeVariableNames.isNotEmpty()) {\n            this.parameterizedGeneratedName = ParameterizedTypeName.get(\n                generatedName,\n                *typeVariableNames.toTypedArray()\n            )\n        } else {\n            this.parameterizedGeneratedName = generatedName\n        }\n\n        var boundObjectType = getEpoxyObjectType(superClassElement, memoizer)\n        if (boundObjectType == null) {\n            logger\n                .logError(\n                    \"Epoxy model type could not be found. (class: %s)\",\n                    superClassElement.name\n                )\n            // Return a basic view type so the code can be generated\n            boundObjectType = memoizer.androidViewType\n        }\n        modelType = boundObjectType.typeName\n        this.boundObjectTypeElement = boundObjectType.typeElement\n\n        val annotation = superClassElement.getAnnotation(EpoxyModelClass::class)\n\n        // By default we don't extend classes that are abstract; if they don't contain all required\n        // methods then our generated class won't compile. If there is a EpoxyModelClass annotation\n        // though we will always generate the subclass\n        shouldGenerateModel = annotation != null || !superClassElement.isAbstract()\n        includeOtherLayoutOptions = annotation?.getAsBoolean(\"useLayoutOverloads\") ?: false\n\n        annotations.addAll(\n            superClassElement.buildAnnotationSpecs({\n                it != memoizer.epoxyModelClassAnnotation\n            }, memoizer)\n        )\n    }\n\n    private fun buildGeneratedModelName(classElement: XTypeElement): ClassName {\n        val packageName = classElement.packageName\n\n        val packageLen = packageName.length + 1\n        val className = classElement.qualifiedName.substring(packageLen).replace(\n            '.',\n            '$'\n        )\n\n        return ClassName.get(\n            packageName,\n            className + GENERATED_CLASS_NAME_SUFFIX\n        )\n    }\n\n    override fun additionalOriginatingElements(currentMemoizer: Memoizer): List<XElement> = listOf(safeSuperClassElement(currentMemoizer))\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ClassNames.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ClassName.get\nimport com.squareup.kotlinpoet.javapoet.toJClassName\n\nobject ClassNames {\n\n    private const val PKG_EPOXY = \"com.airbnb.epoxy\"\n    private const val PKG_PARIS = \"com.airbnb.paris\"\n    private const val PKG_ANDROID = \"android\"\n    private const val PKG_ANDROID_CONTENT = \"android.content\"\n    private const val PKG_ANDROID_VIEW = \"android.view\"\n    private const val PKG_ANDROID_OS = \"android.os\"\n\n    @JvmField\n    val ANDROID_CONTEXT = get(PKG_ANDROID_CONTENT, \"Context\")!!\n\n    @JvmField\n    val ANDROID_VIEW = get(PKG_ANDROID_VIEW, \"View\")!!\n\n    @JvmField\n    val ANDROID_VIEW_GROUP = get(PKG_ANDROID_VIEW, \"ViewGroup\")!!\n\n    @JvmField\n    val ANDROID_ASYNC_TASK = get(PKG_ANDROID_OS, \"AsyncTask\")!!\n\n    @JvmField\n    val ANDROID_MARGIN_LAYOUT_PARAMS =\n        get(PKG_ANDROID_VIEW, \"ViewGroup\", \"MarginLayoutParams\")!!\n\n    @JvmField\n    val ANDROID_R = get(PKG_ANDROID, \"R\")!!\n\n    @JvmField\n    val EPOXY_MODEL_UNTYPED = get(PKG_EPOXY, \"EpoxyModel\")!!\n\n    val EPOXY_MODEL_WITH_HOLDER_UNTYPED = get(PKG_EPOXY, \"EpoxyModelWithHolder\")!!\n\n    // TODO: (eli_hart 9/8/17) Fix this package name\n    @JvmField\n    val EPOXY_R = get(\"com.airbnb.viewmodeladapter\", \"R\")!!\n\n    @JvmField\n    val EPOXY_DATA_BINDING_MODEL = get(PKG_EPOXY, \"DataBindingEpoxyModel\")!!\n\n    @JvmField\n    val EPOXY_DATA_BINDING_HOLDER =\n        get(PKG_EPOXY, \"DataBindingEpoxyModel\", \"DataBindingHolder\")!!\n\n    @JvmField\n    val EPOXY_STRING_ATTRIBUTE_DATA = get(PKG_EPOXY, \"StringAttributeData\")!!\n    val EPOXY_STRING_ATTRIBUTE_DATA_REFLECTION_NAME = EPOXY_STRING_ATTRIBUTE_DATA.reflectionName()\n\n    @JvmField\n    val EPOXY_CONTROLLER = get(PKG_EPOXY, \"EpoxyController\")!!\n\n    @JvmField\n    val MODEL_COLLECTOR = get(PKG_EPOXY, \"ModelCollector\")!!\n\n    @JvmField\n    val EPOXY_STYLE_BUILDER_CALLBACK = get(PKG_EPOXY, \"StyleBuilderCallback\")!!\n\n    @JvmField\n    val EPOXY_CONTROLLER_HELPER = get(PKG_EPOXY, \"ControllerHelper\")!!\n\n    @JvmField\n    val EPOXY_MODEL_PROPERTIES = get(PKG_EPOXY, \"ModelProperties\")!!\n\n    @JvmField\n    val PARIS_STYLE_UTILS = get(PKG_PARIS, \"StyleApplierUtils\", \"Companion\")!!\n\n    @JvmField\n    val PARIS_STYLE = get(\"$PKG_PARIS.styles\", \"Style\")!!\n\n    val EPOXY_VIEW_HOLDER = ClassName.bestGuess(Utils.EPOXY_VIEW_HOLDER_TYPE)\n\n    val EPOXY_GENERATED_MODEL_INTERFACE = ClassName.bestGuess(Utils.GENERATED_MODEL_INTERFACE)\n\n    val EPOXY_ON_BIND_MODEL_LISTENER = ClassName.bestGuess(Utils.ON_BIND_MODEL_LISTENER_TYPE)\n    val EPOXY_ON_UNBIND_MODEL_LISTENER = ClassName.bestGuess(Utils.ON_UNBIND_MODEL_LISTENER_TYPE)\n    val EPOXY_ON_VISIBILITY_STATE_MODEL_LISTENER =\n        ClassName.bestGuess(Utils.ON_VISIBILITY_STATE_MODEL_LISTENER_TYPE)\n    val EPOXY_ON_VISIBILITY_MODEL_LISTENER =\n        ClassName.bestGuess(Utils.ON_VISIBILITY_MODEL_LISTENER_TYPE)\n    val EPOXY_WRAPPED_CHECKED_LISTENER = ClassName.bestGuess(Utils.WRAPPED_CHECKED_LISTENER_TYPE)\n    val EPOXY_WRAPPED_LISTENER = ClassName.bestGuess(Utils.WRAPPED_LISTENER_TYPE)\n    val EPOXY_MODEL_CLICK_LISTENER = ClassName.bestGuess(Utils.MODEL_CLICK_LISTENER_TYPE)\n    val EPOXY_MODEL_LONG_CLICK_LISTENER = ClassName.bestGuess(Utils.MODEL_LONG_CLICK_LISTENER_TYPE)\n    val EPOXY_MODEL_CHECKED_CHANGE_LISTENER =\n        ClassName.bestGuess(Utils.MODEL_CHECKED_CHANGE_LISTENER_TYPE)\n\n    val VIEW_PARENT = get(\"android.view\", \"ViewParent\")\n    val KOTLIN_ANY = ClassName.get(\"kotlin\", \"Any\")\n    val ITERABLE = ClassName.get(\"java.lang\", \"Iterable\")\n    val LIST = ClassName.get(\"java.util\", \"List\")\n    val SET = ClassName.get(\"java.util\", \"Set\")\n    val COLLECTION = ClassName.get(\"java.util\", \"Collection\")\n    val UNIT = KClassNames.KOTLIN_UNIT.toJClassName()\n}\n\nconst val DEPRECATED = \"Deprecated\"\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ConfigManager.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.PackageEpoxyConfig\nimport com.airbnb.epoxy.PackageModelViewConfig\nimport com.airbnb.epoxy.processor.PackageConfigSettings.Companion.create\nimport com.airbnb.epoxy.processor.PackageConfigSettings.Companion.forDefaults\n\n/** Manages configuration settings for different packages.  */\nclass ConfigManager internal constructor(\n    options: Map<String, String>,\n    private val environment: XProcessingEnv,\n) {\n    val packageEpoxyConfigElements: MutableList<XElement> = mutableListOf()\n    val packageModelViewConfigElements: MutableList<XElement> = mutableListOf()\n    private val configurationMap: MutableMap<String, PackageConfigSettings> = mutableMapOf()\n    private val modelViewNamingMap: MutableMap<String, PackageModelViewSettings?> = mutableMapOf()\n    private val validateModelUsage: Boolean\n    private val globalRequireHashCode: Boolean\n    private val globalRequireAbstractModels: Boolean\n    private val globalImplicitlyAddAutoModels: Boolean\n    private val disableKotlinExtensionGeneration: Boolean\n    private val disableGenerateReset: Boolean\n    private val disableGenerateGetters: Boolean\n    private val disableGenerateBuilderOverloads: Boolean\n    val disableDslMarker: Boolean\n    val logTimings: Boolean\n\n    init {\n        validateModelUsage = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_VALIDATE_MODEL_USAGE,\n            defaultValue = true\n        )\n\n        globalRequireHashCode = getBooleanOption(\n            options, PROCESSOR_OPTION_REQUIRE_HASHCODE,\n            PackageEpoxyConfig.REQUIRE_HASHCODE_DEFAULT\n        )\n\n        globalRequireAbstractModels = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS,\n            PackageEpoxyConfig.REQUIRE_ABSTRACT_MODELS_DEFAULT\n        )\n\n        globalImplicitlyAddAutoModels = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS,\n            PackageEpoxyConfig.IMPLICITLY_ADD_AUTO_MODELS_DEFAULT\n        )\n\n        disableKotlinExtensionGeneration = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION,\n            defaultValue = false\n        )\n\n        logTimings = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_LOG_TIMINGS,\n            defaultValue = false\n        )\n\n        disableGenerateReset = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_DISABLE_GENERATE_RESET,\n            defaultValue = false\n        )\n\n        disableGenerateGetters = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS,\n            defaultValue = false\n        )\n\n        disableGenerateBuilderOverloads = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS,\n            defaultValue = false\n        )\n\n        disableDslMarker = getBooleanOption(\n            options,\n            PROCESSOR_OPTION_DISABLE_DLS_MARKER,\n            defaultValue = false\n        )\n    }\n\n    fun processPackageEpoxyConfig(roundEnv: XRoundEnv): List<Exception> {\n        val errors = mutableListOf<Exception>()\n\n        roundEnv.getElementsAnnotatedWith(PackageEpoxyConfig::class)\n            .filterIsInstance<XTypeElement>()\n            .forEach { element ->\n                packageEpoxyConfigElements.add(element)\n                val packageName = element.packageName\n                if (configurationMap.containsKey(packageName)) {\n                    errors.add(\n                        Utils.buildEpoxyException(\n                            \"Only one Epoxy configuration annotation is allowed per package (%s)\",\n                            packageName\n                        )\n                    )\n                    return@forEach\n                }\n                val annotation = element.getAnnotation(PackageEpoxyConfig::class)!!\n                configurationMap[packageName] = create(annotation)\n            }\n\n        return errors\n    }\n\n    fun processPackageModelViewConfig(roundEnv: XRoundEnv): List<Exception> {\n        val errors = mutableListOf<Exception>()\n\n        roundEnv.getElementsAnnotatedWith(PackageModelViewConfig::class)\n            .filterIsInstance<XTypeElement>()\n            .forEach { element ->\n                packageModelViewConfigElements.add(element)\n                val packageName = element.packageName\n                if (modelViewNamingMap.containsKey(packageName)) {\n                    errors.add(\n                        Utils.buildEpoxyException(\n                            \"Only one %s annotation is allowed per package (%s)\",\n                            PackageModelViewConfig::class.java.simpleName,\n                            packageName\n                        )\n                    )\n                    return@forEach\n                }\n                val annotation = element.requireAnnotation(PackageModelViewConfig::class)\n\n                val rClassName = annotation.getAsType(\"rClass\")?.typeElement\n                if (rClassName == null) {\n                    errors.add(\n                        Utils.buildEpoxyException(\n                            element,\n                            \"Unable to get R class details from annotation %s (package: %s)\",\n                            PackageModelViewConfig::class.java.simpleName,\n                            packageName\n                        )\n                    )\n                    return@forEach\n                }\n                val rLayoutClassString = rClassName.asClassName().toJavaPoet().reflectionName()\n                if (!rLayoutClassString.endsWith(\".R\") &&\n                    !rLayoutClassString.endsWith(\".R2\")\n                ) {\n                    errors.add(\n                        Utils.buildEpoxyException(\n                            element,\n                            \"Invalid R class in %s. Was '%s' (package: %s)\",\n                            PackageModelViewConfig::class.java.simpleName,\n                            rLayoutClassString,\n                            packageName\n                        )\n                    )\n                    return@forEach\n                }\n                modelViewNamingMap[packageName] = PackageModelViewSettings(rClassName, annotation)\n            }\n\n        return errors\n    }\n\n    fun requiresHashCode(attributeInfo: AttributeInfo): Boolean {\n        return if (attributeInfo is ViewAttributeInfo) {\n            // View props are forced to implement hash and equals since it is a safer pattern\n            true\n        } else {\n            globalRequireHashCode || attributeInfo.packageName?.let { packageName ->\n                getConfigurationForPackage(packageName).requireHashCode\n            } == true\n        }\n\n        // Legacy models can choose whether they want to require it\n    }\n\n    fun requiresAbstractModels(classElement: XTypeElement): Boolean {\n        return (\n            globalRequireAbstractModels ||\n                getConfigurationForElement(classElement).requireAbstractModels\n            )\n    }\n\n    fun implicitlyAddAutoModels(controller: ControllerClassInfo): Boolean {\n        return (\n            globalImplicitlyAddAutoModels ||\n                getConfigurationForPackage(controller.classPackage).implicitlyAddAutoModels\n            )\n    }\n\n    fun disableKotlinExtensionGeneration(): Boolean = disableKotlinExtensionGeneration\n\n    /**\n     * If true, Epoxy models added to an EpoxyController will be\n     * validated at run time to make sure they are properly used.\n     *\n     * By default this is true, and it is highly recommended to enable it to prevent accidental misuse\n     * of your models. However, you may want to disable this for production builds to avoid the\n     * overhead of the runtime validation code.\n     *\n     * Using a debug build flag is a great way to do this.\n     */\n    fun shouldValidateModelUsage(): Boolean = validateModelUsage\n\n    fun getModelViewConfig(modelViewInfo: ModelViewInfo?): PackageModelViewSettings? {\n        if (modelViewInfo == null) return null\n        return getModelViewConfig(modelViewInfo.viewElement)\n    }\n\n    fun getModelViewConfig(viewElement: XTypeElement): PackageModelViewSettings? {\n        val packageName = viewElement.packageName\n        return getObjectFromPackageMap(\n            modelViewNamingMap,\n            packageName,\n            ifNotFound = null\n        )\n    }\n\n    fun getDefaultBaseModel(viewElement: XTypeElement, currentEnvironment: XProcessingEnv): XType? {\n        val className = getModelViewConfig(viewElement)?.defaultBaseModelClassName\n            ?: return null\n        // Resolve the type fresh each round using the current environment to avoid\n        // accessing stale KSP elements from previous rounds.\n        // IMPORTANT: Use the currentEnvironment parameter, not the instance field,\n        // since the instance field was captured at ConfigManager creation time (round 1).\n        return currentEnvironment.findType(className)\n    }\n\n    fun includeAlternateLayoutsForViews(viewElement: XTypeElement): Boolean {\n        return getModelViewConfig(viewElement)?.includeAlternateLayouts ?: false\n    }\n\n    fun generatedModelSuffix(viewElement: XTypeElement): String {\n        return getModelViewConfig(viewElement)?.generatedModelSuffix\n            ?: GeneratedModelInfo.GENERATED_MODEL_SUFFIX\n    }\n\n    fun disableGenerateBuilderOverloads(modelInfo: GeneratedModelInfo): Boolean {\n        return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateBuilderOverloads\n            ?: disableGenerateBuilderOverloads\n    }\n\n    fun disableGenerateReset(modelInfo: GeneratedModelInfo): Boolean {\n        return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateReset\n            ?: disableGenerateReset\n    }\n\n    fun disableGenerateGetters(modelInfo: GeneratedModelInfo): Boolean {\n        return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateGetters\n            ?: disableGenerateGetters\n    }\n\n    private fun getConfigurationForElement(element: XTypeElement): PackageConfigSettings {\n        return getConfigurationForPackage(element.packageName)\n    }\n\n    fun getConfigurationForPackage(packageName: String): PackageConfigSettings {\n        return getObjectFromPackageMap(\n            configurationMap,\n            packageName,\n            DEFAULT_PACKAGE_CONFIG_SETTINGS\n        )!!\n    }\n\n    companion object {\n        const val PROCESSOR_OPTION_DISABLE_DLS_MARKER = \"epoxyDisableDslMarker\"\n        const val PROCESSOR_OPTION_DISABLE_GENERATE_RESET = \"epoxyDisableGenerateReset\"\n        const val PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS = \"epoxyDisableGenerateGetters\"\n        const val PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS =\n            \"epoxyDisableGenerateOverloads\"\n        const val PROCESSOR_OPTION_LOG_TIMINGS = \"logEpoxyTimings\"\n        const val PROCESSOR_OPTION_VALIDATE_MODEL_USAGE = \"validateEpoxyModelUsage\"\n        const val PROCESSOR_OPTION_REQUIRE_HASHCODE = \"requireHashCodeInEpoxyModels\"\n        const val PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS = \"requireAbstractEpoxyModels\"\n        const val PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS = \"implicitlyAddAutoModels\"\n        const val PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION =\n            \"disableEpoxyKotlinExtensionGeneration\"\n        private val DEFAULT_PACKAGE_CONFIG_SETTINGS = forDefaults()\n\n        private fun getBooleanOption(\n            options: Map<String, String>,\n            option: String,\n            defaultValue: Boolean\n        ): Boolean {\n            val value = options[option] ?: return defaultValue\n            return value.toBoolean()\n        }\n\n        private fun <T> getObjectFromPackageMap(\n            map: Map<String, T>,\n            packageName: String,\n            ifNotFound: T\n        ): T? {\n            if (map.containsKey(packageName)) {\n                return map[packageName]\n            }\n\n            // If there isn't a configuration for that exact package then we look for configurations for\n            // parent packages which include the target package. If multiple parent packages declare\n            // configurations we take the configuration from the more nested parent.\n            var matchValue: T? = null\n            var matchLength = 0\n            map.forEach { (entryPackage, value) ->\n                if (!packageName.startsWith(\"$entryPackage.\")) {\n                    return@forEach\n                }\n                if (matchLength < entryPackage.length) {\n                    matchLength = entryPackage.length\n                    matchValue = value\n                }\n            }\n\n            return matchValue ?: ifNotFound\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ControllerClassInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.TypeName\nimport java.util.HashSet\n\nprivate const val GENERATED_HELPER_CLASS_SUFFIX = \"_EpoxyHelper\"\n\nclass ControllerClassInfo(\n    // Not holding on to any symbols so that this can be stored across rounds\n    controllerClassElement: XTypeElement,\n    val resourceProcessor: ResourceScanner,\n    memoizer: Memoizer\n) {\n    // Exception to the rule of not reusing symbols across rounds - should be safe for originating\n    // elements since those just report the file information which should not change.\n    val originatingElement: XElement = controllerClassElement\n    val classPackage: String = controllerClassElement.packageName\n    val models: MutableSet<ControllerModelField> = HashSet()\n    val modelsImmutable: Set<ControllerModelField> get() = synchronized(models) { models.toSet() }\n\n    val generatedClassName: ClassName = getGeneratedClassName(controllerClassElement)\n    val controllerClassType: TypeName = controllerClassElement.type.typeNameWithWorkaround(memoizer)\n\n    val imports: List<String> by lazy {\n        resourceProcessor.getImports(controllerClassElement)\n    }\n\n    fun addModel(controllerModelField: ControllerModelField) = synchronized(models) {\n        models.add(controllerModelField)\n    }\n\n    fun addModels(controllerModelFields: Collection<ControllerModelField>) = synchronized(models) {\n        models.addAll(controllerModelFields)\n    }\n\n    private fun getGeneratedClassName(controllerClass: XTypeElement): ClassName {\n        val packageName = controllerClass.packageName\n\n        val packageLen = packageName.length + 1\n        val className =\n            controllerClass.qualifiedName.substring(packageLen).replace('.', '$')\n\n        return ClassName.get(packageName, \"$className$GENERATED_HELPER_CLASS_SUFFIX\")\n    }\n\n    override fun toString() =\n        \"ControllerClassInfo(models=$models, generatedClassName=$generatedClassName, \" +\n            \"controllerClassType=$controllerClassType)\"\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ControllerModelField.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.TypeName\n\ndata class ControllerModelField(\n    val fieldName: String,\n    var typeName: TypeName,\n    val packagePrivate: Boolean\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ControllerProcessor.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XFiler\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.addOriginatingElement\nimport androidx.room.compiler.processing.writeTo\nimport com.airbnb.epoxy.AutoModel\nimport com.airbnb.epoxy.processor.ClassNames.EPOXY_MODEL_UNTYPED\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.FieldSpec\nimport com.squareup.javapoet.JavaFile\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeSpec\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType\nimport java.util.ArrayList\nimport java.util.LinkedHashMap\nimport javax.lang.model.element.Modifier\nimport kotlin.reflect.KClass\n\nclass ControllerProcessorProvider : SymbolProcessorProvider {\n    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {\n        return ControllerProcessor(environment)\n    }\n}\n\n// TODO: This could be an isolating processor except that the PackageEpoxyConfig annotation\n// can change the `implicitlyAddAutoModels` setting.\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING)\nclass ControllerProcessor @JvmOverloads constructor(\n    kspEnvironment: SymbolProcessorEnvironment? = null\n) : BaseProcessorWithPackageConfigs(kspEnvironment) {\n    override val usesPackageEpoxyConfig: Boolean = true\n    override val usesModelViewConfig: Boolean = false\n\n    override fun additionalSupportedAnnotations(): List<KClass<*>> = listOf(\n        AutoModel::class\n    )\n\n    private val classNameToInfo = mutableMapOf<ClassName, ControllerClassInfo>()\n\n    override fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        super.processRound(environment, round, memoizer, timer, roundNumber)\n\n        // JavaAP and KAPT can correct error types and still figure out when the type is a generated\n        // model that doesn't exist yet. KSP needs to defer those symbols though, and only process\n        // them once the class is available.\n        val (validFields, invalidFields) = round.getElementsAnnotatedWith(AutoModel::class)\n            .filterIsInstance<XFieldElement>()\n            .partition { !isKsp() || it.validate() }\n\n        timer.markStepCompleted(\"get automodel fields\")\n\n        validFields.forEach { field ->\n            val classElement =\n                field.enclosingTypeElement ?: error(\"Field $field should be used inside a class\")\n            val targetClassInfo = getOrCreateTargetClass(classElement, memoizer)\n            try {\n                targetClassInfo.addModel(buildFieldInfo(targetClassInfo, field, memoizer))\n            } catch (e: Exception) {\n                logger.logError(e)\n            }\n        }\n\n        timer.markStepCompleted(\"parse field info\")\n\n        // Need to wait until all fields are valid until we can write files, because:\n        // 1. multiple fields in the same class are aggregated\n        // 2. across classes we need to handle inheritance\n        if (invalidFields.isEmpty()) {\n            try {\n                updateClassesForInheritance(environment, classNameToInfo)\n            } catch (e: Exception) {\n                logger.logError(e)\n            }\n            timer.markStepCompleted(\"lookup inheritance details\")\n\n            generateJava(classNameToInfo)\n            classNameToInfo.clear()\n            timer.markStepCompleted(\"write automodel helpers\")\n        }\n\n        return invalidFields\n    }\n\n    /**\n     * Check each controller for super classes that also have auto models. For each super class with\n     * auto model we add those models to the auto models of the generated class, so that a\n     * generated class contains all the models of its super classes combined.\n     *\n     * One caveat is that if a sub class is in a different package than its super class we can't\n     * include auto models that are package private, otherwise the generated class won't compile.\n     */\n    private fun updateClassesForInheritance(\n        environment: XProcessingEnv,\n        controllerClassMap: MutableMap<ClassName, ControllerClassInfo>\n    ) {\n        for ((thisClassName, thisClassInfo) in controllerClassMap) {\n            // Need to look up the types now instead of storing them because if we processed the\n            // fields across multiple rounds the stored types cannot be compared.\n            val thisClassType = environment.requireType(thisClassName.toString())\n            val otherClasses: MutableMap<ClassName, ControllerClassInfo> =\n                LinkedHashMap(controllerClassMap)\n\n            otherClasses.remove(thisClassName)\n            for ((otherClassName, otherClassInfo) in otherClasses) {\n                val otherClassType = environment.requireType(otherClassName.toString())\n                if (!thisClassType.isSubTypeOf(otherClassType)) {\n                    continue\n                }\n                val otherControllerModelFields: Set<ControllerModelField> =\n                    otherClassInfo.modelsImmutable\n                if (thisClassInfo.classPackage == thisClassInfo.classPackage) {\n                    thisClassInfo.addModels(otherControllerModelFields)\n                } else {\n                    for (controllerModelField in otherControllerModelFields) {\n                        if (!controllerModelField.packagePrivate) {\n                            thisClassInfo.addModel(controllerModelField)\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun getOrCreateTargetClass(\n        controllerClassElement: XTypeElement,\n        memoizer: Memoizer\n    ): ControllerClassInfo = classNameToInfo.getOrPut(\n        controllerClassElement.asClassName().toJavaPoet()\n    ) {\n        if (!controllerClassElement.isEpoxyController(memoizer)) {\n            logger.logError(\n                controllerClassElement,\n                \"Class with %s annotations must extend %s (%s)\",\n                AutoModel::class.java.simpleName,\n                Utils.EPOXY_CONTROLLER_TYPE,\n                controllerClassElement.name\n            )\n        }\n\n        ControllerClassInfo(controllerClassElement, resourceProcessor, memoizer)\n    }\n\n    private fun buildFieldInfo(\n        classElement: ControllerClassInfo,\n        modelFieldElement: XFieldElement,\n        memoizer: Memoizer\n    ): ControllerModelField {\n        Utils.validateFieldAccessibleViaGeneratedCode(\n            fieldElement = modelFieldElement,\n            annotationClass = AutoModel::class.java,\n            logger = logger,\n        )\n        val fieldName = modelFieldElement.name\n        val fieldType = modelFieldElement.type\n\n        val modelTypeName = if (!fieldType.isError()) {\n            // If the field is a generated Epoxy model then the class won't have been generated\n            // yet and it won't have type info. If the type can't be found that we assume it is\n            // a generated model and is ok.\n            if (!fieldType.isEpoxyModel(memoizer)) {\n                logger.logError(\n                    modelFieldElement,\n                    \"Fields with %s annotations must be of type %s (%s#%s)\",\n                    AutoModel::class.java.simpleName,\n                    Utils.EPOXY_MODEL_TYPE,\n                    modelFieldElement.enclosingElement.expectName,\n                    modelFieldElement.name\n                )\n            }\n\n            fieldType.typeNameWithWorkaround(memoizer)\n        } else {\n            // We only have the simple name of the model, since it isn't generated yet.\n            // We can find the FQN by looking in imports. Imports aren't actually directly accessible\n            // in the AST, so we have a hacky workaround by accessing the compiler tree\n\n            val simpleName = fieldType.toString()\n\n            val packageName = classElement.imports\n                .firstOrNull { it.endsWith(simpleName) }\n                ?.substringBeforeLast(\".$simpleName\")\n                // With no import we assume the model is in the same package as the controller\n                ?: classElement.classPackage\n\n            ClassName.get(packageName, simpleName)\n        }\n\n        return ControllerModelField(\n            fieldName = fieldName,\n            typeName = modelTypeName,\n            packagePrivate = Utils.isFieldPackagePrivate(modelFieldElement)\n        )\n    }\n\n    private fun generateJava(controllerClassMap: MutableMap<ClassName, ControllerClassInfo>) {\n        for ((_, classInfo) in controllerClassMap) {\n            try {\n                generateHelperClassForController(classInfo)\n            } catch (e: Exception) {\n                logger.logError(e)\n            }\n        }\n    }\n\n    private fun generateHelperClassForController(controllerInfo: ControllerClassInfo) {\n        val parameterizeSuperClass = ParameterizedTypeName.get(\n            ClassNames.EPOXY_CONTROLLER_HELPER,\n            controllerInfo.controllerClassType\n        )\n\n        val classSpec = TypeSpec.classBuilder(controllerInfo.generatedClassName).apply {\n\n            addJavadoc(\"Generated file. Do not modify!\")\n            addModifiers(Modifier.PUBLIC)\n            superclass(parameterizeSuperClass)\n            addField(\n                controllerInfo.controllerClassType,\n                \"controller\",\n                Modifier.FINAL,\n                Modifier.PRIVATE\n            )\n            addMethod(buildConstructor(controllerInfo))\n            addMethod(buildResetModelsMethod(controllerInfo))\n\n            if (configManager.shouldValidateModelUsage()) {\n                addFields(buildFieldsToSaveModelsForValidation(controllerInfo))\n                addMethod(buildValidateModelsHaveNotChangedMethod(controllerInfo))\n                addMethod(buildValidateSameValueMethod())\n                addMethod(buildSaveModelsForNextValidationMethod(controllerInfo))\n            }\n\n            addOriginatingElement(controllerInfo.originatingElement)\n\n            // Package configs can be used to change the implicit auto add option.\n            originatingConfigElements().forEach { configElement ->\n                addOriginatingElement(configElement)\n            }\n        }.build()\n\n        JavaFile.builder(controllerInfo.generatedClassName.packageName(), classSpec)\n            .build()\n            .writeTo(filer, mode = XFiler.Mode.Aggregating)\n    }\n\n    private fun buildConstructor(controllerInfo: ControllerClassInfo): MethodSpec {\n        val controllerParam = ParameterSpec\n            .builder(controllerInfo.controllerClassType, \"controller\")\n            .build()\n        return MethodSpec.constructorBuilder()\n            .addParameter(controllerParam)\n            .addModifiers(Modifier.PUBLIC)\n            .addStatement(\"this.controller = controller\")\n            .build()\n    }\n\n    /**\n     * A field is created to save a reference to the model we create. Before the new buildModels phase\n     * we check that it is the same object as on the controller, validating that the user has not\n     * manually assigned a new model to the AutoModel field.\n     */\n    private fun buildFieldsToSaveModelsForValidation(\n        controllerInfo: ControllerClassInfo\n    ): Iterable<FieldSpec> {\n        val fields: MutableList<FieldSpec> = ArrayList()\n        for (model in controllerInfo.models) {\n            fields.add(\n                FieldSpec.builder(\n                    ClassNames.EPOXY_MODEL_UNTYPED,\n                    model.fieldName, Modifier.PRIVATE\n                ).build()\n            )\n        }\n        return fields\n    }\n\n    private fun buildValidateModelsHaveNotChangedMethod(controllerInfo: ControllerClassInfo): MethodSpec {\n        val builder = MethodSpec.methodBuilder(\"validateModelsHaveNotChanged\")\n            .addModifiers(Modifier.PRIVATE)\n\n        // Validate that annotated fields have not been reassigned or had their id changed\n        var id: Long = -1\n        for (model in controllerInfo.models) {\n            builder.addStatement(\n                \"validateSameModel(\\$L, controller.\\$L, \\$S, \\$L)\",\n                model.fieldName, model.fieldName, model.fieldName, id--\n            )\n        }\n        return builder\n            .addStatement(\"validateModelHashCodesHaveNotChanged(controller)\")\n            .build()\n    }\n\n    private fun buildValidateSameValueMethod(): MethodSpec {\n        return MethodSpec.methodBuilder(\"validateSameModel\")\n            .addModifiers(Modifier.PRIVATE)\n            .addParameter(\n                EPOXY_MODEL_UNTYPED,\n                \"expectedObject\"\n            )\n            .addParameter(\n                EPOXY_MODEL_UNTYPED,\n                \"actualObject\"\n            )\n            .addParameter(String::class.java, \"fieldName\")\n            .addParameter(TypeName.INT, \"id\")\n            .beginControlFlow(\"if (expectedObject != actualObject)\")\n            .addStatement(\n                \"throw new \\$T(\\\"Fields annotated with \\$L cannot be directly assigned. The controller \" +\n                    \"manages these fields for you. (\\\" + controller.getClass().getSimpleName() + \" +\n                    \"\\\"#\\\" + fieldName + \\\")\\\")\",\n                IllegalStateException::class.java,\n                AutoModel::class.java.simpleName\n            )\n            .endControlFlow()\n            .beginControlFlow(\"if (actualObject != null && actualObject.id() != id)\")\n            .addStatement(\n                \"throw new \\$T(\\\"Fields annotated with \\$L cannot have their id changed manually. The \" +\n                    \"controller manages the ids of these models for you. (\\\" + controller.getClass()\" +\n                    \".getSimpleName() + \\\"#\\\" + fieldName + \\\")\\\")\",\n                IllegalStateException::class.java,\n                AutoModel::class.java.simpleName\n            )\n            .endControlFlow()\n            .build()\n    }\n\n    private fun buildSaveModelsForNextValidationMethod(controllerInfo: ControllerClassInfo): MethodSpec {\n        val builder = MethodSpec.methodBuilder(\"saveModelsForNextValidation\")\n            .addModifiers(Modifier.PRIVATE)\n        for (model in controllerInfo.models) {\n            builder.addStatement(\"\\$L = controller.\\$L\", model.fieldName, model.fieldName)\n        }\n        return builder.build()\n    }\n\n    private fun buildResetModelsMethod(controllerInfo: ControllerClassInfo): MethodSpec {\n        val builder = MethodSpec.methodBuilder(\"resetAutoModels\")\n            .addAnnotation(Override::class.java)\n            .addModifiers(Modifier.PUBLIC)\n        if (configManager.shouldValidateModelUsage()) {\n            builder.addStatement(\"validateModelsHaveNotChanged()\")\n        }\n        val implicitlyAddAutoModels =\n            configManager.implicitlyAddAutoModels(controllerInfo)\n        var id: Long = -1\n        for (model in controllerInfo.models) {\n            builder.addStatement(\"controller.\\$L = new \\$T()\", model.fieldName, model.typeName)\n                .addStatement(\"controller.\\$L.id(\\$L)\", model.fieldName, id--)\n            if (implicitlyAddAutoModels) {\n                builder.addStatement(\n                    \"setControllerToStageTo(controller.\\$L, controller)\",\n                    model.fieldName\n                )\n            }\n        }\n        if (configManager.shouldValidateModelUsage()) {\n            builder.addStatement(\"saveModelsForNextValidation()\")\n        }\n        return builder.build()\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/DataBindingAttributeInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XMethodElement\nimport com.airbnb.epoxy.processor.Utils.removeSetPrefix\n\ninternal class DataBindingAttributeInfo(\n    modelInfo: DataBindingModelInfo,\n    setterMethod: XMethodElement,\n    hashCodeValidator: HashCodeValidator,\n    memoizer: Memoizer\n) : AttributeInfo(memoizer) {\n\n    init {\n        fieldName = removeSetPrefix(setterMethod.name)\n        // Use the memoizer parameter from the current round, not modelInfo.memoizer.\n        // modelInfo may have been created in a previous round and its memoizer holds stale KSP references.\n        setXType(setterMethod.parameters[0].type, memoizer)\n        rootClass = modelInfo.generatedName.simpleName()\n        packageName = modelInfo.generatedName.packageName()\n        useInHash = !modelInfo.enableDoNotHash ||\n            hashCodeValidator.implementsHashCodeAndEquals(xType)\n        ignoreRequireHashCode = true\n        generateSetter = true\n        generateGetter = true\n        hasFinalModifier = false\n        isPackagePrivate = false\n        isGenerated = true\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/DataBindingModelInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.processor.ClassNames.EPOXY_DATA_BINDING_HOLDER\nimport com.airbnb.epoxy.processor.ClassNames.EPOXY_DATA_BINDING_MODEL\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceValue\nimport com.squareup.javapoet.ClassName\n\ninternal class DataBindingModelInfo(\n    val layoutResource: ResourceValue,\n    val moduleName: String,\n    private val layoutPrefix: String = \"\",\n    val enableDoNotHash: Boolean,\n    val annotatedElement: XElement,\n    memoizer: Memoizer\n) : GeneratedModelInfo(memoizer) {\n    private val dataBindingClassName: ClassName\n\n    private var dataBindingClassElement: XTypeElement? = null\n        get() {\n            if (field == null) {\n                field = memoizer.environment.findTypeElement(dataBindingClassName.toString())\n            }\n            return field\n        }\n\n    init {\n        dataBindingClassName = getDataBindingClassNameForResource(layoutResource, moduleName)\n\n        superClassElement = memoizer.epoxyDataBindingModelBaseClass ?: error(\"Epoxy Databinding library not found\")\n        superClassName = EPOXY_DATA_BINDING_MODEL\n        generatedName = buildGeneratedModelName()\n        parameterizedGeneratedName = generatedName\n        modelType = EPOXY_DATA_BINDING_HOLDER\n        shouldGenerateModel = true\n\n        collectMethodsReturningClassType(superClassElement)\n    }\n\n    /**\n     * Look up the DataBinding class generated for this model's layout file and parse the attributes\n     * for it.\n     * @return the databinding element if it was successfully parsed, null otherwise.\n     */\n    fun parseDataBindingClass(logger: Logger): XTypeElement? {\n        // This databinding class won't exist until the second round of annotation processing since\n        // it is generated in the first round.\n        val dataBindingClassElement = this.dataBindingClassElement ?: return null\n        val hashCodeValidator = HashCodeValidator(memoizer.environment, memoizer, logger)\n\n        dataBindingClassElement.getDeclaredMethods()\n            .filter { Utils.isSetterMethod(it) }\n            .map {\n                DataBindingAttributeInfo(this, it, hashCodeValidator, memoizer)\n            }\n            .filter { it.fieldName !in FIELD_NAME_BLACKLIST }\n            .let {\n                addAttributes(it)\n            }\n\n        return dataBindingClassElement\n    }\n\n    private fun getDataBindingClassNameForResource(\n        layoutResource: ResourceValue,\n        moduleName: String\n    ): ClassName {\n        val modelName = layoutResource.resourceName?.toUpperCamelCase()?.plus(BINDING_SUFFIX)\n            ?: error(\"Resource name not found for layout: ${layoutResource.debugDetails()}\")\n\n        return ClassName.get(\"$moduleName.databinding\", modelName)\n    }\n\n    private fun buildGeneratedModelName(): ClassName {\n        val modelName = layoutResource.resourceName!!\n            .removePrefix(layoutPrefix)\n            .toUpperCamelCase()\n            .plus(BINDING_SUFFIX)\n            .plus(GENERATED_MODEL_SUFFIX)\n\n        return ClassName.get(moduleName, modelName)\n    }\n\n    companion object {\n\n        const val BINDING_SUFFIX = \"Binding\"\n\n        val FIELD_NAME_BLACKLIST = listOf(\n            // Starting with Android plugin 3.1.0 nested DataBinding classes have a\n            // \"setLifecycleOwner\" method\n            \"lifecycleOwner\"\n        )\n    }\n\n    override fun additionalOriginatingElements(currentMemoizer: Memoizer) =\n        listOfNotNull(annotatedElement, dataBindingClassElement)\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/DataBindingModuleLookup.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.squareup.javapoet.ClassName\nimport kotlin.math.min\n\nclass DataBindingModuleLookup(\n    private val environment: XProcessingEnv,\n    private val logger: Logger,\n    private val resourceProcessor: ResourceScanner\n) {\n    fun getModuleName(element: XTypeElement): String {\n        val packageName = element.packageName\n\n        // First we try to get the module name by looking at what R classes were found when processing\n        // layout annotations. This may find nothing if no layouts were given as annotation params\n        var moduleName: String? = getModuleNameViaResources(packageName)\n        if (moduleName == null) {\n            // If the first approach fails, we try to guess at the R class for the module and look up\n            // the class to see if it exists. This can fail if this model's package name does not\n            // include the module name as a prefix (convention makes this unlikely.)\n            moduleName = getModuleNameViaGuessing(packageName)\n        }\n\n        if (moduleName == null) {\n            logger.logError(\"Could not find module name for DataBinding BR class.\")\n            // Fallback to using the package name so we can at least try to generate and compile something\n            moduleName = packageName\n        }\n\n        return moduleName\n    }\n\n    /**\n     * Attempts to get the module name of the given package. We can do this because the package name\n     * of an R class is the module. Generally only one R class is used and we can just use that module\n     * name, but it is possible to have multiple R classes. In that case we compare the package names\n     * to find what is the most similar.\n     *\n     *\n     * We need to get the module name to know the path of the BR class for data binding.\n     */\n    private fun getModuleNameViaResources(packageName: String): String {\n        val rClasses = resourceProcessor.rClassNames\n        if (rClasses.isEmpty()) {\n            return packageName\n        }\n        if (rClasses.size == 1) {\n            // Common case\n            return rClasses[0].packageName()\n        }\n\n        // Generally the only R class used should be the app's. It is possible to use other R classes\n        // though, like Android's. In that case we figure out the most likely match by comparing the\n        // package name.\n        //  For example we might have \"com.airbnb.epoxy.R\" and \"android.R\"\n        val packageNames = packageName.split(\"\\\\.\").toTypedArray()\n        var bestMatch: ClassName? = null\n        val bestNumMatches = -1\n        for (rClass in rClasses) {\n            val rModuleNames = rClass.packageName().split(\"\\\\.\").toTypedArray()\n            var numNameMatches = 0\n            for (i in 0 until min(packageNames.size, rModuleNames.size)) {\n                if (packageNames[i] == rModuleNames[i]) {\n                    numNameMatches++\n                } else {\n                    break\n                }\n            }\n            if (numNameMatches > bestNumMatches) {\n                bestMatch = rClass\n            }\n        }\n        return bestMatch!!.packageName()\n    }\n\n    /**\n     * Attempts to get the android module that is currently being processed.. We can do this because\n     * the package name of an R class is the module name. So, we take any element in the module,\n     *\n     *\n     * We need to get the module name to know the path of the BR class for data binding.\n     */\n    private fun getModuleNameViaGuessing(packageName: String): String? {\n        val packageNameParts = packageName.split(\"\\\\.\").toTypedArray()\n        var moduleName = \"\"\n        for (i in packageNameParts.indices) {\n            moduleName += packageNameParts[i]\n            val rClass = environment.findType(\"$moduleName.R\")\n            moduleName += if (rClass != null) {\n                return moduleName\n            } else {\n                \".\"\n            }\n        }\n        return null\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/DataBindingProcessor.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.EpoxyDataBindingLayouts\nimport com.airbnb.epoxy.EpoxyDataBindingPattern\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceValue\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.squareup.javapoet.ClassName\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType\nimport java.util.Collections\nimport kotlin.reflect.KClass\n\n/**\n * Note, Databinding doens't actually work with KSP because it relies on KAPT, and KSP cannot depend\n * on KAPT sources.\n *\n * If that dependency can be resolved then the below processor implementation \"should\" work.\n */\nclass DataBindingProcessorProvider : SymbolProcessorProvider {\n    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {\n        return DataBindingProcessor(environment)\n    }\n}\n\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING)\nclass DataBindingProcessor @JvmOverloads constructor(\n    kspEnvironment: SymbolProcessorEnvironment? = null\n) : BaseProcessor(kspEnvironment) {\n    private val modelsToWrite = Collections.synchronizedList(\n        mutableListOf<DataBindingModelInfo>()\n    )\n\n    override fun supportedAnnotations(): List<KClass<*>> = listOf(\n        EpoxyDataBindingLayouts::class,\n        EpoxyDataBindingPattern::class\n    )\n\n    override fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        round.getElementsAnnotatedWith(EpoxyDataBindingLayouts::class)\n            .filterIsInstance<XTypeElement>()\n            .also {\n                timer.markStepCompleted(\"get databinding layouts\")\n            }\n            .mapNotNull { layoutsAnnotatedElement ->\n\n                val layoutResources = resourceProcessor.getResourceValueList(\n                    EpoxyDataBindingLayouts::class,\n                    layoutsAnnotatedElement,\n                    \"value\"\n                ) ?: run {\n                    logger.logError(\n                        layoutsAnnotatedElement,\n                        \"Unable to get EpoxyDataBindingLayouts value from $layoutsAnnotatedElement\"\n                    )\n                    return@mapNotNull null\n                }\n\n                // Get the module name after parsing resources so we can use the resource classes to\n                // figure out the module name\n                val moduleName = dataBindingModuleLookup.getModuleName(layoutsAnnotatedElement)\n\n                val enableDoNotHash =\n                    layoutsAnnotatedElement.getAnnotation(EpoxyDataBindingLayouts::class)?.getAsBoolean(\"enableDoNotHash\") == true\n\n                layoutResources.map { resourceValue ->\n                    DataBindingModelInfo(\n                        layoutResource = resourceValue,\n                        moduleName = moduleName,\n                        enableDoNotHash = enableDoNotHash,\n                        annotatedElement = layoutsAnnotatedElement,\n                        memoizer = memoizer\n                    )\n                }\n            }.let { dataBindingModelInfos ->\n                timer.markStepCompleted(\"parse databinding layouts\")\n                modelsToWrite.addAll(dataBindingModelInfos.flatten())\n            }\n\n        round.getElementsAnnotatedWith(EpoxyDataBindingPattern::class)\n            .filterIsInstance<XTypeElement>()\n            .also {\n                timer.markStepCompleted(\"get databinding patterns\")\n            }\n            .map { annotatedElement ->\n\n                val patternAnnotation =\n                    annotatedElement.requireAnnotation(EpoxyDataBindingPattern::class)\n\n                val layoutPrefix = patternAnnotation.getAsString(\"layoutPrefix\")\n                val rClassName = patternAnnotation.getAsType(\"rClass\")?.typeElement\n                    ?: return@map emptyList<DataBindingModelInfo>()\n\n                val moduleName = rClassName.packageName\n                val layoutClassName = ClassName.get(moduleName, \"R\", \"layout\")\n                val enableDoNotHash =\n                    annotatedElement.getAnnotation(EpoxyDataBindingPattern::class)?.getAsBoolean(\"enableDoNotHash\") == true\n\n                val rClassElement = environment.requireTypeElement(layoutClassName.toString())\n\n                rClassElement\n                    .getDeclaredFields()\n                    .asSequence()\n                    .map { it.name }\n                    .filter { it.startsWith(layoutPrefix) }\n                    .map { ResourceValue(layoutClassName, it, 0 /* value doesn't matter */) }\n                    .toList()\n                    .mapNotNull { layoutResource ->\n                        DataBindingModelInfo(\n                            layoutResource = layoutResource,\n                            moduleName = moduleName,\n                            layoutPrefix = layoutPrefix,\n                            enableDoNotHash = enableDoNotHash,\n                            annotatedElement = annotatedElement,\n                            memoizer = memoizer\n                        )\n                    }\n            }.let { dataBindingModelInfos ->\n                timer.markStepCompleted(\"parse databinding patterns\")\n                modelsToWrite.addAll(dataBindingModelInfos.flatten())\n            }\n\n        val modelsWritten = resolveDataBindingClassesAndWriteJava(memoizer)\n        timer.markStepCompleted(\"resolve and write files\")\n        if (modelsWritten.isNotEmpty()) {\n            // All databinding classes are generated at the same time, so once one is ready they\n            // all should be. Since we infer databinding layouts based on a naming pattern we may\n            // have some false positives which we can clear from the list if we can't find a\n            // databinding class for them.\n            modelsToWrite.clear()\n        }\n\n        generatedModels.addAll(modelsWritten)\n\n        // We need to tell KSP that we are waiting for the databinding element so that we will\n        // process another round. We don't have\n        // that symbol to return directly, so we just return any symbol.\n        return if (isKsp()) {\n            modelsToWrite.map { it.annotatedElement }.also {\n                // KSP doesn't normally resurface annotated elements in future rounds, but because\n                // we return it as a deferred symbol it will allow it to be discovered again in the\n                // next round, so to avoid duplicates we clear it.\n                modelsToWrite.clear()\n            }\n        } else {\n            emptyList()\n        }\n    }\n\n    private fun resolveDataBindingClassesAndWriteJava(memoizer: Memoizer): List<DataBindingModelInfo> {\n        return modelsToWrite.filter(\"resolveDataBindingClassesAndWriteJava\") { bindingModelInfo ->\n            bindingModelInfo.parseDataBindingClass(logger) ?: return@filter false\n            createModelWriter(memoizer).generateClassForModel(\n                bindingModelInfo,\n                originatingElements = bindingModelInfo.originatingElements(memoizer)\n            )\n            true\n        }.also { writtenModels ->\n            modelsToWrite.removeAll(writtenModels)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/EpoxyProcessor.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType\nimport java.util.LinkedHashMap\nimport java.util.concurrent.ConcurrentHashMap\nimport kotlin.reflect.KClass\n\nclass EpoxyProcessorProvider : SymbolProcessorProvider {\n    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {\n        return EpoxyProcessor(environment)\n    }\n}\n\n/**\n * Looks for [EpoxyAttribute] annotations and generates a subclass for all classes that have\n * those attributes. The generated subclass includes setters, getters, equals, and hashcode for the\n * given field. Any constructors on the original class are duplicated. Abstract classes are ignored\n * since generated classes would have to be abstract in order to guarantee they compile, and that\n * reduces their usefulness and doesn't make as much sense to support.\n */\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING)\nclass EpoxyProcessor @JvmOverloads constructor(\n    kspEnvironment: SymbolProcessorEnvironment? = null\n) : BaseProcessorWithPackageConfigs(kspEnvironment) {\n\n    override val usesPackageEpoxyConfig: Boolean = true\n    override val usesModelViewConfig: Boolean = false\n    private val styleableModelsToWrite = mutableListOf<BasicGeneratedModelInfo>()\n\n    override fun additionalSupportedAnnotations(): List<KClass<*>> = listOf(\n        EpoxyModelClass::class,\n        EpoxyAttribute::class\n    )\n\n    override fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        super.processRound(environment, round, memoizer, timer, roundNumber)\n        val modelClassMap = ConcurrentHashMap<XTypeElement, GeneratedModelInfo>()\n\n        round.getElementsAnnotatedWith(EpoxyAttribute::class)\n            .filterIsInstance<XFieldElement>()\n            .also {\n                timer.markStepCompleted(\"get epoxy attributes\")\n            }\n            .mapNotNull { annotatedElement ->\n                getOrCreateTargetClass(\n                    modelClassMap,\n                    annotatedElement.enclosingElement as XTypeElement,\n                    memoizer\n                )?.let {\n                    annotatedElement to it\n                }\n            }\n            .also {\n                timer.markStepCompleted(\"parse controller classes\")\n            }\n            .map { (attribute, targetClass) ->\n                buildAttributeInfo(\n                    attribute,\n                    logger,\n                    memoizer\n                ) to targetClass\n            }.forEach { (attributeInfo, targetClass) ->\n                // Do this after, synchronously, to preserve order of the generated attributes.\n                // This keeps the generated code consistent, which is necessary for cache keys,\n                // and some users may rely on the order that attributes are set (even though they shouldn't)\n                targetClass.addAttribute(attributeInfo)\n            }\n\n        timer.markStepCompleted(\"build attribute info\")\n\n        round.getElementsAnnotatedWith(EpoxyModelClass::class)\n            .filterIsInstance<XTypeElement>()\n            .also {\n                timer.markStepCompleted(\"get model classes\")\n            }\n            .map { clazz ->\n                getOrCreateTargetClass(modelClassMap, clazz, memoizer)\n            }\n        timer.markStepCompleted(\"build target class models\")\n\n        addAttributesFromOtherModules(modelClassMap, memoizer)\n        timer.markStepCompleted(\"add attributes from other modules\")\n\n        updateClassesForInheritance(modelClassMap)\n        timer.markStepCompleted(\"update classes for inheritance\")\n\n        val modelInfos = modelClassMap.values\n\n        val styleableModels = modelInfos\n            .filterIsInstance<BasicGeneratedModelInfo>()\n            .filter { modelInfo ->\n                modelInfo.safeSuperClassElement(memoizer).getAnnotation(EpoxyModelClass::class)?.getAsInt(\"layout\") == 0 &&\n                    modelInfo.boundObjectTypeElement?.hasStyleableAnnotation() == true\n            }\n        timer.markStepCompleted(\"check for styleable models\")\n\n        styleableModelsToWrite.addAll(styleableModels)\n\n        modelInfos.minus(styleableModels).mapNotNull {\n            writeModel(it, memoizer)\n        }\n\n        styleableModelsToWrite.mapNotNull { modelInfo ->\n            if (tryAddStyleBuilderAttribute(modelInfo, environment, memoizer)) {\n                writeModel(modelInfo, memoizer)\n                modelInfo\n            } else {\n                null\n            }\n        }\n            .let { styleableModelsToWrite.removeAll(it) }\n\n        generatedModels.addAll(modelClassMap.values)\n        timer.markStepCompleted(\"write models\")\n\n        return emptyList()\n    }\n\n    private fun writeModel(modelInfo: GeneratedModelInfo, memoizer: Memoizer) {\n        createModelWriter(memoizer).generateClassForModel(\n            modelInfo,\n            originatingElements = modelInfo.originatingElements(memoizer)\n        )\n    }\n\n    private fun getOrCreateTargetClass(\n        modelClassMap: MutableMap<XTypeElement, GeneratedModelInfo>,\n        classElement: XTypeElement,\n        memoizer: Memoizer,\n    ): GeneratedModelInfo? {\n        modelClassMap[classElement]?.let { return it }\n\n        val isFinal = classElement.isFinal()\n        if (isFinal) {\n            logger.logError(\n                \"Class with %s annotations cannot be final: %s\",\n                EpoxyAttribute::class.java.simpleName, classElement.name\n            )\n        }\n\n        // Nested classes must be static\n        if (classElement.enclosingTypeElement != null) {\n            if (!classElement.isStatic()) {\n                logger.logError(\n                    \"Nested model classes must be static. (class: %s)\",\n                    classElement.name\n                )\n                return null\n            }\n        }\n\n        if (!classElement.isEpoxyModel(memoizer)) {\n            logger.logError(\n                classElement,\n                \"Class with %s annotations must extend %s (%s)\",\n                EpoxyAttribute::class.java.simpleName, Utils.EPOXY_MODEL_TYPE,\n                classElement.name\n            )\n            return null\n        }\n\n        if (configManager.requiresAbstractModels(classElement) && !classElement.isAbstract()\n        ) {\n            logger\n                .logError(\n                    classElement,\n                    \"Epoxy model class must be abstract (%s)\",\n                    classElement.name\n                )\n        }\n\n        val generatedModelInfo = BasicGeneratedModelInfo(\n            classElement,\n            logger,\n            memoizer\n        )\n        modelClassMap[classElement] = generatedModelInfo\n\n        return generatedModelInfo\n    }\n\n    /**\n     * Looks for attributes on super classes that weren't included in this processor's coverage. Super\n     * classes are already found if they are in the same module since the processor will pick them up\n     * with the rest of the annotations.\n     */\n    private fun addAttributesFromOtherModules(\n        modelClassMap: Map<XTypeElement, GeneratedModelInfo>,\n        memoizer: Memoizer,\n    ) {\n        modelClassMap.entries.forEach(\"addAttributesFromOtherModules\") { (currentEpoxyModel, generatedModelInfo) ->\n            // We add just the attribute info to the class in our module. We do NOT want to\n            // generate a class for the super class EpoxyModel in the other module since one\n            // will be created when that module is processed. If we make one as well there will\n            // be a duplicate (causes proguard errors and is just wrong).\n            memoizer.getInheritedEpoxyAttributes(\n                currentEpoxyModel.superClass!!,\n                generatedModelInfo.generatedName.packageName(),\n                logger,\n                includeSuperClass = { superClassElement ->\n                    !modelClassMap.keys.contains(superClassElement)\n                }\n            ).let { attributeInfos ->\n                generatedModelInfo.addAttributes(attributeInfos)\n            }\n        }\n    }\n\n    /**\n     * Check each model for super classes that also have attributes. For each super class with\n     * attributes we add those attributes to the attributes of the generated class, so that a\n     * generated class contains all the attributes of its super classes combined.\n     *\n     * One caveat is that if a sub class is in a different package than its super class we can't\n     * include attributes that are package private, otherwise the generated class won't compile.\n     */\n    private fun updateClassesForInheritance(\n        helperClassMap: Map<XTypeElement, GeneratedModelInfo>\n    ) {\n        helperClassMap.forEach(\"updateClassesForInheritance\") { thisModelClass, generatedModelInfo ->\n\n            val otherClasses = LinkedHashMap(helperClassMap)\n            otherClasses.remove(thisModelClass)\n\n            otherClasses\n                .filter { (otherClass, _) ->\n                    thisModelClass.isSubTypeOf(otherClass)\n                }\n                .forEach { (otherClass, modelInfo) ->\n                    val otherAttributes = modelInfo.attributeInfoImmutable\n\n                    if (thisModelClass.isInSamePackageAs(otherClass)) {\n                        generatedModelInfo.addAttributes(otherAttributes)\n                    } else {\n                        otherAttributes\n                            .filterNot { it.isPackagePrivate }\n                            .forEach { generatedModelInfo.addAttribute(it) }\n                    }\n                }\n        }\n    }\n\n    companion object {\n        fun buildAttributeInfo(\n            attribute: XFieldElement,\n            logger: Logger,\n            memoizer: Memoizer\n        ): AttributeInfo {\n            Utils.validateFieldAccessibleViaGeneratedCode(\n                attribute,\n                EpoxyAttribute::class.java,\n                logger,\n                skipPrivateFieldCheck = true\n            )\n            return BaseModelAttributeInfo(attribute, logger, memoizer)\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/EpoxyProcessorException.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\n\ninternal class EpoxyProcessorException(\n    message: String,\n    cause: Throwable? = null,\n    element: XElement? = null\n) : RuntimeException(buildMessage(message, element), cause) {\n\n    companion object {\n        private fun buildMessage(message: String, element: XElement?): String {\n            if (element == null) return message\n\n            // Extract element metadata immediately while PSI is still valid.\n            // In KSP2, accessing elements in finish() callback throws:\n            // \"Access to invalid KotlinAlwaysAccessibleLifetimeToken: PSI has changed since creation\"\n            val elementInfo = buildString {\n                append(\" [element=${element.name}\")\n\n                element.enclosingElement?.let { enclosing ->\n                    append(\" in ${enclosing.name}\")\n                }\n\n                append(\"]\")\n            }\n\n            return message + elementInfo\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Extensions.kt",
    "content": "package com.airbnb.epoxy.processor\n\ninternal fun String.lowerCaseFirstLetter(): String {\n    if (isEmpty()) {\n        return this\n    }\n\n    return Character.toLowerCase(get(0)) + substring(1)\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/GeneratedModelInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.XVariableElement\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.processor.Utils.buildEpoxyException\nimport com.squareup.javapoet.AnnotationSpec\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeVariableName\nimport java.util.ArrayList\nimport java.util.LinkedHashSet\nimport javax.lang.model.element.Modifier\n\nabstract class GeneratedModelInfo(val memoizer: Memoizer) {\n\n    lateinit var superClassElement: XTypeElement\n\n    /**\n     * Looks up and returns the super class element by FQN, to avoid errors from accessing\n     * an XTypeElement from a previous processing round.\n     *\n     * @param currentMemoizer The memoizer from the current processing round. Must be passed\n     *        explicitly to ensure we use a fresh environment, not the stale one stored in `this.memoizer`.\n     */\n    fun safeSuperClassElement(currentMemoizer: Memoizer): XTypeElement {\n        return currentMemoizer.environment.requireTypeElement(superClassElement.qualifiedName)\n    }\n\n    lateinit var superClassName: TypeName\n    lateinit var parameterizedGeneratedName: TypeName\n    lateinit var generatedName: ClassName\n\n    /**\n     * Get the object type this model is typed with.\n     */\n    var modelType: TypeName? = null\n        protected set\n    var shouldGenerateModel = false\n\n    /**\n     * If true, any layout classes that exist that are prefixed by the default layout are included in\n     * the generated model as other layout options via a generated method for each alternate layout.\n     */\n    var includeOtherLayoutOptions = false\n\n    val attributeInfo: MutableList<AttributeInfo> = mutableListOf()\n\n    @get:Synchronized\n    val attributeInfoImmutable: List<AttributeInfo>\n        get() = attributeInfo.toList()\n\n    val typeVariableNames: MutableList<TypeVariableName> = ArrayList()\n    val constructors: MutableList<ConstructorInfo> = ArrayList()\n    val methodsReturningClassType: MutableSet<MethodInfo> = LinkedHashSet()\n    val attributeGroups: MutableList<AttributeGroup> = ArrayList()\n    private val attributeToGroup = mutableMapOf<AttributeInfo, AttributeGroup>()\n    val annotations: MutableList<AnnotationSpec> = ArrayList()\n\n    /**\n     * The info for the style builder if this is a model view annotated with @Styleable. Null\n     * otherwise.\n     */\n    var styleBuilderInfo: ParisStyleAttributeInfo? = null\n        private set\n\n    /**\n     * An option set via [com.airbnb.epoxy.ModelView.autoLayout] to have Epoxy create the\n     * view programmatically\n     * instead of via xml layout resource inflation.\n     */\n    var layoutParams = ModelView.Size.NONE\n\n    /**\n     * The elements that influence the generation of this model.\n     * eg base model class for @EpoxyModelClass, view class for @ModelView, etc\n     *\n     * @param currentMemoizer The memoizer from the current processing round.\n     */\n    fun originatingElements(currentMemoizer: Memoizer): List<XElement> {\n        return listOfNotNull(styleBuilderInfo?.styleBuilderElement)\n            .plus(additionalOriginatingElements(currentMemoizer))\n    }\n\n    open fun additionalOriginatingElements(currentMemoizer: Memoizer): List<XElement> = emptyList()\n\n    /**\n     * Get information about constructors of the original class so we can duplicate them in the\n     * generated class and call through to super with the proper parameters\n     */\n    fun getClassConstructors(classElement: XTypeElement): List<ConstructorInfo> {\n        return memoizer.getClassConstructors(classElement, memoizer)\n    }\n\n    /**\n     * Get information about methods returning class type of the original class so we can duplicate\n     * them in the generated class for chaining purposes\n     */\n    fun collectMethodsReturningClassType(superModelClass: XTypeElement) {\n        methodsReturningClassType\n            .addAll(memoizer.getMethodsReturningClassType(superModelClass.qualifiedName, memoizer))\n    }\n\n    @Synchronized\n    fun addAttribute(attributeInfo: AttributeInfo) {\n        addAttributes(listOf(attributeInfo))\n    }\n\n    @Synchronized\n    fun addAttributes(attributesToAdd: Collection<AttributeInfo>) {\n        removeMethodIfDuplicatedBySetter(attributesToAdd)\n\n        // Overwrite duplicates while preserving ordering\n        for (attribute in attributesToAdd) {\n            val existingIndex = attributeInfo.indexOf(attribute)\n            if (existingIndex > -1) {\n                attributeInfo[existingIndex] = attribute\n            } else {\n                attributeInfo.add(attribute)\n            }\n        }\n    }\n\n    @Synchronized\n    fun addAttributeIfNotExists(attributeToAdd: AttributeInfo) {\n        if (attributeToAdd !in attributeInfo) {\n            addAttribute(attributeToAdd)\n        }\n    }\n\n    private fun removeMethodIfDuplicatedBySetter(attributeInfos: Collection<AttributeInfo>) {\n        for (attributeInfo in attributeInfos) {\n            val iterator = methodsReturningClassType.iterator()\n            while (iterator.hasNext()) {\n                val (name, _, params) = iterator.next()\n                if (name == attributeInfo.fieldName && params.size == 1 && params[0].type == attributeInfo.typeName) {\n                    iterator.remove()\n                }\n            }\n        }\n    }\n\n    val typeVariables: Iterable<TypeVariableName>\n        get() = typeVariableNames\n\n    val isStyleable: Boolean\n        get() = styleBuilderInfo != null\n\n    fun setStyleable(\n        parisStyleAttributeInfo: ParisStyleAttributeInfo\n    ) {\n        styleBuilderInfo = parisStyleAttributeInfo\n        addAttribute(parisStyleAttributeInfo)\n    }\n\n    val isProgrammaticView: Boolean\n        get() = isStyleable || layoutParams != ModelView.Size.NONE\n\n    fun hasEmptyConstructor(): Boolean {\n        return constructors.isEmpty() || constructors.any { it.params.isEmpty() }\n    }\n\n    /**\n     * @return True if the super class of this generated model is also extended from a generated\n     * model.\n     */\n    fun isSuperClassAlsoGenerated(currentMemoizer: Memoizer): Boolean {\n        val generatedModelType = currentMemoizer.generatedModelType\n        return safeSuperClassElement(currentMemoizer).type.isSubTypeOf(generatedModelType)\n    }\n\n    data class ConstructorInfo internal constructor(\n        val modifiers: Set<Modifier>,\n        val params: List<ParameterSpec>,\n        val varargs: Boolean\n    )\n\n    override fun toString(): String {\n        return (\n            \"GeneratedModelInfo{\" +\n                \"attributeInfo=\" + attributeInfo +\n                \", superClassName=\" + superClassName +\n                '}'\n            )\n    }\n\n    @Throws(EpoxyProcessorException::class)\n    fun addAttributeGroup(\n        groupName: String?,\n        attributes: List<AttributeInfo>\n    ) {\n        var defaultAttribute: AttributeInfo? = null\n        for (attribute in attributes) {\n            if (attribute.isRequired ||\n                attribute.codeToSetDefault.isEmpty && !hasDefaultKotlinValue(\n                        attribute\n                    )\n            ) {\n                continue\n            }\n            val hasSetExplicitDefault =\n                defaultAttribute != null && hasExplicitDefault(defaultAttribute)\n\n            // Have the first explicit default value in the group trump everything else.\n            // If there are multiple set just ignore the rest. This simplifies our lookup\n            // of kotlin default params since it's hard to know exactly which function has\n            // set a default param (if they have the same function name and param name)\n            if (hasSetExplicitDefault) {\n                continue\n            }\n\n            // If only implicit\n            // defaults exist, have a null default trump default primitives. This makes it so if there\n            // is a nullable object and a primitive in a group, the default value will be to null out the\n            // object.\n            if (defaultAttribute == null || hasExplicitDefault(attribute) ||\n                attribute.hasSetNullability()\n            ) {\n                defaultAttribute = attribute\n            }\n        }\n        val group = AttributeGroup(groupName, attributes, defaultAttribute)\n        attributeGroups.add(group)\n        attributes.forEach {\n            attributeToGroup[it] = group\n        }\n    }\n\n    /**\n     * If this attribute is in a group, returns the other attributes contained in that group.\n     */\n    fun otherAttributesInGroup(attribute: AttributeInfo): List<AttributeInfo> {\n        return attributeToGroup[attribute]\n            ?.attributes\n            ?.minus(attribute)\n            ?: emptyList()\n    }\n\n    fun isOverload(attribute: AttributeInfo): Boolean {\n        return attributeToGroup[attribute]?.attributes?.let { it.size > 1 } == true\n    }\n\n    fun attributeGroup(attribute: AttributeInfo): AttributeGroup? {\n        return attributeToGroup[attribute]\n    }\n\n    class AttributeGroup internal constructor(\n        groupName: String?,\n        attributes: List<AttributeInfo>,\n        defaultAttribute: AttributeInfo?\n    ) {\n        val name: String?\n        val attributes: List<AttributeInfo>\n        val isRequired: Boolean\n        val defaultAttribute: AttributeInfo?\n\n        init {\n            if (attributes.isEmpty()) {\n                throw buildEpoxyException(\"Attributes cannot be empty\")\n            }\n            if (defaultAttribute != null && defaultAttribute.codeToSetDefault.isEmpty &&\n                !hasDefaultKotlinValue(defaultAttribute)\n            ) {\n                throw buildEpoxyException(\"Default attribute has no default code\")\n            }\n            this.defaultAttribute = defaultAttribute\n            isRequired = defaultAttribute == null\n            name = groupName\n            this.attributes =\n                ArrayList(attributes)\n        }\n    }\n\n    companion object {\n        const val RESET_METHOD = \"reset\"\n        const val GENERATED_CLASS_NAME_SUFFIX = \"_\"\n        const val GENERATED_MODEL_SUFFIX = \"Model$GENERATED_CLASS_NAME_SUFFIX\"\n\n        fun buildParamSpecs(params: List<XVariableElement>, memoizer: Memoizer): List<ParameterSpec> {\n            return params.map { it.toParameterSpec(memoizer) }\n        }\n\n        private fun hasDefaultKotlinValue(attribute: AttributeInfo): Boolean {\n            return (attribute as? ViewAttributeInfo)?.hasDefaultKotlinValue == true\n        }\n\n        private fun hasExplicitDefault(attribute: AttributeInfo): Boolean {\n            if (attribute.codeToSetDefault.explicit != null) {\n                return true\n            }\n\n            return (attribute as? ViewAttributeInfo)?.hasDefaultKotlinValue == true\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/GeneratedModelWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.annotation.LayoutRes\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XFiler\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.addOriginatingElement\nimport androidx.room.compiler.processing.writeTo\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.processor.ClassNames.ANDROID_ASYNC_TASK\nimport com.airbnb.epoxy.processor.ClassNames.EPOXY_MODEL_PROPERTIES\nimport com.airbnb.epoxy.processor.ClassNames.PARIS_STYLE\nimport com.airbnb.epoxy.processor.Utils.implementsMethod\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceValue\nimport com.squareup.javapoet.ArrayTypeName\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.FieldSpec\nimport com.squareup.javapoet.JavaFile\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.MethodSpec.Builder\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeName.BOOLEAN\nimport com.squareup.javapoet.TypeName.BYTE\nimport com.squareup.javapoet.TypeName.CHAR\nimport com.squareup.javapoet.TypeName.DOUBLE\nimport com.squareup.javapoet.TypeName.FLOAT\nimport com.squareup.javapoet.TypeName.INT\nimport com.squareup.javapoet.TypeName.LONG\nimport com.squareup.javapoet.TypeName.SHORT\nimport com.squareup.javapoet.TypeSpec\nimport java.lang.annotation.AnnotationTypeMismatchException\nimport java.lang.ref.WeakReference\nimport java.util.ArrayList\nimport java.util.Arrays\nimport java.util.BitSet\nimport java.util.Objects\nimport javax.lang.model.element.Modifier\nimport javax.lang.model.element.Modifier.FINAL\nimport javax.lang.model.element.Modifier.PRIVATE\nimport javax.lang.model.element.Modifier.PROTECTED\nimport javax.lang.model.element.Modifier.PUBLIC\nimport javax.lang.model.element.Modifier.STATIC\n\nclass GeneratedModelWriter(\n    private val filer: XFiler,\n    private val environment: XProcessingEnv,\n    private val logger: Logger,\n    private val resourceProcessor: ResourceScanner,\n    private val configManager: ConfigManager,\n    private val dataBindingModuleLookup: DataBindingModuleLookup,\n    asyncable: Asyncable,\n    private val memoizer: Memoizer\n) {\n\n    val modelInterfaceWriter =\n        ModelBuilderInterfaceWriter(filer, environment, asyncable, configManager)\n\n    open class BuilderHooks {\n        open fun beforeFinalBuild(builder: TypeSpec.Builder) {}\n\n        /** Opportunity to add additional code to the unbind method.  */\n        open fun addToUnbindMethod(\n            unbindBuilder: Builder,\n            unbindParamName: String\n        ) {\n        }\n\n        /** Opportunity to add additional code to the visibilityStateChanged method.  */\n        open fun addToVisibilityStateChangedMethod(\n            visibilityBuilder: Builder,\n            visibilityParamName: String\n        ) {\n        }\n\n        /** Opportunity to add additional code to the visibilityChanged method.  */\n        open fun addToVisibilityChangedMethod(\n            visibilityBuilder: MethodSpec.Builder,\n            visibilityParamName: String\n        ) {\n        }\n\n        /**\n         * True true to have the bind method build, false to not add the method to the generated\n         * class.\n         */\n        open fun addToBindMethod(\n            methodBuilder: Builder,\n            boundObjectParam: ParameterSpec\n        ) {\n        }\n\n        /**\n         * True true to have the bind method build, false to not add the method to the generated class.\n         */\n        open fun addToBindWithDiffMethod(\n            methodBuilder: Builder,\n            boundObjectParam: ParameterSpec,\n            previousModelParam: ParameterSpec\n        ) {\n        }\n\n        open fun addToHandlePostBindMethod(\n            postBindBuilder: Builder,\n            boundObjectParam: ParameterSpec\n        ) {\n        }\n    }\n\n    fun writeFilesForViewInterfaces() {\n        modelInterfaceWriter.writeFilesForViewInterfaces()\n    }\n\n    fun generateClassForModel(\n        info: GeneratedModelInfo,\n        originatingElements: List<XElement>,\n        builderHooks: BuilderHooks? = null\n    ) {\n        if (!info.shouldGenerateModel) {\n            return\n        }\n\n        val generatedModelName = info.generatedName\n\n        val modelClass = buildClass(generatedModelName) {\n            addJavadoc(\"Generated file. Do not modify!\")\n            addModifiers(PUBLIC)\n            superclass(info.superClassName)\n            addSuperinterface(getGeneratedModelInterface(info))\n            addTypeVariables(info.typeVariables)\n            addAnnotations(info.annotations)\n            addFields(buildStyleConstant(info))\n            addFields(generateFields(info))\n            addMethods(generateConstructors(info))\n\n            generateDebugAddToMethodIfNeeded(this, info)\n\n            addMethods(generateProgrammaticViewMethods(info))\n            addMethods(generateBindMethods(builderHooks, info))\n            addMethods(generateVisibilityMethods(builderHooks, info))\n            addMethods(generateStyleableViewMethods(info))\n            addMethods(generateSettersAndGetters(info))\n            addMethods(generateMethodsReturningClassType(info))\n            addMethods(generateDefaultMethodImplementations(info))\n            addMethods(generateOtherLayoutOptions(info))\n            addMethods(generateDataBindingMethodsIfNeeded(info))\n            if (!configManager.disableGenerateReset(info)) {\n                addMethod(generateReset(info))\n            }\n            addMethod(generateEquals(info))\n            addMethod(generateHashCode(info))\n            addMethod(generateToString(info))\n\n            addFromPropertiesMethodIfNeeded(this, info)\n\n            builderHooks?.beforeFinalBuild(this)\n\n            addSuperinterface(modelInterfaceWriter.writeInterface(info, this.build().methodSpecs, memoizer))\n\n            originatingElements.forEach {\n                addOriginatingElement(it)\n            }\n        }\n\n        JavaFile.builder(generatedModelName.packageName(), modelClass)\n            .build()\n            .writeTo(filer, mode = XFiler.Mode.Aggregating)\n    }\n\n    private fun generateOtherLayoutOptions(info: GeneratedModelInfo): Iterable<MethodSpec> {\n        if (!info.includeOtherLayoutOptions || info.isProgrammaticView) {\n            // Layout resources can't be mixed with programmatic views\n            return emptyList()\n        }\n\n        val result = ArrayList<MethodSpec>()\n        val layout = getDefaultLayoutResource(info)\n        if (layout?.qualified != true) {\n            return emptyList()\n        }\n\n        val defaultLayoutNameLength = layout.resourceName!!.length\n\n        for (otherLayout in resourceProcessor.getAlternateLayouts(layout)) {\n            if (!otherLayout.qualified) {\n                continue\n            }\n\n            var layoutDescription = \"\"\n            for (\n                namePart in otherLayout.resourceName!!.substring(defaultLayoutNameLength).split(\n                    \"_\".toRegex()\n                ).dropLastWhile { it.isEmpty() }\n            ) {\n                layoutDescription += Utils.capitalizeFirstLetter(namePart)\n            }\n\n            result.add(\n                buildMethod(\"with\" + layoutDescription + \"Layout\") {\n                    returns(info.parameterizedGeneratedName)\n                    addModifiers(PUBLIC)\n                    addStatement(\"layout(\\$L)\", otherLayout.code)\n                    addStatement(\"return this\")\n                }\n            )\n        }\n\n        return result\n    }\n\n    private fun getGeneratedModelInterface(info: GeneratedModelInfo): ParameterizedTypeName {\n        return ParameterizedTypeName.get(\n            ClassNames.EPOXY_GENERATED_MODEL_INTERFACE,\n            info.modelType\n        )\n    }\n\n    private fun buildStyleConstant(info: GeneratedModelInfo): Iterable<FieldSpec> {\n\n        val styleBuilderInfo = info.styleBuilderInfo ?: return emptyList()\n\n        val constantFields = ArrayList<FieldSpec>()\n\n        // If this is a styleable view we add a constant to store the default style builder.\n        // This is an optimization to avoid recreating the default style many times, since it is\n        // likely often needed at runtime.\n        constantFields.add(\n            buildField(ClassNames.PARIS_STYLE, PARIS_DEFAULT_STYLE_CONSTANT_NAME) {\n                addModifiers(FINAL, PRIVATE, STATIC)\n                initializer(\n                    \"new \\$T().addDefault().build()\",\n                    styleBuilderInfo.styleBuilderClass\n                )\n            }\n        )\n\n        // We store styles in a weak reference since if a controller uses it\n        // once it is likely to be used in other models and when models are rebuilt\n        for ((name) in styleBuilderInfo.styles) {\n            constantFields.add(\n                FieldSpec.builder(\n                    ParameterizedTypeName.get(\n                        ClassName.get(WeakReference::class.java),\n                        ClassNames.PARIS_STYLE\n                    ),\n                    weakReferenceFieldForStyle(name),\n                    PRIVATE, STATIC\n                )\n                    .build()\n            )\n        }\n\n        return constantFields\n    }\n\n    private fun generateFields(classInfo: GeneratedModelInfo): Iterable<FieldSpec> {\n        val fields = ArrayList<FieldSpec>()\n\n        // bit set for tracking what attributes were set\n        if (shouldUseBitSet(classInfo)) {\n            fields.add(\n                buildField(BitSet::class.className(), ATTRIBUTES_BITSET_FIELD_NAME) {\n                    addModifiers(Modifier.PRIVATE, Modifier.FINAL)\n                    initializer(\n                        \"new \\$T(\\$L)\", BitSet::class.java,\n                        classInfo.attributeInfo.size\n                    )\n                }\n            )\n        }\n\n        // Add fields for the bind/unbind listeners\n        val onBindListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_BIND_MODEL_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n        fields.add(\n            FieldSpec.builder(\n                onBindListenerType, modelBindListenerFieldName(),\n                PRIVATE\n            ).build()\n        )\n\n        val onUnbindListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_UNBIND_MODEL_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n        fields.add(\n            FieldSpec.builder(\n                onUnbindListenerType, modelUnbindListenerFieldName(),\n                PRIVATE\n            ).build()\n        )\n\n        val onVisibilityStateChangedListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_VISIBILITY_STATE_MODEL_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n        fields.add(\n            FieldSpec.builder(\n                onVisibilityStateChangedListenerType,\n                modelVisibilityStateChangedListenerFieldName(),\n                PRIVATE\n            ).build()\n        )\n\n        val onVisibilityChangedListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_VISIBILITY_MODEL_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n        fields.add(\n            FieldSpec.builder(\n                onVisibilityChangedListenerType, modelVisibilityChangedListenerFieldName(),\n                PRIVATE\n            ).build()\n        )\n\n        classInfo.attributeInfo\n            .filter { it.isGenerated }\n            .mapTo(fields) { attributeInfo ->\n                buildField(attributeInfo.typeName, attributeInfo.fieldName) {\n                    addModifiers(PRIVATE)\n                    addAnnotations(attributeInfo.setterAnnotations)\n\n                    if (shouldUseBitSet(classInfo, attr = attributeInfo)) {\n                        addJavadoc(\"Bitset index: \\$L\", attributeIndex(classInfo, attributeInfo))\n                    }\n\n                    if (attributeInfo.codeToSetDefault.isPresent) {\n                        initializer(attributeInfo.codeToSetDefault.value())\n                    }\n                }\n            }\n\n        return fields\n    }\n\n    private fun modelUnbindListenerFieldName(): String =\n        \"onModelUnboundListener$GENERATED_FIELD_SUFFIX\"\n\n    private fun modelBindListenerFieldName(): String =\n        \"onModelBoundListener$GENERATED_FIELD_SUFFIX\"\n\n    private fun modelVisibilityStateChangedListenerFieldName(): String =\n        \"onModelVisibilityStateChangedListener$GENERATED_FIELD_SUFFIX\"\n\n    private fun modelVisibilityChangedListenerFieldName(): String =\n        \"onModelVisibilityChangedListener$GENERATED_FIELD_SUFFIX\"\n\n    private fun getModelClickListenerType(classInfo: GeneratedModelInfo): ParameterizedTypeName {\n        return ParameterizedTypeName.get(\n            ClassNames.EPOXY_MODEL_CLICK_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n    }\n\n    private fun getModelLongClickListenerType(\n        classInfo: GeneratedModelInfo\n    ): ParameterizedTypeName {\n        return ParameterizedTypeName.get(\n            ClassNames.EPOXY_MODEL_LONG_CLICK_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n    }\n\n    private fun getModelCheckedChangeListenerType(\n        classInfo: GeneratedModelInfo\n    ): ParameterizedTypeName {\n        return ParameterizedTypeName.get(\n            ClassNames.EPOXY_MODEL_CHECKED_CHANGE_LISTENER,\n            classInfo.parameterizedGeneratedName,\n            classInfo.modelType\n        )\n    }\n\n    /** Include any constructors that are in the super class.  */\n    private fun generateConstructors(info: GeneratedModelInfo): Iterable<MethodSpec> {\n        return info.constructors.map {\n            buildConstructor {\n                // Final is not allowed on java constructors, but ksp can add it, so we remove it\n                addModifiers(it.modifiers.minus(FINAL))\n                addParameters(it.params)\n                varargs(it.varargs)\n\n                val statementBuilder = StringBuilder(\"super(\")\n                generateParams(statementBuilder, it.params)\n                addStatement(statementBuilder.toString())\n            }\n        }\n    }\n\n    private fun generateDebugAddToMethodIfNeeded(\n        classBuilder: TypeSpec.Builder,\n        info: GeneratedModelInfo\n    ) {\n        if (!configManager.shouldValidateModelUsage()) {\n            return\n        }\n\n        classBuilder.addMethod(\"addTo\") {\n            addParameter(ClassNames.EPOXY_CONTROLLER, \"controller\")\n            addAnnotation(Override::class.java)\n            addModifiers(PUBLIC)\n            addStatement(\"super.addTo(controller)\")\n            addStatement(\"addWithDebugValidation(controller)\")\n\n            // If no group default exists, and no attribute in group is set, throw an exception\n            info.attributeGroups\n                .filter { it.isRequired }\n                .forEach { attributeGroup ->\n\n                    addCode(\"if (\")\n                    attributeGroup.attributes.forEachIndexed { index, attribute ->\n                        if (index != 0) {\n                            addCode(\" && \")\n                        }\n\n                        addCode(\"!\\$L\", isAttributeSetCode(info, attribute))\n                    }\n\n                    addCode(\") {\\n\")\n                    addStatement(\n                        \"\\tthrow new \\$T(\\\"A value is required for \\$L\\\")\",\n                        IllegalStateException::class.java,\n                        attributeGroup.name\n                    )\n                    addCode(\"}\\n\")\n                }\n        }\n    }\n\n    private fun generateProgrammaticViewMethods(\n        modelInfo: GeneratedModelInfo\n    ): Iterable<MethodSpec> {\n\n        if (!modelInfo.isProgrammaticView) {\n            return emptyList()\n        }\n\n        val methods = ArrayList<MethodSpec>()\n\n        // getViewType method so that view type is generated at runtime\n        methods.add(\n            buildMethod(\"getViewType\") {\n                addAnnotation(Override::class.java)\n                addModifiers(PROTECTED)\n                returns(TypeName.INT)\n                addStatement(\"return 0\", modelInfo.modelType)\n            }\n        )\n\n        // buildView method to return new view instance\n        methods.add(\n            buildMethod(\"buildView\") {\n                addAnnotation(Override::class.java)\n                addParameter(ClassNames.ANDROID_VIEW_GROUP, \"parent\")\n                addModifiers(PUBLIC)\n                returns(modelInfo.modelType)\n                addStatement(\n                    \"\\$T v = new \\$T(parent.getContext())\", modelInfo.modelType,\n                    modelInfo.modelType\n                )\n\n                getLayoutDimensions(modelInfo)?.let { (layoutWidth, layoutHeight) ->\n                    addStatement(\n                        \"v.setLayoutParams(new \\$T(\\$L, \\$L))\",\n                        ClassNames.ANDROID_MARGIN_LAYOUT_PARAMS, layoutWidth, layoutHeight\n                    )\n                } ?: run {\n                    beginControlFlow(\"if (v.getLayoutParams() == null)\")\n                        .addStatement(\n                            \"throw new \\$T(\\\"Layout params is required to be set for Size.MANUAL\\\")\",\n                            NullPointerException::class.java\n                        )\n                        .endControlFlow()\n                }\n\n                addStatement(\"return v\")\n            }\n        )\n\n        return methods\n    }\n\n    private fun getLayoutDimensions(modelInfo: GeneratedModelInfo): Pair<CodeBlock, CodeBlock>? {\n        val matchParent = CodeBlock.of(\"\\$T.MATCH_PARENT\", ClassNames.ANDROID_MARGIN_LAYOUT_PARAMS)\n        val wrapContent = CodeBlock.of(\"\\$T.WRAP_CONTENT\", ClassNames.ANDROID_MARGIN_LAYOUT_PARAMS)\n\n        // Returns a pair of width to height\n        return when (modelInfo.layoutParams) {\n            ModelView.Size.MANUAL -> null\n            ModelView.Size.WRAP_WIDTH_MATCH_HEIGHT -> wrapContent to matchParent\n            ModelView.Size.MATCH_WIDTH_MATCH_HEIGHT -> matchParent to matchParent\n            // This will be used for Styleable views as the default\n            ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT -> matchParent to wrapContent\n            ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT -> wrapContent to wrapContent\n            else -> wrapContent to wrapContent\n        }\n    }\n\n    private fun generateVisibilityMethods(\n        builderHooks: BuilderHooks?,\n        modelInfo: GeneratedModelInfo\n    ): Iterable<MethodSpec> {\n        val methods = ArrayList<MethodSpec>()\n\n        val visibilityObjectParam =\n            ParameterSpec.builder(modelInfo.modelType, \"object\", FINAL).build()\n\n        methods.add(buildVisibilityStateChangedMethod(builderHooks, visibilityObjectParam))\n\n        val onVisibilityStateChangedListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_VISIBILITY_STATE_MODEL_LISTENER,\n            modelInfo.parameterizedGeneratedName,\n            modelInfo.modelType\n        )\n        val visibilityStateChangedListenerParam =\n            ParameterSpec.builder(onVisibilityStateChangedListenerType, \"listener\").build()\n\n        val onVisibilityStateChanged = MethodSpec.methodBuilder(\"onVisibilityStateChanged\")\n            .addJavadoc(\n                \"Register a listener that will be called when this model visibility state \" +\n                    \"has changed.\\n\" +\n                    \"<p>\\n\" +\n                    \"The listener will contribute to this model's hashCode state per the {@link\\n\" +\n                    \"com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\\n\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n\n        addOnMutationCall(onVisibilityStateChanged)\n            .addParameter(visibilityStateChangedListenerParam)\n            .addStatement(\"this.\\$L = listener\", modelVisibilityStateChangedListenerFieldName())\n            .addStatement(\"return this\")\n\n        methods.add(onVisibilityStateChanged.build())\n\n        methods.add(buildVisibilityChangedMethod(builderHooks, visibilityObjectParam))\n\n        val onVisibilityChangedListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_VISIBILITY_MODEL_LISTENER,\n            modelInfo.parameterizedGeneratedName,\n            modelInfo.modelType\n        )\n        val visibilityChangedListenerParam =\n            ParameterSpec.builder(onVisibilityChangedListenerType, \"listener\").build()\n\n        val onVisibilityChanged = MethodSpec.methodBuilder(\"onVisibilityChanged\")\n            .addJavadoc(\n                \"Register a listener that will be called when this model visibility has \" +\n                    \"changed.\\n\" +\n                    \"<p>\\n\" +\n                    \"The listener will contribute to this model's hashCode state per the {@link\\n\" +\n                    \"com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\\n\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n\n        addOnMutationCall(onVisibilityChanged)\n            .addParameter(visibilityChangedListenerParam)\n            .addStatement(\"this.\\$L = listener\", modelVisibilityChangedListenerFieldName())\n            .addStatement(\"return this\")\n\n        methods.add(onVisibilityChanged.build())\n\n        return methods\n    }\n\n    private fun generateBindMethods(\n        builderHooks: BuilderHooks?,\n        modelInfo: GeneratedModelInfo\n    ): Iterable<MethodSpec> {\n        val methods = ArrayList<MethodSpec>()\n\n        // Add bind/unbind methods so the class can set the epoxyModelBoundObject and\n        // boundEpoxyViewHolder fields for the model click listener to access\n\n        val viewHolderType = ClassNames.EPOXY_VIEW_HOLDER\n        val viewHolderParam = ParameterSpec.builder(viewHolderType, \"holder\", FINAL).build()\n\n        val boundObjectParam = ParameterSpec.builder(modelInfo.modelType, \"object\", FINAL)\n            .build()\n\n        methods.add(buildPreBindMethod(modelInfo, viewHolderParam, boundObjectParam))\n\n        // If the view is styleable then we need to override bind to apply the style\n        // If builderhooks is nonnull we assume that it is adding code to the bind methods\n        if (builderHooks != null || modelInfo.isStyleable) {\n            methods.add(buildBindMethod(builderHooks, boundObjectParam, modelInfo))\n            methods.add(buildBindWithDiffMethod(builderHooks, modelInfo, boundObjectParam))\n        }\n\n        val postBind = buildMethod(\"handlePostBind\") {\n            addModifiers(PUBLIC)\n            addAnnotation(Override::class.java)\n            addParameter(boundObjectParam)\n            addParameter(TypeName.INT, \"position\")\n\n            if (modelInfo.isSuperClassAlsoGenerated(memoizer)) {\n                // If a super class is also generated we need to make sure to call through to these\n                // methods on it as well. This is particularly important for EpoxyModelGroup.\n                addStatement(\"super.handlePostBind(\\$L, position)\", boundObjectParam.name)\n            }\n\n            beginControlFlow(\"if (\\$L != null)\", modelBindListenerFieldName())\n            addStatement(\n                \"\\$L.onModelBound(this, object, position)\",\n                modelBindListenerFieldName()\n            )\n            endControlFlow()\n\n            addHashCodeValidationIfNecessary(\n                this,\n                \"The model was changed during the bind call.\"\n            )\n\n            builderHooks?.addToHandlePostBindMethod(this, boundObjectParam)\n        }\n\n        methods.add(postBind)\n\n        val onBindListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_BIND_MODEL_LISTENER,\n            modelInfo.parameterizedGeneratedName,\n            modelInfo.modelType\n        )\n        val bindListenerParam = ParameterSpec.builder(onBindListenerType, \"listener\").build()\n\n        val onBind = MethodSpec.methodBuilder(\"onBind\")\n            .addJavadoc(\n                \"Register a listener that will be called when this model is bound to a view.\\n\" +\n                    \"<p>\\n\" +\n                    \"The listener will contribute to this model's hashCode state per the {@link\\n\" +\n                    \"com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\\n\" +\n                    \"<p>\\n\" +\n                    \"You may clear the listener by setting a null value, or by calling \" +\n                    \"{@link #reset()}\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n            .addParameter(bindListenerParam)\n\n        addOnMutationCall(onBind)\n            .addStatement(\"this.\\$L = listener\", modelBindListenerFieldName())\n            .addStatement(\"return this\")\n            .build()\n\n        methods.add(onBind.build())\n\n        val unbindParamName = \"object\"\n        val unbindObjectParam = ParameterSpec.builder(modelInfo.modelType, unbindParamName).build()\n\n        val unbindBuilder = MethodSpec.methodBuilder(\"unbind\")\n            .addAnnotation(Override::class.java)\n            .addModifiers(PUBLIC)\n            .addParameter(unbindObjectParam)\n\n        unbindBuilder\n            .addStatement(\"super.unbind(object)\")\n            .beginControlFlow(\"if (\\$L != null)\", modelUnbindListenerFieldName())\n            .addStatement(\"\\$L.onModelUnbound(this, object)\", modelUnbindListenerFieldName())\n            .endControlFlow()\n\n        builderHooks?.addToUnbindMethod(unbindBuilder, unbindParamName)\n\n        methods.add(\n            unbindBuilder\n                .build()\n        )\n\n        val onUnbindListenerType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_ON_UNBIND_MODEL_LISTENER,\n            modelInfo.parameterizedGeneratedName,\n            modelInfo.modelType\n        )\n        val unbindListenerParam = ParameterSpec.builder(onUnbindListenerType, \"listener\")\n            .build()\n\n        val onUnbind = MethodSpec.methodBuilder(\"onUnbind\")\n            .addJavadoc(\n                \"Register a listener that will be called when this model is unbound from a \" +\n                    \"view.\\n\" +\n                    \"<p>\\n\" +\n                    \"The listener will contribute to this model's hashCode state per the {@link\\n\" +\n                    \"com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\\n\" +\n                    \"<p>\\n\" +\n                    \"You may clear the listener by setting a null value, or by calling \" +\n                    \"{@link #reset()}\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n\n        addOnMutationCall(onUnbind)\n            .addParameter(unbindListenerParam)\n            .addStatement(\"this.\\$L = listener\", modelUnbindListenerFieldName())\n            .addStatement(\"return this\")\n\n        methods.add(onUnbind.build())\n\n        return methods\n    }\n\n    private fun buildBindMethod(\n        builderHooks: BuilderHooks?,\n        boundObjectParam: ParameterSpec,\n        modelInfo: GeneratedModelInfo\n    ) = buildMethod(\"bind\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        addParameter(boundObjectParam)\n\n        // The style is applied before calling super or binding properties so that the model can\n        // override style settings\n        addBindStyleCodeIfNeeded(\n            modelInfo,\n            this,\n            boundObjectParam,\n            false\n        )\n\n        addStatement(\"super.bind(\\$L)\", boundObjectParam.name)\n\n        builderHooks?.addToBindMethod(this, boundObjectParam)\n    }\n\n    private fun buildVisibilityStateChangedMethod(\n        builderHooks: BuilderHooks?,\n        visibilityObjectParam: ParameterSpec\n    ) = buildMethod(\"onVisibilityStateChanged\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        addParameter(TypeName.INT, \"visibilityState\")\n        addParameter(visibilityObjectParam)\n\n        beginControlFlow(\"if (\\$L != null)\", modelVisibilityStateChangedListenerFieldName())\n        addStatement(\n            \"\\$L.onVisibilityStateChanged(this, object, visibilityState)\",\n            modelVisibilityStateChangedListenerFieldName()\n        )\n        endControlFlow()\n\n        builderHooks?.addToVisibilityStateChangedMethod(\n            this,\n            visibilityObjectParam.name\n        )\n\n        addStatement(\n            \"super.onVisibilityStateChanged(\\$L, \\$L)\",\n            \"visibilityState\",\n            visibilityObjectParam.name\n        )\n    }\n\n    private fun buildVisibilityChangedMethod(\n        builderHooks: BuilderHooks?,\n        visibilityObjectParam: ParameterSpec\n    ) = buildMethod(\"onVisibilityChanged\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        addParameter(TypeName.FLOAT, \"percentVisibleHeight\")\n        addParameter(TypeName.FLOAT, \"percentVisibleWidth\")\n        addParameter(TypeName.INT, \"visibleHeight\")\n        addParameter(TypeName.INT, \"visibleWidth\")\n        addParameter(visibilityObjectParam)\n\n        beginControlFlow(\"if (\\$L != null)\", modelVisibilityChangedListenerFieldName())\n        addStatement(\n            \"\\$L.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, \" +\n                \"visibleHeight, visibleWidth)\",\n            modelVisibilityChangedListenerFieldName()\n        )\n        endControlFlow()\n\n        builderHooks?.addToVisibilityChangedMethod(this, visibilityObjectParam.name)\n\n        addStatement(\n            \"super.onVisibilityChanged(\\$L, \\$L, \\$L, \\$L, \\$L)\", \"percentVisibleHeight\",\n            \"percentVisibleWidth\", \"visibleHeight\", \"visibleWidth\", visibilityObjectParam.name\n        )\n    }\n\n    private fun buildBindWithDiffMethod(\n        builderHooks: BuilderHooks?,\n        classInfo: GeneratedModelInfo,\n        boundObjectParam: ParameterSpec\n    ) = buildMethod(\"bind\") {\n\n        val previousModelParam = ParameterSpec.builder(\n            ClassNames.EPOXY_MODEL_UNTYPED,\n            \"previousModel\"\n        ).build()\n\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        addParameter(boundObjectParam)\n        addParameter(previousModelParam)\n\n        val generatedModelClass = classInfo.generatedName\n        beginControlFlow(\n            \"if (!(\\$L instanceof \\$T))\",\n            previousModelParam.name,\n            generatedModelClass\n        )\n        addStatement(\"bind(\\$L)\", boundObjectParam.name)\n        addStatement(\"return\")\n        endControlFlow()\n        addStatement(\n            \"\\$T that = (\\$T) previousModel\",\n            generatedModelClass,\n            generatedModelClass\n        )\n\n        addBindStyleCodeIfNeeded(\n            classInfo,\n            this,\n            boundObjectParam,\n            true\n        )\n\n        // We want to make sure the base model has its bind method called as well. Since the\n        // user can provide a custom base class we aren't sure if it implements diff binding.\n        // If so we should call it, but if not, calling it would invoke the default\n        // EpoxyModel implementation which calls normal \"bind\". Doing that would force a full\n        // bind!!! So we mustn't do that. So, we only call the super diff binding if we think\n        // it's a custom implementation.\n        if (modelImplementsBindWithDiff(\n                classInfo.safeSuperClassElement(memoizer),\n                memoizer\n            )\n        ) {\n            addStatement(\n                \"super.bind(\\$L, \\$L)\",\n                boundObjectParam.name,\n                previousModelParam.name\n            )\n        } else {\n            addStatement(\"super.bind(\\$L)\", boundObjectParam.name)\n        }\n\n        builderHooks?.addToBindWithDiffMethod(\n            this,\n            boundObjectParam,\n            previousModelParam\n        )\n    }\n\n    private fun buildPreBindMethod(\n        modelInfo: GeneratedModelInfo,\n        viewHolderParam: ParameterSpec,\n        boundObjectParam: ParameterSpec\n    ): MethodSpec {\n\n        val positionParamName = \"position\"\n        val preBindBuilder = MethodSpec.methodBuilder(\"handlePreBind\")\n            .addModifiers(PUBLIC)\n            .addAnnotation(Override::class.java)\n            .addParameter(viewHolderParam)\n            .addParameter(boundObjectParam)\n            .addParameter(TypeName.INT, positionParamName, Modifier.FINAL)\n\n        if (modelInfo.isSuperClassAlsoGenerated(memoizer)) {\n            // If a super class is also generated we need to make sure to call through to these\n            // methods on it as well. This is particularly important for EpoxyModelGroup.\n            preBindBuilder.addStatement(\n                \"super.handlePreBind(\\$L, \\$L, \\$L)\",\n                viewHolderParam.name,\n                boundObjectParam.name,\n                positionParamName\n            )\n        }\n\n        addHashCodeValidationIfNecessary(\n            preBindBuilder,\n            \"The model was changed between being added to the controller and being bound.\"\n        )\n\n        if (modelInfo.isStyleable && configManager.shouldValidateModelUsage()) {\n\n            // We validate that the style attributes are the same as in the default, otherwise\n            // recycling will not work correctly. It is done in the background since it is fairly\n            // slow and can noticeably add jank to scrolling in dev\n            preBindBuilder\n                .beginControlFlow(\n                    \"if (!\\$T.equals(\\$L, \\$L.getTag(\\$T.id.epoxy_saved_view_style)))\",\n                    Objects::class.java,\n                    PARIS_STYLE_ATTR_NAME,\n                    boundObjectParam.name,\n                    ClassNames.EPOXY_R\n                )\n                .beginControlFlow(\n                    \"\\$T.THREAD_POOL_EXECUTOR.execute(new \\$T()\",\n                    ANDROID_ASYNC_TASK,\n                    Runnable::class.java\n                )\n                .beginControlFlow(\"public void run()\")\n                .beginControlFlow(\"try\")\n                .addStatement(\n                    \"\\$T.assertSameAttributes(new \\$T(\\$L), \\$L, \\$L)\",\n                    ClassNames.PARIS_STYLE_UTILS,\n                    modelInfo.styleBuilderInfo!!.styleApplierClass,\n                    boundObjectParam.name,\n                    PARIS_STYLE_ATTR_NAME,\n                    PARIS_DEFAULT_STYLE_CONSTANT_NAME\n                )\n                .endControlFlow()\n                .beginControlFlow(\"catch(\\$T e)\", AssertionError::class.java)\n                .addStatement(\n                    \"throw new \\$T(\\\"\\$L model at position \\\" + \\$L + \\\" has an invalid \" +\n                        \"style:\\\\n\\\\n\\\" + e\" + \".getMessage())\",\n                    IllegalStateException::class.java,\n                    modelInfo.generatedName.simpleName(),\n                    positionParamName\n                )\n                .endControlFlow()\n                .endControlFlow()\n                .endControlFlow(\")\")\n                .endControlFlow()\n        }\n\n        return preBindBuilder.build()\n    }\n\n    private fun generateStyleableViewMethods(modelInfo: GeneratedModelInfo): Iterable<MethodSpec> {\n        val styleBuilderInfo = modelInfo.styleBuilderInfo ?: return emptyList()\n\n        val methods = ArrayList<MethodSpec>()\n        val styleType = styleBuilderInfo.typeName\n        val styleBuilderClass = styleBuilderInfo.styleBuilderClass\n\n        // setter for style object\n        val builder = MethodSpec.methodBuilder(PARIS_STYLE_ATTR_NAME)\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n            .addParameter(styleType, PARIS_STYLE_ATTR_NAME)\n\n        setBitSetIfNeeded(modelInfo, styleBuilderInfo, builder)\n        addOnMutationCall(builder)\n            .addStatement(styleBuilderInfo.setterCode(), PARIS_STYLE_ATTR_NAME)\n\n        methods.add(\n            builder\n                .addStatement(\"return this\")\n                .build()\n        )\n\n        // Lambda for building the style\n        val parameterizedBuilderCallbackType = ParameterizedTypeName.get(\n            ClassNames.EPOXY_STYLE_BUILDER_CALLBACK, styleBuilderClass\n        )\n\n        methods.add(\n            MethodSpec.methodBuilder(\"styleBuilder\")\n                .addModifiers(PUBLIC)\n                .returns(modelInfo.parameterizedGeneratedName)\n                .addParameter(parameterizedBuilderCallbackType, \"builderCallback\")\n                .addStatement(\n                    \"\\$T builder = new \\$T()\",\n                    styleBuilderClass,\n                    styleBuilderClass\n                )\n                .addStatement(\"builderCallback.buildStyle(builder.addDefault())\")\n                .addStatement(\"return \\$L(builder.build())\", PARIS_STYLE_ATTR_NAME)\n                .build()\n        )\n\n        // Methods for setting each defined style directly\n        for ((name, javadoc) in styleBuilderInfo.styles) {\n            val capitalizedStyle = Utils.capitalizeFirstLetter(name)\n            val methodName = \"with\" + capitalizedStyle + \"Style\"\n            val fieldName = weakReferenceFieldForStyle(name)\n\n            // The style is stored in a static weak reference since it is likely to be reused in\n            // other models are when models are rebuilt.\n            val styleMethodBuilder = MethodSpec.methodBuilder(methodName)\n\n            if (javadoc != null) {\n                styleMethodBuilder.addJavadoc(javadoc)\n            }\n\n            methods.add(\n                styleMethodBuilder\n                    .addModifiers(PUBLIC)\n                    .returns(modelInfo.parameterizedGeneratedName)\n                    .addStatement(\n                        \"\\$T style = \\$L != null ? \\$L.get() : null\",\n                        ClassNames.PARIS_STYLE,\n                        fieldName, fieldName\n                    )\n                    .beginControlFlow(\"if (style == null)\")\n                    .addStatement(\n                        \"style =  new \\$T().add\\$L().build()\",\n                        styleBuilderClass, capitalizedStyle\n                    )\n                    .addStatement(\n                        \"\\$L = new \\$T<>(style)\", fieldName,\n                        WeakReference::class.java\n                    )\n                    .endControlFlow()\n                    .addStatement(\"return \\$L(style)\", PARIS_STYLE_ATTR_NAME)\n                    .build()\n            )\n        }\n\n        return methods\n    }\n\n    private fun generateMethodsReturningClassType(info: GeneratedModelInfo): Iterable<MethodSpec> {\n        return info.methodsReturningClassType.mapNotNull { methodInfo ->\n\n            val builder = MethodSpec.methodBuilder(methodInfo.name)\n                .addModifiers(methodInfo.modifiers)\n                .addParameters(methodInfo.params)\n                .addAnnotation(Override::class.java)\n                .varargs(methodInfo.varargs)\n                .returns(info.parameterizedGeneratedName)\n\n            val isLayoutUnsupportedOverload = info.isProgrammaticView &&\n                \"layout\" == methodInfo.name &&\n                methodInfo.params.size == 1 &&\n                methodInfo.params[0].type === TypeName.INT\n\n            if (isLayoutUnsupportedOverload) {\n                builder.addStatement(\n                    \"throw new \\$T(\\\"Layout resources are unsupported with programmatic \" +\n                        \"views.\\\")\",\n                    UnsupportedOperationException::class.java\n                )\n            } else {\n\n                val statementBuilder = StringBuilder(\n                    String.format(\n                        \"super.%s(\",\n                        methodInfo.name\n                    )\n                )\n                generateParams(statementBuilder, methodInfo.params)\n\n                builder\n                    .addStatement(statementBuilder.toString())\n                    .addStatement(\"return this\")\n            }\n\n            if (configManager.disableGenerateBuilderOverloads(info) && !isLayoutUnsupportedOverload) {\n                // We want to keep the layout overload when it is throwing an UnsupportedOperationException\n                // because that actually adds new behavior. All other overloads simply call super\n                // and return \"this\", which can be disabled when builder chaining is not needed\n                // (ie with kotlin).\n                null\n            } else {\n                builder.build()\n            }\n        }\n    }\n\n    /**\n     * Generates default implementations of certain model methods if the model is abstract and\n     * doesn't implement them.\n     */\n    private fun generateDefaultMethodImplementations(\n        info: GeneratedModelInfo\n    ): Iterable<MethodSpec> {\n        val methods = ArrayList<MethodSpec>()\n\n        if (info.isProgrammaticView) {\n            methods.add(\n                buildDefaultLayoutMethodBase()\n                    .toBuilder()\n                    .addStatement(\n                        \"throw new \\$T(\\\"Layout resources are unsupported for views created \" +\n                            \"programmatically\" + \".\\\")\",\n                        UnsupportedOperationException::class.java\n                    )\n                    .build()\n            )\n        } else {\n            addCreateHolderMethodIfNeeded(info, methods)\n            addDefaultLayoutMethodIfNeeded(info, methods)\n        }\n\n        return methods\n    }\n\n    /**\n     * If the model is a holder and doesn't implement the \"createNewHolder\" method we can generate a\n     * default implementation by getting the class type and creating a new instance of it.\n     *\n     * If the holder class have a constructor that accept the parent it will invoke it.\n     */\n    private fun addCreateHolderMethodIfNeeded(\n        modelClassInfo: GeneratedModelInfo,\n        methods: MutableList<MethodSpec>\n    ) {\n\n        val originalClassElement = modelClassInfo.safeSuperClassElement(memoizer)\n        if (!originalClassElement.type.isEpoxyModelWithHolder(memoizer)) {\n            return\n        }\n\n        var createHolderMethod = MethodSpec.methodBuilder(\n            CREATE_NEW_HOLDER_METHOD_NAME\n        )\n            .addAnnotation(Override::class.java)\n            .addModifiers(Modifier.PROTECTED)\n            .addParameter(\n                ClassName.get(\"android.view\", \"ViewParent\"),\n                \"parent\"\n            )\n            .build()\n\n        if (implementsMethod(originalClassElement, createHolderMethod, environment)) {\n            return\n        }\n\n        createHolderMethod = with(createHolderMethod.toBuilder()) {\n            returns(modelClassInfo.modelType)\n            val modelTypeElement = modelClassInfo.modelType?.let { environment.findTypeElement(it.toString()) }\n            if (modelTypeElement != null &&\n                modelClassInfo.memoizer.hasViewParentConstructor(modelTypeElement)\n            ) {\n                addStatement(\"return new \\$T(parent)\", modelClassInfo.modelType)\n            } else {\n                addStatement(\"return new \\$T()\", modelClassInfo.modelType)\n            }\n            build()\n        }\n\n        methods.add(createHolderMethod)\n    }\n\n    /**\n     * If there is no existing implementation of getDefaultLayout we can generate an implementation.\n     * This relies on a layout res being set in the @EpoxyModelClass annotation.\n     */\n    private fun addDefaultLayoutMethodIfNeeded(\n        modelInfo: GeneratedModelInfo,\n        methods: MutableList<MethodSpec>\n    ) {\n\n        val layout = getDefaultLayoutResource(modelInfo) ?: return\n\n        methods.add(\n            buildDefaultLayoutMethodBase()\n                .toBuilder()\n                .addStatement(\"return \\$L\", layout.code)\n                .build()\n        )\n    }\n\n    private fun buildDefaultLayoutMethodBase(): MethodSpec {\n        return MethodSpec.methodBuilder(GET_DEFAULT_LAYOUT_METHOD_NAME)\n            .addAnnotation(Override::class.java)\n            .addAnnotation(LayoutRes::class.java)\n            .addModifiers(Modifier.PROTECTED)\n            .returns(TypeName.INT)\n            .build()\n    }\n\n    private fun getDefaultLayoutResource(modelInfo: GeneratedModelInfo): ResourceValue? {\n        // TODO: This is pretty ugly and could be abstracted/decomposed better. We could probably\n        // make a small class to contain this logic, or build it into the model info classes\n\n        if (modelInfo is DataBindingModelInfo) {\n            return modelInfo.layoutResource\n        }\n\n        if (modelInfo is ModelViewInfo) {\n            return modelInfo.getLayoutResource(resourceProcessor)\n        }\n\n        val superClassElement = modelInfo.safeSuperClassElement(memoizer)\n        if (implementsMethod(superClassElement, buildDefaultLayoutMethodBase(), environment)) {\n            return null\n        }\n\n        val modelClassWithAnnotation = findSuperClassWithClassAnnotation(superClassElement)\n        if (modelClassWithAnnotation == null) {\n            logger\n                .logError(\n                    \"Model must use %s annotation if it does not implement %s. (class: %s)\",\n                    EpoxyModelClass::class.java,\n                    GET_DEFAULT_LAYOUT_METHOD_NAME,\n                    modelInfo.superClassName\n                )\n            return null\n        }\n\n        return resourceProcessor\n            .getResourceValue(EpoxyModelClass::class, modelClassWithAnnotation, \"layout\")\n    }\n\n    /**\n     * Add `setDataBindingVariables` for DataBinding models if they haven't implemented it. This\n     * adds the basic method and a method that checks for payload changes and only sets the\n     * variables that changed.\n     */\n    private fun generateDataBindingMethodsIfNeeded(info: GeneratedModelInfo): Iterable<MethodSpec> {\n        if (!info.safeSuperClassElement(memoizer).type.isDataBindingEpoxyModel(memoizer)) {\n            return emptyList()\n        }\n\n        val bindVariablesMethod = MethodSpec.methodBuilder(\"setDataBindingVariables\")\n            .addAnnotation(Override::class.java)\n            .addParameter(\n                ClassName.get(\"androidx.databinding\", \"ViewDataBinding\"),\n                \"binding\"\n            )\n            .addModifiers(Modifier.PROTECTED)\n            .returns(TypeName.VOID)\n            .build()\n\n        // If the base method is already implemented don't bother checking for the payload method\n        if (implementsMethod(\n                info.safeSuperClassElement(memoizer),\n                bindVariablesMethod,\n                environment\n            )\n        ) {\n            return emptyList()\n        }\n\n        val generatedModelClass = info.generatedName\n\n        val moduleName = (info as? DataBindingModelInfo)?.moduleName\n            ?: dataBindingModuleLookup.getModuleName(info.safeSuperClassElement(memoizer))\n\n        val baseMethodBuilder = bindVariablesMethod.toBuilder()\n\n        val payloadMethodBuilder = bindVariablesMethod\n            .toBuilder()\n            .addParameter(ClassNames.EPOXY_MODEL_UNTYPED, \"previousModel\")\n            .beginControlFlow(\n                \"if (!(previousModel instanceof \\$T))\",\n                generatedModelClass\n            )\n            .addStatement(\"setDataBindingVariables(binding)\")\n            .addStatement(\"return\")\n            .endControlFlow()\n            .addStatement(\n                \"\\$T that = (\\$T) previousModel\", generatedModelClass,\n                generatedModelClass\n            )\n\n        val brClass = ClassName.get(moduleName, \"BR\")\n        val validateAttributes = configManager.shouldValidateModelUsage()\n        for (attribute in info.attributeInfo) {\n            val attrName = attribute.fieldName\n            val setVariableBlock = CodeBlock.of(\n                \"binding.setVariable(\\$T.\\$L, \\$L)\", brClass,\n                attrName, attribute.getterCode()\n            )\n\n            if (validateAttributes) {\n                // The setVariable method returns false if the variable id was not found in the\n                // layout. We can warn the user about this if they have model validations turned on,\n                // otherwise it fails silently.\n                baseMethodBuilder\n                    .beginControlFlow(\"if (!\\$L)\", setVariableBlock)\n                    .addStatement(\n                        \"throw new \\$T(\\\"The attribute \\$L was defined in your data binding \" +\n                            \"model (\\$L) but \" + \"a data variable of that name was not found in \" +\n                            \"the layout.\\\")\",\n                        IllegalStateException::class.java, attrName,\n                        info.superClassName\n                    )\n                    .endControlFlow()\n            } else {\n                baseMethodBuilder.addStatement(\"\\$L\", setVariableBlock)\n            }\n\n            // Handle binding variables only if they changed\n            startNotEqualsControlFlow(payloadMethodBuilder, attribute)\n                .addStatement(\"\\$L\", setVariableBlock)\n                .endControlFlow()\n        }\n\n        val methods = ArrayList<MethodSpec>()\n        methods.add(baseMethodBuilder.build())\n        methods.add(payloadMethodBuilder.build())\n        return methods\n    }\n\n    /**\n     * Looks for [EpoxyModelClass] annotation in the original class and his parents.\n     */\n    private fun findSuperClassWithClassAnnotation(classElement: XTypeElement): XTypeElement? {\n        if (!classElement.isEpoxyModel(memoizer)) {\n            return null\n        }\n\n        val annotation = classElement.getAnnotation(EpoxyModelClass::class)\n            // This is an error. The model must have an EpoxyModelClass annotation\n            // since getDefaultLayout is not implemented\n            ?: return null\n\n        val layoutRes: Int\n        try {\n            layoutRes = annotation.getAsInt(\"layout\")\n        } catch (e: AnnotationTypeMismatchException) {\n            logger.logError(\n                \"Invalid layout value in %s annotation. (class: %s). %s: %s\",\n                EpoxyModelClass::class.java,\n                classElement.name,\n                e.javaClass.simpleName,\n                e.message ?: \"\"\n            )\n            return null\n        }\n\n        if (layoutRes != 0) {\n            return classElement\n        }\n\n        // This model did not specify a layout in its EpoxyModelClass annotation,\n        // but its superclass might\n        classElement.superClass?.typeElement\n            ?.let { superClass ->\n                findSuperClassWithClassAnnotation(superClass)\n            }\n            ?.let {\n                return it\n            }\n\n        logger.logError(\n            classElement,\n            \"Model must specify a valid layout resource in the %s annotation. \" +\n                \"(class: %s)\",\n            EpoxyModelClass::class.java.simpleName,\n            classElement.name\n        )\n\n        return null\n    }\n\n    private fun generateParams(\n        statementBuilder: StringBuilder,\n        params: List<ParameterSpec>\n    ) {\n        var first = true\n        for (param in params) {\n            if (!first) {\n                statementBuilder.append(\", \")\n            }\n            first = false\n            statementBuilder.append(param.name)\n        }\n        statementBuilder.append(\")\")\n    }\n\n    private fun generateSettersAndGetters(modelInfo: GeneratedModelInfo): List<MethodSpec> {\n        val methods = ArrayList<MethodSpec>()\n\n        for (attr in modelInfo.attributeInfo) {\n            if (attr is ViewAttributeInfo && attr.generateStringOverloads) {\n                methods.addAll(StringOverloadWriter(modelInfo, attr, configManager).buildMethods())\n            } else {\n                if (attr.isViewClickListener || attr.isViewLongClickListener) {\n                    methods.add(generateSetClickModelListener(modelInfo, attr))\n                }\n\n                if (attr.isViewCheckedChangeListener) {\n                    methods.add(generateSetCheckedChangeModelListener(modelInfo, attr))\n                }\n\n                if (attr.generateSetter && !attr.hasFinalModifier) {\n                    methods.add(generateSetter(modelInfo, attr))\n                }\n\n                if (attr.generateGetter && !configManager.disableGenerateGetters(modelInfo)) {\n                    methods.add(generateGetter(modelInfo, attr))\n                }\n            }\n        }\n\n        return methods\n    }\n\n    private fun generateSetClickModelListener(\n        classInfo: GeneratedModelInfo,\n        attribute: AttributeInfo\n    ): MethodSpec {\n        val attributeName = attribute.generatedSetterName()\n\n        val clickListenerType = if (attribute.isViewLongClickListener)\n            getModelLongClickListenerType(classInfo)\n        else\n            getModelClickListenerType(classInfo)\n\n        val param = ParameterSpec.builder(clickListenerType, attributeName, FINAL)\n            .addAnnotations(attribute.setterAnnotations).build()\n\n        val builder = MethodSpec.methodBuilder(attributeName)\n            .addJavadoc(\n                \"Set a click listener that will provide the parent view, model, and adapter \" +\n                    \"position of the clicked view. This will clear the normal \" +\n                    \"View.OnClickListener if one has been set\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(classInfo.parameterizedGeneratedName)\n            .addParameter(param)\n\n        setBitSetIfNeeded(classInfo, attribute, builder)\n\n        val wrapperClickListenerConstructor = CodeBlock.of(\n            \"new \\$T<>(\\$L)\",\n            ClassNames.EPOXY_WRAPPED_LISTENER,\n            param.name\n        )\n\n        addOnMutationCall(builder)\n            .beginControlFlow(\"if (\\$L == null)\", attributeName)\n            .addStatement(attribute.setterCode(), \"null\")\n            .endControlFlow()\n            .beginControlFlow(\"else\")\n            .addStatement(attribute.setterCode(), wrapperClickListenerConstructor)\n            .endControlFlow()\n            .addStatement(\"return this\")\n\n        return builder.build()\n    }\n\n    private fun generateSetCheckedChangeModelListener(\n        classInfo: GeneratedModelInfo,\n        attribute: AttributeInfo\n    ): MethodSpec {\n        val attributeName = attribute.generatedSetterName()\n        val checkedListenerType = getModelCheckedChangeListenerType(classInfo)\n\n        val param = ParameterSpec.builder(checkedListenerType, attributeName, FINAL)\n            .addAnnotations(attribute.setterAnnotations).build()\n\n        val builder = MethodSpec.methodBuilder(attributeName)\n            .addJavadoc(\n                \"Set a checked change listener that will provide the parent view, model, value, and adapter \" +\n                    \"position of the checked view. This will clear the normal \" +\n                    \"CompoundButton.OnCheckedChangeListener if one has been set\"\n            )\n            .addModifiers(PUBLIC)\n            .returns(classInfo.parameterizedGeneratedName)\n            .addParameter(param)\n\n        setBitSetIfNeeded(classInfo, attribute, builder)\n\n        val wrapperCheckedListenerConstructor = CodeBlock.of(\n            \"new \\$T(\\$L)\",\n            ClassNames.EPOXY_WRAPPED_CHECKED_LISTENER,\n            param.name\n        )\n\n        addOnMutationCall(builder)\n            .beginControlFlow(\"if (\\$L == null)\", attributeName)\n            .addStatement(attribute.setterCode(), \"null\")\n            .endControlFlow()\n            .beginControlFlow(\"else\")\n            .addStatement(attribute.setterCode(), wrapperCheckedListenerConstructor)\n            .endControlFlow()\n            .addStatement(\"return this\")\n\n        return builder.build()\n    }\n\n    private fun generateEquals(helperClass: GeneratedModelInfo) = buildMethod(\"equals\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        returns(Boolean::class.javaPrimitiveType!!)\n        addParameter(Any::class.java, \"o\")\n        beginControlFlow(\"if (o == this)\")\n        addStatement(\"return true\")\n        endControlFlow()\n        beginControlFlow(\"if (!(o instanceof \\$T))\", helperClass.generatedName)\n        addStatement(\"return false\")\n        endControlFlow()\n        beginControlFlow(\"if (!super.equals(o))\")\n        addStatement(\"return false\")\n        endControlFlow()\n        addStatement(\"\\$T that = (\\$T) o\", helperClass.generatedName, helperClass.generatedName)\n\n        startNotEqualsControlFlow(\n            this,\n            false,\n            ClassNames.EPOXY_ON_BIND_MODEL_LISTENER,\n            modelBindListenerFieldName()\n        )\n        addStatement(\"return false\")\n        endControlFlow()\n\n        startNotEqualsControlFlow(\n            this,\n            false,\n            ClassNames.EPOXY_ON_UNBIND_MODEL_LISTENER,\n            modelUnbindListenerFieldName()\n        )\n        addStatement(\"return false\")\n        endControlFlow()\n\n        startNotEqualsControlFlow(\n            this,\n            false,\n            ClassNames.EPOXY_ON_VISIBILITY_STATE_MODEL_LISTENER,\n            modelVisibilityStateChangedListenerFieldName()\n        )\n        addStatement(\"return false\")\n        endControlFlow()\n\n        startNotEqualsControlFlow(\n            this,\n            false,\n            ClassNames.EPOXY_ON_VISIBILITY_MODEL_LISTENER,\n            modelVisibilityChangedListenerFieldName()\n        )\n        addStatement(\"return false\")\n        endControlFlow()\n\n        for (attributeInfo in helperClass.attributeInfo) {\n            val type = attributeInfo.typeName\n\n            if (!attributeInfo.useInHash && type.isPrimitive) {\n                continue\n            }\n\n            startNotEqualsControlFlow(this, attributeInfo)\n            addStatement(\"return false\")\n            endControlFlow()\n        }\n\n        addStatement(\"return true\")\n    }\n\n    private fun generateHashCode(helperClass: GeneratedModelInfo) = buildMethod(\"hashCode\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        returns(TypeName.INT)\n        addStatement(\"int $HASH_CODE_RESULT_PROPERTY = super.hashCode()\")\n\n        addHashCodeLineForType(\n            this,\n            false,\n            ClassNames.EPOXY_ON_BIND_MODEL_LISTENER,\n            modelBindListenerFieldName()\n        )\n\n        addHashCodeLineForType(\n            this,\n            false,\n            ClassNames.EPOXY_ON_UNBIND_MODEL_LISTENER,\n            modelUnbindListenerFieldName()\n        )\n\n        addHashCodeLineForType(\n            this,\n            false,\n            ClassNames.EPOXY_ON_VISIBILITY_STATE_MODEL_LISTENER,\n            modelVisibilityStateChangedListenerFieldName()\n        )\n\n        addHashCodeLineForType(\n            this,\n            false,\n            ClassNames.EPOXY_ON_VISIBILITY_MODEL_LISTENER,\n            modelVisibilityChangedListenerFieldName()\n        )\n\n        for (attributeInfo in helperClass.attributeInfo) {\n            if (!attributeInfo.useInHash) {\n                continue\n            }\n            if (attributeInfo.typeName === DOUBLE) {\n                addStatement(\"long temp\")\n                break\n            }\n        }\n\n        for (attributeInfo in helperClass.attributeInfo) {\n            val type = attributeInfo.typeName\n\n            if (!attributeInfo.useInHash && type.isPrimitive) {\n                continue\n            }\n\n            addHashCodeLineForType(\n                this, attributeInfo.useInHash, type,\n                attributeInfo.getterCode()\n            )\n        }\n\n        addStatement(\"return $HASH_CODE_RESULT_PROPERTY\")\n    }\n\n    private fun generateToString(helperClass: GeneratedModelInfo) = buildMethod(\"toString\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        returns(String::class.java)\n\n        val sb = StringBuilder()\n        sb.append(String.format(\"\\\"%s{\\\" +\\n\", helperClass.generatedName.simpleName()))\n\n        var first = true\n        for (attributeInfo in helperClass.attributeInfo) {\n            if (attributeInfo.doNotUseInToString) {\n                continue\n            }\n\n            val attributeName = attributeInfo.fieldName\n            if (first) {\n                sb.append(\n                    String.format(\n                        \"\\\"%s=\\\" + %s +\\n\", attributeName,\n                        attributeInfo.getterCode()\n                    )\n                )\n                first = false\n            } else {\n                sb.append(\n                    String.format(\n                        \"\\\", %s=\\\" + %s +\\n\", attributeName,\n                        attributeInfo.getterCode()\n                    )\n                )\n            }\n        }\n\n        sb.append(\"\\\"}\\\" + super.toString()\")\n\n        addStatement(\"return \\$L\", sb.toString())\n    }\n\n    private fun generateGetter(modelInfo: GeneratedModelInfo, data: AttributeInfo): MethodSpec {\n        val getterName = data.generatedGetterName(\n            isOverload = modelInfo.isOverload(data)\n        )\n        return buildMethod(getterName) {\n            addModifiers(PUBLIC)\n            returns(data.typeName)\n            addAnnotations(data.getterAnnotations)\n            addStatement(\"return \\$L\", data.superGetterCode())\n        }\n    }\n\n    private fun generateSetter(\n        modelInfo: GeneratedModelInfo,\n        attribute: AttributeInfo\n    ): MethodSpec {\n        val attributeName = attribute.fieldName\n        val paramName = attribute.generatedSetterName()\n        val builder = MethodSpec.methodBuilder(attribute.generatedSetterName())\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n\n        val hasMultipleParams = attribute is MultiParamAttribute\n        if (hasMultipleParams) {\n            builder.addParameters((attribute as MultiParamAttribute).params)\n            builder.varargs((attribute as MultiParamAttribute).varargs())\n        } else {\n            builder.addParameter(\n                ParameterSpec.builder(attribute.typeName, paramName)\n                    .addAnnotations(attribute.setterAnnotations).build()\n            )\n        }\n\n        if (attribute.javaDoc != null) {\n            builder.addJavadoc(attribute.javaDoc)\n        }\n\n        if (!hasMultipleParams) {\n            addParameterNullCheckIfNeeded(configManager, attribute, paramName, builder)\n        }\n\n        setBitSetIfNeeded(modelInfo, attribute, builder)\n\n        modelInfo.otherAttributesInGroup(attribute)\n\n        for (overload in modelInfo.otherAttributesInGroup(attribute)) {\n            if (shouldUseBitSet(modelInfo)) {\n                builder.addStatement(\n                    \"\\$L.clear(\\$L)\", ATTRIBUTES_BITSET_FIELD_NAME,\n                    attributeIndex(modelInfo, overload)\n                )\n            }\n\n            builder.addStatement(\n                overload.setterCode(),\n                if (overload.codeToSetDefault.isPresent)\n                    overload.codeToSetDefault.value()\n                else\n                    Utils.getDefaultValue(overload.typeName)\n            )\n        }\n\n        addOnMutationCall(builder)\n            .addStatement(\n                attribute.setterCode(),\n                if (hasMultipleParams)\n                    (attribute as MultiParamAttribute).valueToSetOnAttribute\n                else\n                    paramName\n            )\n\n        // Call the super setter if it exists.\n        // No need to do this if the attribute is private since we already called the super setter\n        // to set it\n        if (!attribute.isPrivate && attribute.hasSuperSetter) {\n            if (hasMultipleParams) {\n                logger\n                    .logError(\n                        \"Multi params not supported for methods that call super (%s)\",\n                        attribute\n                    )\n            }\n\n            builder.addStatement(\"super.\\$L(\\$L)\", attributeName, paramName)\n        }\n\n        return builder\n            .addStatement(\"return this\")\n            .build()\n    }\n\n    private fun generateReset(helperClass: GeneratedModelInfo) = buildMethod(\"reset\") {\n        addAnnotation(Override::class.java)\n        addModifiers(PUBLIC)\n        returns(helperClass.parameterizedGeneratedName)\n        addStatement(\"\\$L = null\", modelBindListenerFieldName())\n        addStatement(\"\\$L = null\", modelUnbindListenerFieldName())\n        addStatement(\"\\$L = null\", modelVisibilityStateChangedListenerFieldName())\n        addStatement(\"\\$L = null\", modelVisibilityChangedListenerFieldName())\n\n        if (shouldUseBitSet(helperClass)) {\n            addStatement(\"\\$L.clear()\", ATTRIBUTES_BITSET_FIELD_NAME)\n        }\n\n        helperClass.attributeInfo\n            .filterNot { it.hasFinalModifier }\n            .forEach {\n                addStatement(\n                    it.setterCode(),\n                    if (it.codeToSetDefault.isPresent)\n                        it.codeToSetDefault.value()\n                    else\n                        Utils.getDefaultValue(it.typeName)\n                )\n            }\n\n        addStatement(\"super.reset()\")\n        addStatement(\"return this\")\n    }\n\n    private fun addHashCodeValidationIfNecessary(\n        method: MethodSpec.Builder,\n        message: String\n    ): MethodSpec.Builder {\n        if (configManager.shouldValidateModelUsage()) {\n            method.addStatement(\"validateStateHasNotChangedSinceAdded(\\$S, position)\", message)\n        }\n\n        return method\n    }\n\n    /**\n     * If the modelfactory module is present, and if this model supports it, this generates a static\n     * method whose purpose is to create a new model based on a typed mapping of property names to\n     * values provided via the ModelProperties interface. Notably, this generated method makes it\n     * easy to create models from JSON and various other data formats.\n     */\n    private fun addFromPropertiesMethodIfNeeded(\n        classBuilder: TypeSpec.Builder,\n        modelInfo: GeneratedModelInfo\n    ) {\n        // The epoxy-modelfactory module must be present to enable this functionality\n        if (!environment.isTypeLoaded(EPOXY_MODEL_PROPERTIES)) {\n            return\n        }\n\n        // Models that don't have an empty constructor are not supported because there would be no\n        // clear way to create new instances\n        if (!modelInfo.hasEmptyConstructor()) {\n            return\n        }\n\n        val attributeInfoConditions = listOf(\n            AttributeInfo::isBoolean,\n            AttributeInfo::isCharSequenceOrString,\n            AttributeInfo::isDouble,\n            AttributeInfo::isDrawableRes,\n            AttributeInfo::isEpoxyModelList,\n            AttributeInfo::isInt,\n            AttributeInfo::isLong,\n            AttributeInfo::isRawRes,\n            AttributeInfo::isStringList,\n            AttributeInfo::isStringAttributeData,\n            AttributeInfo::isViewClickListener\n        )\n        val supportedAttributeInfo = if (modelInfo.attributeGroups.isNotEmpty()) {\n            modelInfo.attributeInfo\n                .groupBy { it.generatedSetterName() }\n                .mapNotNull { (_, attributes) ->\n                    // Amongst attributes with a supported type, we only include those that have a\n                    // unique name. This means that multiple attributes with the same name and\n                    // supported types are excluded, because we wouldn't know which one to use.\n                    attributes.singleOrNull { attributeInfo ->\n                        attributeInfoConditions.any { it.invoke(attributeInfo) }\n                    }\n                }\n        } else {\n            // attributeGroups is always empty for models not using @ModelView\n            modelInfo.attributeInfo.filter { attributeInfo ->\n                attributeInfoConditions.any { it.invoke(attributeInfo) }\n            }\n        }\n            .filter { it.generateSetter && !it.hasFinalModifier }\n\n        // If none of the properties are of a supported type the method isn't generated\n        if (supportedAttributeInfo.isEmpty()) {\n            return\n        }\n\n        val method = MethodSpec.methodBuilder(\"from\").apply {\n            addModifiers(PUBLIC, STATIC)\n            addParameter(EPOXY_MODEL_PROPERTIES, \"properties\")\n            returns(modelInfo.generatedName)\n\n            addStatement(\n                \"\\$T model = new \\$T()\",\n                modelInfo.generatedName,\n                modelInfo.generatedName\n            )\n\n            addStatement(\"model.id(properties.getId())\")\n\n            // Groups attributes that are part of the same attribute group, others will be by\n            // themselves (at this point no two attributes should have the same generated setter\n            // name).\n            val supportedAttributeInfoGroups = supportedAttributeInfo.groupBy {\n                if (it.groupKey.isNullOrEmpty()) {\n                    it.generatedSetterName()\n                } else {\n                    it.groupKey\n                }\n            }\n\n            for ((_, attributeInfoGroup) in supportedAttributeInfoGroups) {\n                for ((index, attributeInfo) in attributeInfoGroup.withIndex()) {\n                    val setterName = attributeInfo.generatedSetterName()\n                    val isStartOfGroup = index == 0\n                    val isEndOfGroup = index == attributeInfoGroup.size - 1\n\n                    if (isStartOfGroup) {\n                        beginControlFlow(\"if (properties.has(\\$S))\", setterName)\n                    } else {\n                        nextControlFlow(\"else if (properties.has(\\$S))\", setterName)\n                    }\n\n                    val jsonGetterName = when {\n                        attributeInfo.isBoolean -> \"getBoolean\"\n                        attributeInfo.isCharSequenceOrString ||\n                            attributeInfo.isStringAttributeData -> \"getString\"\n                        attributeInfo.isDouble -> \"getDouble\"\n                        attributeInfo.isDrawableRes -> \"getDrawableRes\"\n                        attributeInfo.isEpoxyModelList -> \"getEpoxyModelList\"\n                        attributeInfo.isInt && !attributeInfo.isDrawableRes &&\n                            !attributeInfo.isRawRes -> \"getInt\"\n                        attributeInfo.isLong -> \"getLong\"\n                        attributeInfo.isRawRes -> \"getRawRes\"\n                        attributeInfo.isStringList -> \"getStringList\"\n                        attributeInfo.isViewClickListener -> \"getOnClickListener\"\n                        else -> {\n                            logger.logError(\n                                \"Missing ModelProperties method for a supported attribute type.\"\n                            )\n                            null\n                        }\n                    }\n                    jsonGetterName?.let {\n                        addStatement(\n                            \"model.\\$N(properties.\\$N(\\$S))\",\n                            setterName,\n                            jsonGetterName,\n                            setterName\n                        )\n                    }\n\n                    if (isEndOfGroup) {\n                        endControlFlow()\n                    }\n                }\n            }\n\n            if (modelInfo.isStyleable) {\n                addStatement(\"\\$T style = properties.getStyle()\", PARIS_STYLE)\n                beginControlFlow(\"if (style != null)\")\n                addStatement(\"model.style(style)\")\n                endControlFlow()\n            }\n\n            addStatement(\"return model\")\n        }.build()\n\n        classBuilder.addMethod(method)\n    }\n\n    companion object {\n        /**\n         * Use this suffix on helper fields added to the generated class so that we don't clash with\n         * fields on the original model.\n         */\n        private val GENERATED_FIELD_SUFFIX = \"_epoxyGeneratedModel\"\n        private val CREATE_NEW_HOLDER_METHOD_NAME = \"createNewHolder\"\n        private val GET_DEFAULT_LAYOUT_METHOD_NAME = \"getDefaultLayout\"\n        val ATTRIBUTES_BITSET_FIELD_NAME = \"assignedAttributes$GENERATED_FIELD_SUFFIX\"\n\n        fun shouldUseBitSet(info: GeneratedModelInfo): Boolean {\n            return info.attributeInfo.any { shouldUseBitSet(info, it) }\n        }\n\n        // Avoid generating bitset code for attributes that don't need it.\n        fun shouldUseBitSet(info: GeneratedModelInfo, attr: AttributeInfo): Boolean {\n            if (info !is ModelViewInfo) return false\n\n            // We use the bitset to validate if a required attribute had a value set on it\n            if (attr.isRequired) return true\n\n            // If the attribute is not generated then we assume that its parent model\n            // handles its binding.\n            if (!attr.isGenerated) return false\n\n            // With default values we use the bitset when our bind code needs to conditionally\n            // check which attribute value to set (either because its in a group or it has a default value)\n            return ModelViewWriter.hasConditionals(info.attributeGroup(attr))\n        }\n\n        fun isAttributeSetCode(\n            info: GeneratedModelInfo,\n            attribute: AttributeInfo\n        ) = CodeBlock.of(\n            \"\\$L.get(\\$L)\", ATTRIBUTES_BITSET_FIELD_NAME,\n            attributeIndex(info, attribute)\n        )!!\n\n        private fun attributeIndex(\n            modelInfo: GeneratedModelInfo,\n            attributeInfo: AttributeInfo\n        ): Int {\n            val index = modelInfo.attributeInfo.indexOf(attributeInfo)\n            if (index < 0) {\n                error(\"The attribute $attributeInfo does not exist in the model ${modelInfo.generatedName}\")\n            }\n            return index\n        }\n\n        fun setBitSetIfNeeded(\n            modelInfo: GeneratedModelInfo,\n            attr: AttributeInfo,\n            stringSetter: Builder\n        ) {\n            if (shouldUseBitSet(modelInfo, attr)) {\n                stringSetter.addStatement(\n                    \"\\$L.set(\\$L)\", ATTRIBUTES_BITSET_FIELD_NAME,\n                    attributeIndex(modelInfo, attr)\n                )\n            }\n        }\n\n        fun addParameterNullCheckIfNeeded(\n            configManager: ConfigManager,\n            attr: AttributeInfo,\n            paramName: String,\n            builder: Builder\n        ) {\n\n            if (configManager.shouldValidateModelUsage() &&\n                attr.hasSetNullability() &&\n                !attr.isNullable()\n            ) {\n\n                builder.beginControlFlow(\"if (\\$L == null)\", paramName)\n                    .addStatement(\n                        \"throw new \\$T(\\\"\\$L cannot be null\\\")\",\n                        IllegalArgumentException::class.java, paramName\n                    )\n                    .endControlFlow()\n            }\n        }\n\n        fun startNotEqualsControlFlow(\n            methodBuilder: MethodSpec.Builder,\n            attribute: AttributeInfo\n        ): MethodSpec.Builder {\n            val attributeType = attribute.typeName\n            val useHash = attributeType.isPrimitive || attribute.useInHash\n            return startNotEqualsControlFlow(\n                methodBuilder, useHash, attributeType,\n                attribute.getterCode()\n            )\n        }\n\n        fun startNotEqualsControlFlow(\n            builder: Builder,\n            useObjectHashCode: Boolean,\n            type: TypeName,\n            accessorCode: String\n        ) = builder.beginControlFlow(\n            \"if (\\$L)\",\n            notEqualsCodeBlock(useObjectHashCode, type, accessorCode)\n        )\n\n        fun notEqualsCodeBlock(attribute: AttributeInfo): CodeBlock {\n            val attributeType = attribute.typeName\n            val useHash = attributeType.isPrimitive || attribute.useInHash\n            return notEqualsCodeBlock(useHash, attributeType, attribute.getterCode())\n        }\n\n        fun notEqualsCodeBlock(\n            useObjectHashCode: Boolean,\n            type: TypeName,\n            accessorCode: String\n        ): CodeBlock = if (useObjectHashCode) {\n            when {\n                type === FLOAT -> CodeBlock.of(\n                    \"(Float.compare(that.\\$L, \\$L) != 0)\",\n                    accessorCode, accessorCode\n                )\n                type === DOUBLE -> CodeBlock.of(\n                    \"(Double.compare(that.\\$L, \\$L) != 0)\",\n                    accessorCode, accessorCode\n                )\n                type.isPrimitive -> CodeBlock.of(\"(\\$L != that.\\$L)\", accessorCode, accessorCode)\n                type is ArrayTypeName -> CodeBlock.of(\n                    \"!\\$T.equals(\\$L, that.\\$L)\",\n                    TypeName.get(Arrays::class.java),\n                    accessorCode, accessorCode\n                )\n                else -> CodeBlock.of(\n                    \"(\\$L != null ? !\\$L.equals(that.\\$L) : that.\\$L != null)\",\n                    accessorCode, accessorCode, accessorCode, accessorCode\n                )\n            }\n        } else {\n            CodeBlock.of(\"((\\$L == null) != (that.\\$L == null))\", accessorCode, accessorCode)\n        }\n\n        private fun addHashCodeLineForType(\n            builder: Builder,\n            useObjectHashCode: Boolean,\n            type: TypeName,\n            accessorCode: String\n        ) {\n            builder.apply {\n                if (useObjectHashCode) {\n                    when (type) {\n                        BYTE, CHAR, SHORT, INT -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + \\$L\",\n                            accessorCode\n                        )\n                        LONG -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (int) (\\$L ^ (\\$L >>> 32))\",\n                            accessorCode,\n                            accessorCode\n                        )\n                        FLOAT -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (\\$L != +0.0f \" + \"? \" +\n                                \"Float.floatToIntBits(\\$L) : 0)\",\n                            accessorCode, accessorCode\n                        )\n                        DOUBLE -> {\n                            addStatement(\"temp = Double.doubleToLongBits(\\$L)\", accessorCode)\n                            addStatement(\"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (int) (temp ^ (temp >>> 32))\")\n                        }\n                        BOOLEAN -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (\\$L ? 1 : 0)\",\n                            accessorCode\n                        )\n                        is ArrayTypeName -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + Arrays.hashCode(\\$L)\",\n                            accessorCode\n                        )\n                        else -> addStatement(\n                            \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (\\$L != null ? \\$L.hashCode() : 0)\",\n                            accessorCode,\n                            accessorCode\n                        )\n                    }\n                } else {\n                    addStatement(\n                        \"$HASH_CODE_RESULT_PROPERTY = 31 * $HASH_CODE_RESULT_PROPERTY + (\\$L != null ? 1 : 0)\",\n                        accessorCode\n                    )\n                }\n            }\n        }\n\n        fun addOnMutationCall(method: MethodSpec.Builder) = method.addStatement(\"onMutation()\")!!\n\n        fun modelImplementsBindWithDiff(\n            clazz: XTypeElement,\n            currentMemoizer: Memoizer\n        ): Boolean {\n            // Re-resolve the type element using the current memoizer's environment to avoid\n            // accessing stale KSP elements from previous rounds. In KSP2, this triggers\n            // \"PSI has changed since creation\" errors.\n            val freshClazz = currentMemoizer.environment.requireType(clazz.qualifiedName).typeElement!!\n            val baseBindWithDiffMethod = currentMemoizer.baseBindWithDiffMethod\n\n            return freshClazz.getAllMethods().any {\n                it.name == baseBindWithDiffMethod.name &&\n                    !it.isAbstract() &&\n                    it.overrides(\n                        other = baseBindWithDiffMethod,\n                        owner = freshClazz\n                    )\n            }\n        }\n    }\n}\n\n/**\n * Property name of the int property used to build the hashcode result.\n * An underscore is used to not clash with any attribute names a user might choose.\n */\nprivate const val HASH_CODE_RESULT_PROPERTY = \"_result\"\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/GroupedAttribute.kt",
    "content": "package com.airbnb.epoxy.processor\n\nclass GroupedAttribute(\n    val attributeInfo: AttributeInfo,\n    val group: GeneratedModelInfo.AttributeGroup\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/HashCodeValidator.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XArrayType\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.isArray\nimport androidx.room.compiler.processing.isEnum\nimport androidx.room.compiler.processing.isEnumEntry\nimport com.airbnb.epoxy.processor.Utils.getMethodOnClass\nimport com.airbnb.epoxy.processor.Utils.isIterableType\nimport com.airbnb.epoxy.processor.Utils.isMap\nimport com.airbnb.epoxy.processor.Utils.throwError\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.TypeName\n\n/** Validates that an attribute implements hashCode and equals.  */\ninternal class HashCodeValidator(\n    private val environment: XProcessingEnv,\n    private val memoizer: Memoizer,\n    val logger: Logger,\n) {\n\n    fun implementsHashCodeAndEquals(mirror: XType): Boolean {\n        return try {\n            validateImplementsHashCode(mirror)\n            true\n        } catch (e: EpoxyProcessorException) {\n            false\n        }\n    }\n\n    @Throws(EpoxyProcessorException::class)\n    fun validate(attribute: AttributeInfo) {\n        try {\n            validateImplementsHashCode(attribute.xType)\n        } catch (e: EpoxyProcessorException) {\n            // Append information about the attribute and class to the existing exception\n            logger.logError(\n                e.message +\n                    \" (%s) Epoxy requires every model attribute to implement equals and hashCode \" +\n                    \"so that changes in the model \" +\n                    \"can be tracked. If you want the attribute to be excluded, use \" +\n                    \"the option 'DoNotHash'. If you want to ignore this warning use \" +\n                    \"the option 'IgnoreRequireHashCode'\",\n                attribute\n            )\n        }\n    }\n\n    @Throws(EpoxyProcessorException::class)\n    private fun validateImplementsHashCode(xType: XType) {\n        if (xType.isError()) {\n            // The class type cannot be resolved. This may be because it is a generated epoxy model and\n            // the class hasn't been built yet.\n            // We just assume that the class will implement hashCode at runtime.\n            return\n        }\n        if (xType.typeName.isPrimitive || xType.typeName.isBoxedPrimitive) {\n            return\n        }\n        if (xType.isArray()) {\n            validateArrayType(xType)\n            return\n        }\n\n        val xTypeElement = xType.typeElement ?: return\n\n        if (xTypeElement.isDataClass() || xTypeElement.isEnum() || xTypeElement.isEnumEntry() || xTypeElement.isValueClass()) {\n            return\n        }\n\n        if (xType.isMap(environment)) {\n            // as part of ksp conversion we need to add this to maintain legacy behavior because\n            // java Maps implement equals/hashcode so they are automatically approved, even\n            // though we never verified the key/value type implements it. Not adding it\n            // now to avoid breaking existing code.\n            return\n        }\n\n        if (isIterableType(xType, memoizer)) {\n            validateIterableType(xType)\n            return\n        }\n        if (isAutoValueType(xTypeElement)) {\n            return\n        }\n        if (isWhiteListedType(xTypeElement)) {\n            return\n        }\n        if (!hasHashCodeInClassHierarchy(xTypeElement)) {\n            throwError(\"Attribute does not implement hashCode\")\n        }\n        if (!hasEqualsInClassHierarchy(xTypeElement)) {\n            throwError(\"Attribute does not implement equals\")\n        }\n    }\n\n    private fun hasHashCodeInClassHierarchy(clazz: XTypeElement): Boolean {\n        return hasFunctionInClassHierarchy(clazz, HASH_CODE_METHOD)\n    }\n\n    private fun hasEqualsInClassHierarchy(clazz: XTypeElement): Boolean {\n        return hasFunctionInClassHierarchy(clazz, EQUALS_METHOD)\n    }\n\n    private fun hasFunctionInClassHierarchy(clazz: XTypeElement, function: MethodSpec): Boolean {\n        val methodOnClass = getMethodOnClass(clazz, function, environment)\n            ?: return false\n\n        val implementingClass = methodOnClass.enclosingElement as? XTypeElement\n        return implementingClass?.name != \"Object\" && implementingClass?.type?.isObjectOrAny() != true\n\n        // We don't care if the method is abstract or not, as long as it exists and it isn't the Object\n        // implementation then the runtime value will implement it to some degree (hopefully\n        // correctly :P)\n    }\n\n    @Throws(EpoxyProcessorException::class)\n    private fun validateArrayType(mirror: XArrayType) {\n        // Check that the type of the array implements hashCode\n        val arrayType = mirror.componentType\n        try {\n            validateImplementsHashCode(arrayType)\n        } catch (e: EpoxyProcessorException) {\n            throwError(\n                \"Type in array does not implement hashCode. Type: %s\",\n                arrayType.toString()\n            )\n        }\n    }\n\n    @Throws(EpoxyProcessorException::class)\n    private fun validateIterableType(type: XType) {\n        for (typeParameter in type.typeArguments) {\n            // check that the type implements hashCode\n            try {\n                validateImplementsHashCode(typeParameter)\n            } catch (e: EpoxyProcessorException) {\n                throwError(\n                    \"Type in Iterable does not implement hashCode. Type: %s\",\n                    typeParameter.toString()\n                )\n            }\n        }\n\n        // Assume that the iterable class implements hashCode and just return\n    }\n\n    private fun isWhiteListedType(element: XTypeElement): Boolean {\n        return element.isSubTypeOf(memoizer.charSequenceType)\n    }\n\n    /**\n     * Returns true if this class is expected to be implemented via a generated autovalue class,\n     * which implies it will have equals/hashcode at runtime.\n     */\n    private fun isAutoValueType(element: XTypeElement): Boolean {\n        // For migrating away from autovalue and copying autovalue sources to version control (and therefore\n        // removing annotations and compile time generation) the annotation lookup no longer works.\n        // Instead, assume that if a type is abstract then it has a runtime implementation the properly\n        // implements equals/hashcode.\n        if (element.isAbstract() && !element.isInterface()) return true\n\n        // Only works for classes in the module since AutoValue has a retention of Source so it is\n        // discarded after compilation.\n        for (xAnnotation in element.getAllAnnotations()) {\n            // Avoid type resolution as simple name should be enough\n            val isAutoValue = xAnnotation.name == \"AutoValue\"\n            if (isAutoValue) {\n                return true\n            }\n        }\n        return false\n    }\n\n    companion object {\n        private val HASH_CODE_METHOD = MethodSpec.methodBuilder(\"hashCode\")\n            .returns(TypeName.INT)\n            .build()\n        private val EQUALS_METHOD = MethodSpec.methodBuilder(\"equals\")\n            .addParameter(TypeName.OBJECT, \"obj\")\n            .returns(TypeName.BOOLEAN)\n            .build()\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ImportScanner.java",
    "content": "package com.airbnb.epoxy.processor;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementScanner7;\n\npublic class ImportScanner extends ElementScanner7<Void, Void> {\n\n  private Set<String> types = new HashSet<>();\n\n  public Set<String> getImportedTypes() {\n    return types;\n  }\n\n  @Override\n  public Void visitType(TypeElement e, Void p) {\n    for (TypeMirror interfaceType : e.getInterfaces()) {\n      types.add(interfaceType.toString());\n    }\n\n    TypeMirror superclass = e.getSuperclass();\n    SynchronizationKt.ensureLoaded(superclass);\n    types.add(superclass.toString());\n    return super.visitType(e, p);\n  }\n\n  @Override\n  public Void visitExecutable(ExecutableElement e, Void p) {\n    if (e.getReturnType().getKind() == TypeKind.DECLARED) {\n      types.add(e.getReturnType().toString());\n    }\n    return super.visitExecutable(e, p);\n  }\n\n  @Override\n  public Void visitTypeParameter(TypeParameterElement e, Void p) {\n    if (e.asType().getKind() == TypeKind.DECLARED) {\n      types.add(e.asType().toString());\n    }\n    return super.visitTypeParameter(e, p);\n  }\n\n  @Override\n  public Void visitVariable(VariableElement e, Void p) {\n    if (e.asType().getKind() == TypeKind.DECLARED) {\n      types.add(e.asType().toString());\n    }\n    return super.visitVariable(e, p);\n  }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/JavaPoetDsl.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.AnnotationSpec\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.FieldSpec\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeSpec\nimport com.squareup.javapoet.TypeVariableName\nimport java.lang.reflect.Type\nimport javax.lang.model.element.Modifier\nimport kotlin.reflect.KClass\n\ninternal inline fun buildClass(\n    name: String,\n    initializer: TypeSpec.Builder.() -> Unit\n): TypeSpec = TypeSpec.classBuilder(name).apply(initializer).build()\n\ninternal inline fun buildInterface(\n    name: String,\n    initializer: TypeSpec.Builder.() -> Unit\n): TypeSpec = TypeSpec.interfaceBuilder(name).apply(initializer).build()\n\ninternal inline fun buildInterface(\n    name: ClassName,\n    initializer: TypeSpec.Builder.() -> Unit\n): TypeSpec = TypeSpec.interfaceBuilder(name).apply(initializer).build()\n\ninternal inline fun buildClass(\n    className: ClassName,\n    initializer: TypeSpec.Builder.() -> Unit\n): TypeSpec = TypeSpec.classBuilder(className).apply(initializer).build()\n\ninternal inline fun TypeSpec.Builder.addAnnotation(\n    type: Class<*>,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun TypeSpec.Builder.addAnnotation(\n    type: ClassName,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun buildConstructor(\n    initializer: MethodSpec.Builder.() -> Unit\n): MethodSpec = MethodSpec.constructorBuilder().apply(initializer).build()\n\ninternal inline fun buildMethod(\n    name: String,\n    initializer: MethodSpec.Builder.() -> Unit\n): MethodSpec = MethodSpec.methodBuilder(name).apply(initializer).build()\n\n/** Copies all details of a methodspec besides the statement, allowing you to override any piece of the method. */\ninternal fun MethodSpec.copy(\n    name: String? = null,\n    modifiers: Iterable<Modifier>? = null, // replaces all existing modifiers if not null\n    additionalModifiers: Iterable<Modifier>? = null, // Appends to existing modifiers if not null\n    returns: TypeName? = null,\n    params: Iterable<ParameterSpec>? = null,\n    varargs: Boolean? = null,\n    typeVariables: Iterable<TypeVariableName>? = null,\n    exceptions: Iterable<TypeName>? = null,\n    // Any other custom init code, like adding statements\n    callback: MethodSpec.Builder.() -> Unit = {}\n): MethodSpec {\n    val builder = MethodSpec.methodBuilder(name ?: this.name)\n        .addModifiers(modifiers ?: this.modifiers)\n        .addModifiers(additionalModifiers ?: emptyList())\n        .returns(returns ?: this.returnType)\n        .addParameters(params ?: this.parameters)\n        .varargs(varargs ?: this.varargs)\n        .addTypeVariables(typeVariables ?: this.typeVariables)\n        .addExceptions(exceptions ?: this.exceptions)\n\n    return builder.apply(callback).build()\n}\n\ninternal inline fun MethodSpec.Builder.addAnnotation(\n    type: Class<*>,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun MethodSpec.Builder.addAnnotation(\n    type: ClassName,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun buildField(\n    type: Type,\n    name: String,\n    initializer: FieldSpec.Builder.() -> Unit\n): FieldSpec = FieldSpec.builder(type, name).apply(initializer).build()\n\ninternal inline fun buildField(\n    type: TypeName,\n    name: String,\n    initializer: FieldSpec.Builder.() -> Unit\n): FieldSpec = FieldSpec.builder(type, name).apply(initializer).build()\n\ninternal inline fun FieldSpec.Builder.addAnnotation(\n    type: Class<*>,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun FieldSpec.Builder.addAnnotation(\n    type: ClassName,\n    initializer: AnnotationSpec.Builder.() -> Unit\n) {\n    addAnnotation(AnnotationSpec.builder(type).apply(initializer).build())\n}\n\ninternal inline fun TypeSpec.Builder.addMethod(\n    name: String,\n    initializer: MethodSpec.Builder.() -> Unit\n) {\n    addMethod(MethodSpec.methodBuilder(name).apply(initializer).build())\n}\n\ninternal inline fun TypeSpec.Builder.addField(\n    type: TypeName,\n    name: String,\n    vararg modifiers: Modifier,\n    initializer: FieldSpec.Builder.() -> Unit\n) {\n    addField(FieldSpec.builder(type, name, *modifiers).apply(initializer).build())\n}\n\ninternal inline fun TypeSpec.Builder.addConstructor(initializer: MethodSpec.Builder.() -> Unit) {\n    addMethod(MethodSpec.constructorBuilder().apply(initializer).build())\n}\n\ninternal inline fun MethodSpec.Builder.addParameter(\n    type: TypeName,\n    name: String,\n    vararg modifiers: Modifier,\n    initializer: ParameterSpec.Builder.() -> Unit\n) {\n    addParameter(ParameterSpec.builder(type, name, *modifiers).apply(initializer).build())\n}\n\ninternal fun KClass<*>.className() = ClassName.get(this.java)\ninternal fun Class<*>.className() = ClassName.get(this)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/KClassNames.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.kotlinpoet.ClassName\nimport com.squareup.kotlinpoet.asClassName\n\nobject KClassNames {\n\n    // Annotations\n    val DEPRECATED = Deprecated::class.asClassName()\n    val KOTLIN_UNIT = ClassName.bestGuess(\"kotlin.Unit\")\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/KotlinModelBuilderExtensionWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XFiler\nimport androidx.room.compiler.processing.addOriginatingElement\nimport androidx.room.compiler.processing.writeTo\nimport com.squareup.kotlinpoet.AnnotationSpec\nimport com.squareup.kotlinpoet.FileSpec\nimport com.squareup.kotlinpoet.FunSpec\nimport com.squareup.kotlinpoet.KModifier\nimport com.squareup.kotlinpoet.LambdaTypeName\nimport com.squareup.kotlinpoet.ParameterizedTypeName\nimport com.squareup.kotlinpoet.TypeVariableName\nimport com.squareup.kotlinpoet.javapoet.toKTypeName\nimport javax.lang.model.element.Modifier\n\ninternal class KotlinModelBuilderExtensionWriter(\n    val filer: XFiler,\n    asyncable: Asyncable\n) : Asyncable by asyncable {\n\n    fun generateExtensionsForModels(\n        generatedModels: List<GeneratedModelInfo>,\n        processorName: String,\n        memoizer: Memoizer\n    ) {\n        generatedModels\n            .filter { it.shouldGenerateModel }\n            .groupBy { it.generatedName.packageName() }\n            .mapNotNull(\"generateExtensionsForModels\") { packageName, models ->\n                buildExtensionFile(\n                    packageName,\n                    models,\n                    processorName,\n                    memoizer\n                )\n            }.forEach(\"writeExtensionsForModels\", parallel = false) {\n                // Cannot be done in parallel since filer is not thread safe\n                it.writeTo(filer, mode = XFiler.Mode.Aggregating)\n            }\n    }\n\n    private fun buildExtensionFile(\n        packageName: String,\n        models: List<GeneratedModelInfo>,\n        processorName: String,\n        memoizer: Memoizer\n    ): FileSpec {\n        val fileBuilder = FileSpec.builder(\n            packageName,\n            \"Epoxy${processorName.removePrefix(\"Epoxy\")}KotlinExtensions\"\n        )\n\n        models.map {\n            if (it.constructors.isEmpty()) {\n                listOf(buildExtensionsForModel(it, null, memoizer))\n            } else {\n                it.constructors.map { constructor ->\n                    buildExtensionsForModel(it, constructor, memoizer)\n                }\n            }\n        }\n            .flatten()\n            // Sort by function name to keep ordering consistent across builds. Otherwise if the\n            // processor processes models in differing orders we can have indeterminate source file\n            // generation which breaks cache keys.\n            .sortedBy { it.name }\n            .forEach { fileBuilder.addFunction(it) }\n\n        // We suppress Deprecation warnings for this class in case any of the models used are deprecated.\n        // This prevents the generated file from causing errors for using deprecated classes.\n        fileBuilder.addAnnotation(\n            AnnotationSpec.builder(Suppress::class)\n                .addMember(\"%S\", \"DEPRECATION\")\n                .build()\n        )\n\n        return fileBuilder.build()\n    }\n\n    private fun buildExtensionsForModel(\n        model: GeneratedModelInfo,\n        constructor: GeneratedModelInfo.ConstructorInfo?,\n        memoizer: Memoizer\n    ): FunSpec {\n        val constructorIsNotPublic =\n            constructor != null && Modifier.PUBLIC !in constructor.modifiers\n\n        val initializerLambda = LambdaTypeName.get(\n            receiver = getBuilderInterfaceTypeName(model).toKTypeName(),\n            returnType = KClassNames.KOTLIN_UNIT\n        )\n\n        FunSpec.builder(getMethodName(model)).run {\n            receiver(ClassNames.MODEL_COLLECTOR.toKTypeName())\n            val params = constructor?.params ?: listOf()\n            addParameters(params.map { it.toKPoet() })\n\n            addParameter(\n                \"modelInitializer\",\n                initializerLambda\n            )\n\n            val modelClass = model.parameterizedGeneratedName.toKTypeName()\n            if (modelClass is ParameterizedTypeName) {\n                // We expect the type arguments to be of type TypeVariableName\n                // Otherwise we can't get bounds information off of it and can't do much\n                modelClass\n                    .typeArguments\n                    .filterIsInstance<TypeVariableName>()\n                    .let { if (it.isNotEmpty()) addTypeVariables(it) }\n            }\n\n            addModifiers(KModifier.INLINE)\n            addModifiers(if (constructorIsNotPublic) KModifier.INTERNAL else KModifier.PUBLIC)\n\n            addStatement(\"add(\")\n            beginControlFlow(\n                \"%T(${params.joinToString(\", \") { it.name }}).apply\",\n                modelClass\n            )\n            addStatement(\"modelInitializer()\")\n            endControlFlow()\n            addStatement(\")\")\n\n            model.originatingElements(memoizer).forEach {\n                addOriginatingElement(it)\n            }\n            return build()\n        }\n    }\n\n    private fun getMethodName(model: GeneratedModelInfo) = model.generatedName\n        .simpleName()\n        .lowerCaseFirstLetter()\n        .removeSuffix(GeneratedModelInfo.GENERATED_MODEL_SUFFIX)\n        .removeSuffix(DataBindingModelInfo.BINDING_SUFFIX)\n        .removeSuffix(GeneratedModelInfo.GENERATED_CLASS_NAME_SUFFIX)\n        .replace(\"$\", \"\")\n        .removeSuffix(\"Epoxy\")\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/KotlinUtils.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XProcessingEnv\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.TypeName\nimport javax.lang.model.element.TypeElement\nimport javax.lang.model.util.Types\n\nfun TypeElement.superClassElement(types: Types): TypeElement? =\n    types.asElement(superclass)?.ensureLoaded() as TypeElement?\n\nfun String.toUpperCamelCase(): String {\n    val separators = listOf('_', ' ')\n\n    return transformEachChar { prevChar, char, _ ->\n        if (char !in separators) {\n            append(\n                when (prevChar) {\n                    null, in separators -> Character.toUpperCase(char)\n                    else -> char\n                }\n            )\n        }\n    }\n}\n\n/** Creates a new version of the classname where the simple name has the given suffix added to it.\n *\n * If there are multiple simple names they are combined into 1.\n * */\nfun ClassName.appendToName(suffix: String) = ClassName.get(\n    packageName(),\n    simpleNames().joinToString(separator = \"_\", postfix = suffix)\n).annotated(annotations)!!\n\n/** Iterates through each character, allowing you to build a string by transforming the characters as needed. */\nprivate fun String.transformEachChar(\n    operation: StringBuilder.(Char?, Char, Char?) -> Unit\n): String {\n    val stringBuilder = StringBuilder(length)\n\n    for (i in 0 until length) {\n        stringBuilder.operation(getOrNull(i - 1), get(i), getOrNull(i))\n    }\n\n    return stringBuilder.toString()\n}\n\nfun XProcessingEnv.isTypeLoaded(typeName: TypeName): Boolean {\n    return findTypeElement(typeName.toString()) != null\n}\n\n/** Similar to the java 8 Map#merge method. */\nfun <K, V> MutableMap<K, V>.putOrMerge(\n    key: K,\n    value: V,\n    reduceFunction: (V, V) -> V\n) {\n    val oldValue = get(key)\n    val newValue = if (oldValue == null) {\n        value\n    } else {\n        reduceFunction(oldValue, value)\n    }\n\n    put(key, newValue)\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Logger.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XMessager\nimport com.airbnb.epoxy.processor.Utils.buildEpoxyException\nimport java.io.PrintWriter\nimport java.io.StringWriter\nimport java.util.Collections\nimport java.util.Stack\nimport javax.tools.Diagnostic\n\nclass Logger(val messager: XMessager, val logTimings: Boolean) {\n\n    private val timings = mutableListOf<Timing>()\n    private val currentTimingBlocks = Stack<MutableList<Timing>>()\n\n    private val loggedExceptions: MutableList<Throwable> =\n        Collections.synchronizedList(mutableListOf())\n\n    fun writeExceptions() {\n        loggedExceptions.forEach {\n            val msg = \"${it.javaClass.simpleName}: ${it.localizedMessage}\\n${it.stackTraceString()}\"\n\n            // In KSP2, PSI elements became invalid after processing round completes.\n            // Don't pass element to messager, only include location info in the message text.\n            messager.printMessage(\n                kind = Diagnostic.Kind.ERROR,\n                msg = msg,\n            )\n        }\n        loggedExceptions.clear()\n    }\n\n    private fun Throwable.stackTraceString(): String {\n        val sw = StringWriter()\n        val pw = PrintWriter(sw)\n        printStackTrace(pw)\n        pw.flush()\n        return sw.toString()\n    }\n\n    fun warn(msg: String) {\n        messager.printMessage(Diagnostic.Kind.WARNING, msg)\n    }\n\n    fun logErrors(exceptions: List<Exception>) {\n        exceptions.forEach { logError(it) }\n    }\n\n    /**\n     * Errors logged with this should describe exactly what is wrong. These won't show the stacktrace\n     * in the error output to reduce confusion.\n     */\n    fun logError(msg: String, vararg args: Any) {\n        logError(buildEpoxyException(msg, *args))\n    }\n\n    fun logError(element: XElement, msg: String, vararg args: Any) {\n        logError(buildEpoxyException(element, msg, *args))\n    }\n\n    fun logError(msg: String, element: XElement) {\n        logError(EpoxyProcessorException(msg, element = element))\n    }\n\n    /**\n     * Errors are logged and saved until after classes are generating. Otherwise if we throw\n     * immediately the models are not generated which leads to lots of other compiler errors which\n     * mask the actual issues.\n     *\n     *\n     * If the exception is not an [EpoxyProcessorException] then the stacktrace will be shown in\n     * the output.\n     */\n    @JvmOverloads\n    fun logError(e: Throwable, message: String? = null) {\n        loggedExceptions.add(message?.let { EpoxyProcessorException(it, e) } ?: e)\n    }\n\n    fun note(message: String) {\n        // These don't show up in gradle builds unless --debug verbosity is used, which makes them\n        // not so useful :(. We often use warn instead for that reason\n        messager.printMessage(Diagnostic.Kind.NOTE, \"$message\\n \")\n    }\n\n    fun <T> measure(\n        name: String,\n        numItems: Int? = null,\n        isParallel: Boolean? = null,\n        block: () -> T\n    ): T {\n        if (!logTimings) return block()\n        currentTimingBlocks.add(mutableListOf())\n\n        val start = System.nanoTime()\n        val result = block()\n        val elapsed = (System.nanoTime() - start) / 1_000_000\n\n        val timing = Timing(\n            name = name,\n            durationMs = elapsed,\n            nestedTimings = currentTimingBlocks.pop(),\n            itemCount = numItems,\n            isParallel = isParallel\n        )\n\n        (currentTimingBlocks.lastOrNull() ?: timings).add(timing)\n\n        return result\n    }\n\n    fun printTimings(processorName: String) {\n        if (!logTimings) return\n\n        val timingString = timings.joinToString(nesting = 1)\n        val totalDuration = timings.sumOf { it.durationMs.toInt() }\n        warn(\n            \"$processorName completed in $totalDuration ms:\\n$timingString\\n \"\n        )\n    }\n}\n\nprivate fun List<Timing>.joinToString(nesting: Int) = joinToString(\"\") { it.toString(nesting) }\n\ndata class Timing(\n    val name: String,\n    val durationMs: Long,\n    val nestedTimings: List<Timing>,\n    val itemCount: Int? = null,\n    val isParallel: Boolean? = null\n) {\n    fun toString(nesting: Int = 0): String {\n        if (durationMs == 0L) return \"\"\n\n        val parallel = if (isParallel == true) \"in parallel\" else \"\"\n        val items = if (itemCount != null) \"($itemCount items $parallel)\" else \"\"\n        val indent = \"  \".repeat(nesting)\n        return \"$indent$name: $durationMs ms $items\\n${nestedTimings.joinToString(nesting + 1)}\"\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Memoizer.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XArrayType\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.isVoid\nimport androidx.room.compiler.processing.isVoidObject\nimport com.airbnb.epoxy.AfterPropsSet\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.OnViewRecycled\nimport com.airbnb.epoxy.OnVisibilityChanged\nimport com.airbnb.epoxy.OnVisibilityStateChanged\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.processor.GeneratedModelInfo.Companion.RESET_METHOD\nimport com.airbnb.epoxy.processor.GeneratedModelInfo.Companion.buildParamSpecs\nimport com.airbnb.epoxy.processor.Utils.EPOXY_CONTROLLER_TYPE\nimport com.airbnb.epoxy.processor.Utils.EPOXY_HOLDER_TYPE\nimport com.airbnb.epoxy.processor.Utils.VIEW_CHECKED_CHANGE_LISTENER_TYPE\nimport com.airbnb.epoxy.processor.Utils.VIEW_CLICK_LISTENER_TYPE\nimport com.airbnb.epoxy.processor.Utils.VIEW_LONG_CLICK_LISTENER_TYPE\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.getFieldWithReflection\nimport com.airbnb.epoxy.processor.resourcescanning.getFieldWithReflectionOrNull\nimport com.google.devtools.ksp.getDeclaredFunctions\nimport com.google.devtools.ksp.processing.Resolver\nimport com.google.devtools.ksp.symbol.KSClassDeclaration\nimport com.google.devtools.ksp.symbol.KSType\nimport com.squareup.javapoet.ArrayTypeName\nimport com.squareup.javapoet.TypeName\nimport kotlin.reflect.KClass\n\nclass Memoizer(\n    val environment: XProcessingEnv,\n    val logger: Logger\n) {\n\n    val isKsp: Boolean get() = environment.backend == XProcessingEnv.Backend.KSP\n\n    val androidViewType: XType by lazy {\n        environment.requireType(Utils.ANDROID_VIEW_TYPE)\n    }\n\n    val epoxyModelClassAnnotation by lazy { EpoxyModelClass::class.className() }\n\n    val generatedModelType: XType by lazy {\n        environment.requireType(\"com.airbnb.epoxy.GeneratedModel\")\n    }\n\n    val viewOnClickListenerType: XType by lazy {\n        environment.requireType(VIEW_CLICK_LISTENER_TYPE)\n    }\n    val viewOnLongClickListenerType: XType by lazy {\n        environment.requireType(VIEW_LONG_CLICK_LISTENER_TYPE)\n    }\n    val viewOnCheckChangedType: XType by lazy {\n        environment.requireType(VIEW_CHECKED_CHANGE_LISTENER_TYPE)\n    }\n\n    val charSequenceType: XType by lazy {\n        environment.requireType(CharSequence::class)\n    }\n\n    val charSequenceNullableType: XType by lazy {\n        environment.requireType(CharSequence::class).makeNullable()\n    }\n\n    val iterableType: XType by lazy {\n        environment.requireType(Iterable::class)\n    }\n\n    val stringAttributeType: XType by lazy {\n        environment.requireType(ClassNames.EPOXY_STRING_ATTRIBUTE_DATA.toString())\n    }\n\n    val epoxyDataBindingModelBaseClass: XTypeElement? by lazy {\n        environment.findTypeElement(ClassNames.EPOXY_DATA_BINDING_MODEL.toString())\n    }\n\n    val parisStyleType: XType by lazy {\n        environment.requireType(ClassNames.PARIS_STYLE.toString())\n    }\n\n    val epoxyModelClassElementUntyped: XTypeElement by lazy {\n        environment.requireTypeElement(ClassNames.EPOXY_MODEL_UNTYPED.toString())\n    }\n\n    val epoxyModelCollectorType: XType by lazy {\n        environment.requireType(ClassNames.MODEL_COLLECTOR.toString())\n    }\n\n    val epoxyControllerType: XType by lazy {\n        environment.requireType(EPOXY_CONTROLLER_TYPE)\n    }\n\n    val epoxyModelWithHolderTypeUntyped: XType by lazy {\n        environment.requireType(ClassNames.EPOXY_MODEL_WITH_HOLDER_UNTYPED.toString())\n    }\n\n    val epoxyHolderType: XType by lazy {\n        environment.requireType(EPOXY_HOLDER_TYPE)\n    }\n\n    val viewType: XType by lazy {\n        environment.requireType(ClassNames.ANDROID_VIEW.toString())\n    }\n\n    val baseBindWithDiffMethod: XMethodElement by lazy {\n        epoxyModelClassElementUntyped.getDeclaredMethods()\n            .firstOrNull {\n                it.name == \"bind\" &&\n                    it.parameters.size == 2 &&\n                    // Second parameter in bind function is an epoxy model.\n                    it.parameters[1].type.typeElement?.name == \"EpoxyModel\"\n            }\n            ?: error(\"Unable to find bind function in epoxy model\")\n    }\n\n    private val methodsReturningClassType = mutableMapOf<String, Set<MethodInfo>>()\n\n    fun getMethodsReturningClassType(classQualifiedName: String, memoizer: Memoizer): Set<MethodInfo> {\n        // Re-resolve the type fresh using the current memoizer's environment.\n        // The caller may have been created in a previous round, and accessing properties\n        // of stale KSP types in KSP2 triggers \"PSI has changed since creation\" errors.\n        // By passing the qualified name as a String and resolving fresh each time,\n        // we ensure we always use current-round types.\n        val classType = memoizer.environment.requireType(classQualifiedName)\n        val classElement = classType.typeElement!!\n\n        return methodsReturningClassType.getOrPut(classQualifiedName) {\n\n            val methodInfos: List<MethodInfo> =\n                classElement.getDeclaredMethods().mapNotNull { subElement ->\n\n                    if (subElement.isPrivate() || subElement.isFinal() || subElement.isStatic()) {\n                        return@mapNotNull null\n                    }\n\n                    val methodReturnType = subElement.returnType\n                    if (!methodReturnType.isSameType(classType) &&\n                        !classType.isSubTypeOf(methodReturnType)\n                    ) {\n                        return@mapNotNull null\n                    }\n\n                    val methodName = subElement.name\n                    if (methodName == RESET_METHOD && subElement.parameters.isEmpty()) {\n                        return@mapNotNull null\n                    }\n                    val isEpoxyAttribute = subElement.hasAnnotation(EpoxyAttribute::class)\n\n                    MethodInfo(\n                        methodName,\n                        // Javapoet needs the javax modifiers to create the MethodSpec, so we\n                        // manually create them. These are the only options after returning\n                        // from checking the other modifiers\n                        subElement.javacModifiers,\n                        buildParamSpecs(subElement.parameters, memoizer),\n                        subElement.isVarArgs(),\n                        isEpoxyAttribute,\n                        subElement\n                    )\n                }\n\n            // Note: Adding super type methods second preserves any overloads in the base\n            // type that may have changes (ie, a new return type or annotation), since\n            // Set.plus only adds items that don't already exist.\n            val superClassElement = classElement.superClass?.typeElement\n                ?: return@getOrPut emptySet()\n            methodInfos.toSet() + getMethodsReturningClassType(superClassElement.qualifiedName, memoizer)\n        }\n    }\n\n    private val classConstructors =\n        mutableMapOf<String, List<GeneratedModelInfo.ConstructorInfo>>()\n\n    /**\n     * Get information about constructors of the original class so we can duplicate them in the\n     * generated class and call through to super with the proper parameters\n     */\n    fun getClassConstructors(\n        classElement: XTypeElement,\n        memoizer: Memoizer\n    ): List<GeneratedModelInfo.ConstructorInfo> {\n        return classConstructors.getOrPut(classElement.qualifiedName) {\n\n            classElement\n                .getConstructors()\n                .map { xConstructorElement ->\n\n                    GeneratedModelInfo.ConstructorInfo(\n                        xConstructorElement.javacModifiers,\n                        buildParamSpecs(xConstructorElement.parameters, memoizer),\n                        xConstructorElement.isVarArgs()\n                    )\n                }\n        }\n    }\n\n    private val validatedViewModelBaseElements = mutableMapOf<String, XTypeElement?>()\n    fun validateViewModelBaseClass(\n        baseModelType: XType,\n        logger: Logger,\n        viewName: String\n    ): XTypeElement? {\n        val baseModelElement = baseModelType.typeElement!!\n        return validatedViewModelBaseElements.getOrPut(baseModelElement.qualifiedName) {\n\n            if (!baseModelType.isEpoxyModel(this)) {\n                logger.logError(\n                    baseModelElement,\n                    \"The base model provided to an %s must extend EpoxyModel, but was %s (%s).\",\n                    ModelView::class.java.simpleName, baseModelType, viewName\n                )\n                null\n            } else if (!validateSuperClassIsTypedCorrectly(baseModelElement)) {\n                logger.logError(\n                    baseModelElement,\n                    \"The base model provided to an %s must have View as its type (%s).\",\n                    ModelView::class.java.simpleName, viewName\n                )\n                null\n            } else {\n                baseModelElement\n            }\n        }\n    }\n\n    /** The super class that our generated model extends from must have View as its only type.  */\n    private fun validateSuperClassIsTypedCorrectly(classType: XTypeElement): Boolean {\n        val typeParameters = classType.type.typeArguments\n\n        // TODO: (eli_hart 6/15/17) It should be valid to have multiple or no types as long as they\n        // are correct, but that should be a rare case\n        val typeParam = typeParameters.singleOrNull() ?: return false\n\n        // Any type is allowed, so View wil work\n        return typeParam.isObjectOrAny() ||\n            // If there is no type bound then a View will work\n            typeParam.extendsBound()?.typeElement?.type == null ||\n            // if the bound is Any, then that is fine too.\n            // For some reason this case is different in KSP and needs to be checked for.\n            typeParam.extendsBound()?.typeElement?.type?.isObjectOrAny() == true ||\n            typeParam.isSubTypeOf(viewType)\n    }\n\n    /**\n     * Looks up all of the declared EpoxyAttribute fields on superclasses and returns\n     * attribute info for them.\n     */\n    fun getInheritedEpoxyAttributes(\n        originatingSuperClassType: XType,\n        modelPackage: String,\n        logger: Logger,\n        includeSuperClass: (XTypeElement) -> Boolean = { true }\n    ): List<AttributeInfo> {\n        val result = mutableListOf<AttributeInfo>()\n\n        var currentSuperClassElement: XTypeElement? = originatingSuperClassType.typeElement\n\n        while (currentSuperClassElement != null) {\n            val superClassAttributes = getEpoxyAttributesOnElement(\n                currentSuperClassElement,\n                logger\n            )\n\n            val attributes = superClassAttributes?.superClassAttributes\n\n            if (attributes?.isNotEmpty() == true) {\n                attributes.takeIf {\n                    includeSuperClass(currentSuperClassElement!!)\n                }?.filterTo(result) {\n                    // We can't inherit a package private attribute if we're not in the same package\n                    !it.isPackagePrivate || modelPackage == superClassAttributes.superClassPackage\n                }\n            }\n\n            currentSuperClassElement = currentSuperClassElement.superClass?.typeElement\n        }\n\n        return result\n    }\n\n    data class SuperClassAttributes(\n        val superClassPackage: String,\n        val superClassAttributes: List<AttributeInfo>\n    )\n\n    private val inheritedEpoxyAttributes = mutableMapOf<String, SuperClassAttributes?>()\n\n    private fun getEpoxyAttributesOnElement(\n        classElement: XTypeElement,\n        logger: Logger\n    ): SuperClassAttributes? {\n        return inheritedEpoxyAttributes.getOrPut(classElement.qualifiedName) {\n            if (!classElement.isEpoxyModel(this)) {\n                null\n            } else {\n                val attributes = classElement\n                    .getDeclaredFields()\n                    .filter { it.hasAnnotation(EpoxyAttribute::class) }\n                    .map {\n                        EpoxyProcessor.buildAttributeInfo(\n                            it,\n                            logger,\n                            memoizer = this\n                        )\n                    }\n\n                SuperClassAttributes(\n                    superClassPackage = classElement.packageName,\n                    superClassAttributes = attributes\n                )\n            }\n        }\n    }\n\n    class SuperViewAnnotations(\n        val viewPackageName: String,\n        val annotatedElements: Map<KClass<out Annotation>, List<ViewElement>>\n    )\n\n    class ViewElement(\n        val element: XElement,\n        val isPackagePrivate: Boolean,\n        val attributeInfo: Lazy<ViewAttributeInfo>\n    ) {\n        val simpleName: String by lazy {\n            element.expectName\n        }\n    }\n\n    private val annotationsOnSuperView = mutableMapOf<String, SuperViewAnnotations>()\n\n    fun getAnnotationsOnViewSuperClass(\n        superViewElement: XTypeElement,\n        logger: Logger,\n        resourceProcessor: ResourceScanner\n    ): SuperViewAnnotations {\n        return annotationsOnSuperView.getOrPut(superViewElement.qualifiedName) {\n\n            val viewPackageName = superViewElement.packageName\n            val annotatedElements =\n                mutableMapOf<KClass<out Annotation>, MutableList<ViewElement>>()\n\n            viewModelAnnotations.forEach { annotation ->\n                superViewElement.getElementsAnnotatedWith(annotation).forEach { element ->\n                    annotatedElements\n                        .getOrPut(annotation) { mutableListOf() }\n                        .add(\n                            ViewElement(\n                                element = element,\n                                isPackagePrivate = Utils.isFieldPackagePrivate(element),\n                                attributeInfo = lazy {\n                                    ViewAttributeInfo(\n                                        viewElement = superViewElement,\n                                        viewPackage = viewPackageName,\n                                        hasDefaultKotlinValue = false,\n                                        viewAttributeElement = element,\n                                        logger = logger,\n                                        resourceProcessor = resourceProcessor,\n                                        memoizer = this\n                                    )\n                                }\n                            )\n                        )\n                }\n            }\n\n            SuperViewAnnotations(\n                viewPackageName,\n                annotatedElements\n            )\n        }\n    }\n\n    private val typeMap = mutableMapOf<XType, Type>()\n    fun getType(xType: XType): Type {\n        return typeMap.getOrPut(xType) { Type(xType, this) }\n    }\n\n    private val implementsModelCollectorMap = mutableMapOf<String, Boolean>()\n    fun implementsModelCollector(classElement: XTypeElement): Boolean {\n        return implementsModelCollectorMap.getOrPut(classElement.qualifiedName) {\n                classElement.getSuperInterfaceElements().any {\n                    it.type.isEpoxyModelCollector(this)\n                } || classElement.superClass?.typeElement?.let { superClassElement ->\n                    // Also check the class hierarchy\n                    implementsModelCollector(superClassElement)\n                } ?: false\n        }\n    }\n\n    private val hasViewParentConstructorMap = mutableMapOf<String, Boolean>()\n    fun hasViewParentConstructor(classElement: XTypeElement): Boolean {\n        return hasViewParentConstructorMap.getOrPut(classElement.qualifiedName) {\n            getClassConstructors(classElement, this).any {\n                it.params.size == 1 && it.params[0].type == ClassNames.VIEW_PARENT\n            }\n        }\n    }\n\n    private val typeNameMap = mutableMapOf<TypeName, TypeName>()\n    fun typeNameWithWorkaround(xType: XType): TypeName {\n        // Use xType.typeName as the cache key instead of xType itself, because in KSP 2.0\n        // two different types with wildcards (e.g., List<CharSequence> vs List<? extends CharSequence>)\n        // can have the same equals()/hashCode() but different typeName values.\n        val originalTypeName = xType.typeName\n        if (!isKsp) return originalTypeName\n\n        return typeNameMap.getOrPut(originalTypeName) {\n            // The different subtypes of KSType do different things.\n            if (xType is XArrayType) {\n                return@getOrPut ArrayTypeName.of(xType.componentType.typeNameWithWorkaround(this))\n            }\n\n            val original = xType.typeName\n            if (original.isPrimitive || (xType.isVoidObject() || xType.isVoid())) return@getOrPut original\n\n            when (xType.javaClass.simpleName) {\n                // not sure if type arguments are correct to handle differently, so leaving the original\n                // implementation\n                \"KspTypeArgumentType\" -> return@getOrPut original\n            }\n\n            // Handle the \"DefaultKspType\", which is the main case we are trying to patch.\n            val ksType =\n                xType.getFieldWithReflectionOrNull<KSType>(\"ksType\") ?: return@getOrPut original\n            // always box these. For primitives, typeName might return the primitive type but if we\n            // wanted it to be a primitive, we would've resolved it to [KspPrimitiveType].\n            val env = xType.getFieldWithReflection<XProcessingEnv>(\"env\")\n            val resolver = env.getFieldWithReflection<Resolver>(\"_resolver\")\n            ksType.typeName(resolver).tryBox()\n        }\n    }\n\n    private val lightMethodsMap = mutableMapOf<XTypeElement, List<MethodInfoLight>>()\n\n    /**\n     * A function more efficient way to get basic information about elements, without type resolution.\n     */\n    fun getDeclaredMethodsLight(element: XTypeElement): List<MethodInfoLight> {\n        return lightMethodsMap.getOrPut(element) {\n            if (isKsp) {\n                element.getFieldWithReflection<KSClassDeclaration>(\"declaration\")\n                    .getDeclaredFunctions()\n                    .map {\n                        MethodInfoLight(\n                            name = it.simpleName.asString(),\n                            docComment = it.docString\n                        )\n                    }.toList()\n            } else {\n                element.getDeclaredMethods().map {\n                    MethodInfoLight(\n                        name = it.name,\n                        docComment = it.docComment\n                    )\n                }\n            }\n        }\n    }\n}\n\nprivate val viewModelAnnotations = listOf(\n    ModelProp::class,\n    TextProp::class,\n    CallbackProp::class,\n    AfterPropsSet::class,\n    OnVisibilityChanged::class,\n    OnVisibilityStateChanged::class,\n    OnViewRecycled::class\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/MethodInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XMethodElement\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport javax.lang.model.element.Modifier\n\ndata class MethodInfo(\n    val name: String?,\n    val modifiers: Set<Modifier>,\n    val params: List<ParameterSpec>,\n    val varargs: Boolean,\n    val isEpoxyAttribute: Boolean,\n    val methodElement: XMethodElement\n) {\n    private val paramTypes: List<TypeName> get() = params.map { it.type }\n\n    // Use an equals/hashcode that matches method signature, but doesn't count non signature\n    // changes such as annotations, return type, or param names.\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as MethodInfo\n\n        if (name != other.name) return false\n        if (paramTypes != other.paramTypes) return false\n        if (varargs != other.varargs) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = name?.hashCode() ?: 0\n        result = 31 * result + paramTypes.hashCode()\n        result = 31 * result + varargs.hashCode()\n        return result\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelBuilderInterfaceWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XFiler\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.addOriginatingElement\nimport androidx.room.compiler.processing.writeTo\nimport com.airbnb.epoxy.EpoxyBuildScope\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.JavaFile\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport java.util.concurrent.ConcurrentHashMap\nimport javax.lang.model.element.Modifier\n\nconst val MODEL_BUILDER_INTERFACE_SUFFIX = \"Builder\"\n\n/**\n * Creates an interface for a generated model that contains all of the valid setters for building a\n * model in an EpoxyController. This allows us to expose the interface when building a model and\n * hide all of the non applicable junk that shouldn't be used when building a model (eg equals/bind/toString etc)\n *\n * We can also hide the setters that are legacy from usage with EpoxyAdapter.\n */\nclass ModelBuilderInterfaceWriter(\n    private val filer: XFiler,\n    private val environment: XProcessingEnv,\n    val asyncable: Asyncable,\n    val configManager: ConfigManager,\n) : Asyncable by asyncable {\n\n    private val viewInterfacesToGenerate = ConcurrentHashMap<ClassName, InterfaceDetails>()\n\n    data class InterfaceDetails(\n        val implementingViews: Set<XTypeElement> = emptySet(),\n        val methodsOnInterface: Set<MethodDetails> = emptySet()\n    )\n\n    /** These setters can't be used with models in an EpoxyController, they were made for EpoxyAdapter. */\n    private val blackListedLegacySetterNames = setOf(\"hide\", \"show\", \"reset\")\n\n    fun writeInterface(\n        modelInfo: GeneratedModelInfo,\n        methods: MutableList<MethodSpec>,\n        memoizer: Memoizer\n    ): TypeName {\n\n        val interfaceName = getBuilderInterfaceClassName(modelInfo)\n        val modelInterface = buildInterface(interfaceName) {\n            val interfaceMethods = getInterfaceMethods(modelInfo, methods, interfaceName)\n\n            if (modelInfo is ModelViewInfo) {\n                addOriginatingElement(modelInfo.viewElement)\n\n                modelInfo.viewInterfaces.forEach { it ->\n                    addOriginatingElement(it)\n\n                    val packageName =\n                        configManager.getModelViewConfig(modelInfo.viewElement)?.rClass?.packageName()\n                            ?: it.packageName\n                    val viewInterface =\n                        it.asClassName().toJavaPoet().appendToName(\"Model_\").setPackage(packageName)\n                    addSuperinterface(viewInterface)\n\n                    // Store the subset of methods common to all interface implementations so we\n                    // can generate the interface with the proper methods later\n                    synchronized(viewInterfacesToGenerate) {\n                        viewInterfacesToGenerate.putOrMerge(\n                            viewInterface,\n                            InterfaceDetails(\n                                implementingViews = setOf(modelInfo.viewElement),\n                                methodsOnInterface = interfaceMethods.map { MethodDetails(it) }\n                                    .toSet()\n                            )\n                        ) { details1, details2 ->\n                            InterfaceDetails(\n                                implementingViews = details1.implementingViews + details2.implementingViews,\n                                methodsOnInterface = details1.methodsOnInterface intersect details2.methodsOnInterface\n                            )\n                        }\n                    }\n                }\n            }\n\n            addModifiers(Modifier.PUBLIC)\n            addTypeVariables(modelInfo.typeVariables)\n            addMethods(interfaceMethods)\n            if (!configManager.disableDslMarker) {\n                addAnnotation(EpoxyBuildScope::class.java)\n            }\n\n            val superClassElement = modelInfo.safeSuperClassElement(memoizer)\n            if (memoizer.implementsModelCollector(superClassElement)) {\n                // If the model implements \"ModelCollector\" we want the builder too\n                addSuperinterface(ClassNames.MODEL_COLLECTOR)\n            }\n\n            addOriginatingElement(superClassElement)\n        }\n\n        JavaFile.builder(modelInfo.generatedName.packageName(), modelInterface)\n            .build()\n            .writeTo(filer, mode = XFiler.Mode.Aggregating)\n\n        return getBuilderInterfaceTypeName(modelInfo)\n    }\n\n    private fun getInterfaceMethods(\n        modelInfo: GeneratedModelInfo,\n        methods: MutableList<MethodSpec>,\n        interfaceName: ClassName\n    ): List<MethodSpec> {\n        return methods\n            .asSequence()\n            .filter {\n                !it.hasModifier(Modifier.STATIC)\n            }\n            .filter {\n                it.returnType == modelInfo.parameterizedGeneratedName\n            }\n            .filter {\n                !blackListedLegacySetterNames.contains(it.name)\n            }\n            .filter {\n                // Layout throws an exception for programmatic views, so we might a well leave it out too\n                !(modelInfo.isProgrammaticView && it.name == \"layout\")\n            }\n            .map {\n                it.copy(\n                    // We have the methods return the interface type instead of the model, so\n                    // that subclasses of the model can also implement this interface\n                    returns = interfaceName,\n                    additionalModifiers = listOf(Modifier.ABSTRACT)\n                )\n            }\n            .toList()\n    }\n\n    /**\n     * We need to gather information about all of the view interfaces first, and then write the interface classes.\n     */\n    fun writeFilesForViewInterfaces() {\n        // For each interface we figure out which methods to add to it by getting the largest subset of props supported by all models with the interface.\n        // This approach has a few advantages:\n        // 1. Easily inherit TextProp and other overloads\n        // 2. Inherit base model props like id\n        // 3. Don't have to figure out if a prop matches an interface method exactly (eg the model method is \"clickable\" but the interface method is \"setClickable\")\n        // This means that the generated interface won't necessarily map exactly to the original view interface\n        // It just represents the set of props shared by all models with that view interface, which should be all we need in practice.\n\n        viewInterfacesToGenerate.forEach(\"write view interface\") { interfaceName, details ->\n            val interfaceSpec = buildInterface(interfaceName) {\n                addModifiers(Modifier.PUBLIC)\n\n                addMethods(\n                    details.methodsOnInterface.map {\n                        it.methodSpec.copy {\n                            returns(interfaceName)\n                        }\n                    }\n                        // For cache consistency of generated files make sure these are sorted.\n                        // Methods may have the same name due to overloads, so also sorting by\n                        // hashcode.\n                        .sortedWith(compareBy({ it.name }, { it.hashCode() }))\n                )\n\n                details.implementingViews.forEach {\n                    // Note: If a brand new model view class is added that implements this interface\n                    // it could affect which methods are included on the generated interface since\n                    // we use an intersection. If that happens the incremental compiler may not know\n                    // that this file was affected, or the incremental annotation processing may\n                    // in some way not work correctly. We ignore this possible bug for now as it\n                    // would be very rare and there isn't much we can do without a large breaking\n                    // change to how the interface generation works.\n                    addOriginatingElement(it)\n                }\n            }\n\n            val implementingViewTypeElement = details.implementingViews.firstOrNull()\n            val packageName = implementingViewTypeElement?.let {\n                configManager.getModelViewConfig(it)?.rClass?.packageName()\n            } ?: interfaceName.packageName()\n            JavaFile.builder(packageName, interfaceSpec)\n                .build()\n                .writeTo(filer, mode = XFiler.Mode.Aggregating)\n        }\n\n        viewInterfacesToGenerate.clear()\n    }\n\n    /** A wrapper around MethodSpec that allows us to compare methods with equality that only\n     * checks name and param types. This prevents things like annotations and param name from\n     * affecting equality, and gets us closer to checking the actual method signature.\n     * */\n    class MethodDetails(val methodSpec: MethodSpec) {\n        val name = methodSpec.name!!\n        val params = methodSpec.parameters.map { ParamDetails(it) }\n\n        override fun equals(other: Any?): Boolean {\n            if (this === other) return true\n            if (other !is MethodDetails) return false\n\n            if (name != other.name) return false\n            if (params != other.params) return false\n\n            return true\n        }\n\n        override fun hashCode(): Int {\n            var result = name.hashCode()\n            result = 31 * result + params.hashCode()\n            return result\n        }\n    }\n\n    /** A wrapper around ParameterSpec that allows us to compare params with equality that only\n     * checks param type. This prevents things like annotations and param name from\n     * affecting equality.\n     * */\n    class ParamDetails(val parameterSpec: ParameterSpec) {\n        val type = parameterSpec.type!!\n\n        override fun equals(other: Any?): Boolean {\n            if (this === other) return true\n            if (other !is ParamDetails) return false\n\n            if (type != other.type) return false\n\n            return true\n        }\n\n        override fun hashCode() = type.hashCode()\n    }\n}\n\ninternal fun getBuilderInterfaceTypeName(modelInfo: GeneratedModelInfo): TypeName {\n    val interfaceClassName = getBuilderInterfaceClassName(modelInfo)\n\n    val types: Array<TypeName> = modelInfo.typeVariableNames.toTypedArray()\n    return if (types.isEmpty()) {\n        interfaceClassName\n    } else {\n        ParameterizedTypeName.get(interfaceClassName, *types)\n    }\n}\n\ninternal fun getBuilderInterfaceClassName(modelInfo: GeneratedModelInfo): ClassName {\n    val generatedModelName = modelInfo.generatedName\n\n    return ClassName.get(\n        generatedModelName.packageName(),\n        generatedModelName.simpleName().removeSuffix(\"_\").replace(\n            \"$\",\n            \"_\"\n        ) + MODEL_BUILDER_INTERFACE_SUFFIX\n    )\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.isVoid\nimport androidx.room.compiler.processing.isVoidObject\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceValue\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ParameterizedTypeName\nimport java.util.Collections\n\nclass ModelViewInfo(\n    val viewElement: XTypeElement,\n    private val environment: XProcessingEnv,\n    val logger: Logger,\n    private val configManager: ConfigManager,\n    private val resourceProcessor: ResourceScanner,\n    memoizer: Memoizer\n) : GeneratedModelInfo(memoizer) {\n\n    val resetMethodNames = Collections.synchronizedSet(mutableSetOf<String>())\n    val visibilityStateChangedMethodNames = Collections.synchronizedSet(mutableSetOf<String>())\n    val visibilityChangedMethodNames = Collections.synchronizedSet(mutableSetOf<String>())\n    val afterPropsSetMethodNames = Collections.synchronizedSet(mutableSetOf<String>())\n    private val viewAnnotation = viewElement.requireAnnotation(ModelView::class)\n\n    val saveViewState: Boolean\n    val fullSpanSize: Boolean\n    private val generatedModelSuffix: String\n\n    /** All interfaces the view implements that have at least one prop set by the interface. */\n    val viewInterfaces: List<XTypeElement>\n\n    val viewAttributes: List<ViewAttributeInfo>\n        get() = attributeInfo.filterIsInstance<ViewAttributeInfo>()\n\n    init {\n        superClassElement = lookUpSuperClassElement()\n        this.superClassName = ParameterizedTypeName\n            .get(superClassElement.asClassName().toJavaPoet(), viewElement.type.typeNameWithWorkaround(memoizer))\n\n        generatedModelSuffix = configManager.generatedModelSuffix(viewElement)\n        generatedName = buildGeneratedModelName(viewElement)\n        // We don't have any type parameters on our generated model\n        this.parameterizedGeneratedName = generatedName\n        shouldGenerateModel = !viewElement.isAbstract()\n\n        if (\n            superClassElement.name != ClassNames.EPOXY_MODEL_UNTYPED.simpleName()\n        ) {\n            // If the view has a custom base model then we copy any custom constructors on it\n            constructors.addAll(getClassConstructors(safeSuperClassElement(memoizer)))\n        }\n\n        collectMethodsReturningClassType(safeSuperClassElement(memoizer))\n\n        // The bound type is the type of this view\n        modelType = viewElement.type.typeName\n\n        saveViewState = viewAnnotation.getAsBoolean(\"saveViewState\")\n        layoutParams = ModelView.Size.valueOf(viewAnnotation.getAsEnum(\"autoLayout\").name)\n        fullSpanSize = viewAnnotation.getAsBoolean(\"fullSpan\")\n        includeOtherLayoutOptions = configManager.includeAlternateLayoutsForViews(viewElement)\n\n        val methodsOnView = viewElement.getDeclaredMethods()\n        viewInterfaces = viewElement\n            .getSuperInterfaceElements()\n            .filter { interfaceElement ->\n                // Only include the interface if the view has one of the interface methods annotated with a prop annotation\n                val interfaceMethods = interfaceElement.getDeclaredMethods()\n                methodsOnView.any { viewMethod ->\n                    viewMethod.hasAnyAnnotation(*ModelViewProcessor.modelPropAnnotationsArray) &&\n                        interfaceMethods.any { interfaceMethod ->\n                            // To keep this simple we only compare name and ignore parameters, should be close enough\n                            viewMethod.name == interfaceMethod.name\n                        }\n                }\n            }\n\n        // Pass deprecated annotations on to the generated model\n        annotations.addAll(\n            viewElement.buildAnnotationSpecs({ DEPRECATED == it.simpleName() }, memoizer)\n        )\n    }\n\n    private fun lookUpSuperClassElement(): XTypeElement {\n        val classToExtend = viewAnnotation.getAsType(\"baseModelClass\")\n            ?.takeIf { !it.isVoidObject() && !it.isVoid() }\n            ?: configManager.getDefaultBaseModel(viewElement, environment)\n            ?: return memoizer.epoxyModelClassElementUntyped\n\n        val superElement =\n            memoizer.validateViewModelBaseClass(classToExtend, logger, viewElement.name)\n\n        return superElement ?: memoizer.epoxyModelClassElementUntyped\n    }\n\n    private fun buildGeneratedModelName(\n        viewElement: XTypeElement,\n    ): ClassName {\n        val packageName = viewElement.packageName\n\n        var className = viewElement.name\n        className += generatedModelSuffix\n\n        return ClassName.get(packageName, className)\n    }\n\n    fun buildProp(prop: XElement): ViewAttributeInfo {\n\n        val hasDefaultKotlinValue = checkIsSetterWithSingleDefaultParam(prop)\n\n        // Since our generated code is java we need jvmoverloads so that a no arg\n        // version of the function is generated. However, the JvmOverloads annotation\n        // is stripped when generating the java code so we can't check it directly (but it is available in KSP).\n        // Instead, we verify that a no arg function of the same name exists\n        val hasNoArgEquivalent = hasDefaultKotlinValue &&\n            prop is XMethodElement &&\n            (prop.hasAnnotation(JvmOverloads::class) || viewElement.hasOverload(prop, 0))\n\n        if (hasDefaultKotlinValue && !hasNoArgEquivalent) {\n            logger.logError(\n                prop,\n                \"Model view function with default argument must be annotated with @JvmOverloads: %s#%s\",\n                viewElement.name,\n                prop\n            )\n        }\n\n        return ViewAttributeInfo(\n            viewElement = viewElement,\n            viewPackage = generatedName.packageName(),\n            hasDefaultKotlinValue = hasDefaultKotlinValue && hasNoArgEquivalent,\n            viewAttributeElement = prop,\n            logger = logger,\n            resourceProcessor = resourceProcessor,\n            memoizer = memoizer\n        )\n    }\n\n    fun addOnRecycleMethod(methodName: String) {\n        resetMethodNames.add(methodName)\n    }\n\n    fun addOnVisibilityStateChangedMethod(methodName: String) {\n        visibilityStateChangedMethodNames.add(methodName)\n    }\n\n    fun addOnVisibilityChangedMethod(methodName: String) {\n        visibilityChangedMethodNames.add(methodName)\n    }\n\n    fun addAfterPropsSetMethod(methodName: String) {\n        afterPropsSetMethodNames.add(methodName)\n    }\n\n    fun getLayoutResource(resourceProcessor: ResourceScanner): ResourceValue {\n        val annotation = viewElement.requireAnnotation(ModelView::class)\n        val layoutValue = annotation.getAsInt(\"defaultLayout\")\n        if (layoutValue != 0) {\n            return resourceProcessor.getResourceValue(ModelView::class, viewElement, \"defaultLayout\")\n                ?: error(\"ModelView default layout not found for $viewElement\")\n        }\n\n        val modelViewConfig = configManager.getModelViewConfig(viewElement)\n\n        if (modelViewConfig != null) {\n            return modelViewConfig.getNameForView(viewElement)\n        }\n\n        logger.logError(viewElement, \"Unable to get layout resource for view %s\", viewElement.name)\n        return ResourceValue(0)\n    }\n\n    private fun checkIsSetterWithSingleDefaultParam(element: XElement): Boolean {\n        if (element !is XMethodElement) return false\n        return element.parameters.singleOrNull()?.hasDefaultValue == true\n    }\n\n    override fun additionalOriginatingElements(currentMemoizer: Memoizer) = listOf(viewElement)\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewProcessor.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XExecutableElement\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRoundEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.XVariableElement\nimport com.airbnb.epoxy.AfterPropsSet\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.OnViewRecycled\nimport com.airbnb.epoxy.OnVisibilityChanged\nimport com.airbnb.epoxy.OnVisibilityStateChanged\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.processor.Utils.validateFieldAccessibleViaGeneratedCode\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.squareup.javapoet.TypeName\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType\nimport java.util.HashMap\nimport java.util.HashSet\nimport java.util.concurrent.ConcurrentHashMap\nimport javax.tools.Diagnostic\nimport kotlin.contracts.contract\nimport kotlin.reflect.KClass\n\nclass ModelViewProcessorProvider : SymbolProcessorProvider {\n    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {\n        return ModelViewProcessor(environment)\n    }\n}\n\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING)\nclass ModelViewProcessor @JvmOverloads constructor(\n    kspEnvironment: SymbolProcessorEnvironment? = null\n) : BaseProcessorWithPackageConfigs(kspEnvironment) {\n\n    override val usesPackageEpoxyConfig: Boolean = false\n    override val usesModelViewConfig: Boolean = true\n\n    private val modelClassMap = ConcurrentHashMap<XTypeElement, ModelViewInfo>()\n    private val styleableModelsToWrite = mutableListOf<ModelViewInfo>()\n\n    override fun additionalSupportedAnnotations(): List<KClass<*>> = listOf(\n        ModelView::class,\n        TextProp::class,\n        CallbackProp::class\n    )\n\n    override fun processRound(\n        environment: XProcessingEnv,\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        timer: Timer,\n        roundNumber: Int\n    ): List<XElement> {\n        super.processRound(environment, round, memoizer, timer, roundNumber)\n        timer.markStepCompleted(\"package config processing\")\n\n        // We have a very common case of needing to wait for Paris styleables to be generated before\n        // we can fully process our models and generate code. To support this we need to tell KSP to\n        // defer symbols. However, this also causes KSP to reprocess the same annotations and create\n        // duplicates if we try to save the previous models, and with KSP it is also not valid to use\n        // symbols across rounds and that can cause errors.\n        // Java AP on the other hand will not reprocess annotated elements so we need to hold on to\n        // them across rounds.\n        // To support this case in an efficient way in KSP we check for any Paris dependencies and\n        // bail ASAP in that case to avoid reprocessing as much as possible.\n        // Paris only ever generates code in the first round, so it should be safe to rely on this.\n        val shouldDeferElementsIfHasParisDependency = isKsp() && roundNumber == 1\n        val elementsToDefer =\n            processViewAnnotations(round, memoizer, shouldDeferElementsIfHasParisDependency)\n\n        timer.markStepCompleted(\"process View Annotations\")\n\n        if (elementsToDefer.isNotEmpty()) {\n            return elementsToDefer\n        }\n\n        // Avoid doing the work to look up the rest of the annotations in model view classes\n        // if no new  model view classes were found.\n        if (modelClassMap.isNotEmpty()) {\n            val classTypes = modelClassMap.keys.toList()\n            processSetterAnnotations(classTypes, memoizer)\n            timer.markStepCompleted(\"process setter Annotations\")\n\n            processResetAnnotations(classTypes, memoizer)\n            timer.markStepCompleted(\"process reset Annotations\")\n\n            processVisibilityStateChangedAnnotations(classTypes, memoizer)\n            processVisibilityChangedAnnotations(classTypes, memoizer)\n            timer.markStepCompleted(\"process visibility Annotations\")\n\n            processAfterBindAnnotations(classTypes, memoizer)\n            timer.markStepCompleted(\"process after bind Annotations\")\n\n            updateViewsForInheritedViewAnnotations(memoizer)\n            timer.markStepCompleted(\"update For Inherited Annotations\")\n\n            // Group overloads after inheriting methods from super classes so those can be included in\n            // the groups as well.\n            groupOverloads()\n            timer.markStepCompleted(\"group overloads\")\n\n            // Up until here our code generation has assumed that that all attributes in a group are\n            // view attributes (and not attributes inherited from a base model class), so this should be\n            // done after grouping attributes, and these attributes should not be grouped.\n            // No code to bind these attributes is generated, as it is assumed that the original model\n            // handles its own bind (also we can't know how to bind these).\n            updatesViewsForInheritedBaseModelAttributes(memoizer)\n            timer.markStepCompleted(\"updates for inherited Attributes\")\n\n            addStyleAttributes()\n            timer.markStepCompleted(\"add style attributes\")\n        }\n\n        // This may write previously generated models that were waiting for their style builder\n        // to be generated.\n        writeJava(environment, memoizer, timer)\n\n        generatedModels.addAll(modelClassMap.values)\n        modelClassMap.clear()\n\n        if (roundNumber > 2 && styleableModelsToWrite.isNotEmpty()) {\n            messager.printMessage(\n                Diagnostic.Kind.ERROR,\n                \"Unable to find Paris generated code for styleable Epoxy models. Is Paris configured correctly?\"\n            )\n        }\n\n        return emptyList()\n    }\n\n    private fun processViewAnnotations(\n        round: XRoundEnv,\n        memoizer: Memoizer,\n        shouldDeferElementsIfHasParisDependency: Boolean\n    ): List<XElement> {\n        val modelViewElements = round.getElementsAnnotatedWith(ModelView::class)\n\n        if (shouldDeferElementsIfHasParisDependency && modelViewElements.any { it.hasStyleableAnnotation() }) {\n            return modelViewElements.toList()\n        }\n\n        modelViewElements\n            .forEach(\"processViewAnnotations\") { viewElement ->\n                if (!validateViewElement(viewElement, memoizer)) {\n                    return@forEach\n                }\n\n                modelClassMap[viewElement] = ModelViewInfo(\n                    viewElement,\n                    environment,\n                    logger,\n                    configManager,\n                    resourceProcessor,\n                    memoizer\n                )\n            }\n\n        return emptyList()\n    }\n\n    private fun validateViewElement(viewElement: XElement, memoizer: Memoizer): Boolean {\n        contract {\n            returns(true) implies (viewElement is XTypeElement)\n        }\n        if (viewElement !is XTypeElement) {\n            logger.logError(\n                \"${ModelView::class.simpleName} annotations can only be on a class\",\n                viewElement\n            )\n            return false\n        }\n\n        if (viewElement.isPrivate()) {\n            logger.logError(\n                \"${ModelView::class.simpleName} annotations must not be on private classes.\",\n                viewElement\n            )\n            return false\n        }\n\n        // Nested classes must be static\n        if (viewElement.enclosingTypeElement != null) {\n            logger.logError(\n                \"Classes with ${ModelView::class.java} annotations cannot be nested.\",\n                viewElement\n            )\n            return false\n        }\n\n        if (!viewElement.type.isSubTypeOf(memoizer.androidViewType)) {\n            logger.logError(\n                \"Classes with ${ModelView::class.java} annotations must extend \" +\n                    \"android.view.View.\",\n                viewElement\n            )\n            return false\n        }\n\n        return true\n    }\n\n    private fun processSetterAnnotations(classTypes: List<XTypeElement>, memoizer: Memoizer) {\n        for (propAnnotation in modelPropAnnotations) {\n            classTypes.getElementsAnnotatedWith(propAnnotation).mapNotNull { prop ->\n                val enclosingElement = prop.enclosingTypeElement ?: return@mapNotNull null\n                // Interfaces can use model property annotations freely, they will be processed if\n                // and when implementors of that interface are processed. This is particularly\n                // useful for Kotlin delegation where the model view class may not be overriding\n                // the interface properties directly, and so doesn't have an opportunity to annotate\n                // them with Epoxy model property annotations.\n                if (enclosingElement.isInterface()) {\n                    return@mapNotNull null\n                }\n\n                val info = getModelInfoForPropElement(prop)\n                if (info == null) {\n                    logger.logError(\n                        \"${propAnnotation.simpleName} annotation can only be used in classes \" +\n                            \"annotated with ${ModelView::class.java.simpleName} \" +\n                            \"(${enclosingElement.name}#$prop)\",\n                        prop\n                    )\n                    return@mapNotNull null\n                }\n\n                // JvmOverloads is used on properties with default arguments, which we support.\n                // However, the generated no arg version of the function will also have the\n                // @ModelProp annotation so we need to ignore it when it is processed.\n                // However, the JvmOverloads annotation is removed in the java class so we need\n                // to manually look for a valid overload function.\n                if (prop is XMethodElement &&\n                    prop.parameters.isEmpty() &&\n                    info.viewElement.findOverload(\n                            prop,\n                            1\n                        )?.hasAnyAnnotation(*modelPropAnnotationsArray) == true\n                ) {\n                    return@mapNotNull null\n                }\n\n                if (!validatePropElement(prop, propAnnotation.java, memoizer)) {\n                    return@mapNotNull null\n                }\n\n                info.buildProp(prop) to info\n            }.forEach { (viewProp, modelInfo) ->\n                // This is done synchronously after the parallel prop building so that we\n                // have all props in the order they are listed in the view.\n                // This keeps a consistent ordering despite the parallel execution, which is necessary\n                // for consistent generated code as well as consistent prop binding order (which\n                // people are not supposed to rely on, but inevitably do, and we want to avoid breaking\n                // that by changing the ordering).\n                modelInfo.addAttribute(viewProp)\n            }\n        }\n    }\n\n    private fun groupOverloads() {\n        modelClassMap.values.forEach { viewInfo ->\n            val attributeGroups = HashMap<String, MutableList<AttributeInfo>>()\n\n            // Track which groups are created manually by the user via a group annotation param.\n            // We use this to check that more than one setter is in the group, since otherwise it\n            // doesn't make sense to have a group and there is likely a typo we can catch for them\n            val customGroups = HashSet<String>()\n\n            for (attributeInfo in viewInfo.attributeInfo) {\n                val setterInfo = attributeInfo as ViewAttributeInfo\n\n                var groupKey = setterInfo.groupKey!!\n                if (groupKey.isEmpty()) {\n                    // Default to using the method name as the group name, so method overloads are\n                    // grouped together by default\n                    groupKey = setterInfo.viewAttributeName\n                } else {\n                    customGroups.add(groupKey)\n                }\n\n                attributeGroups\n                    .getOrPut(groupKey) { mutableListOf() }\n                    .add(attributeInfo)\n            }\n\n            for (customGroup in customGroups) {\n                attributeGroups[customGroup]?.let {\n                    if (it.size == 1) {\n                        val attribute = it[0] as ViewAttributeInfo\n                        logger.logError(\n                            \"Only one setter was included in the custom group \" +\n                                \"'$customGroup' at ${viewInfo.viewElement.name}#\" +\n                                \"${attribute.viewAttributeName}. Groups should have at \" +\n                                \"least 2 setters.\"\n                        )\n                    }\n                }\n            }\n\n            for ((groupKey, groupAttributes) in attributeGroups) {\n                viewInfo.addAttributeGroup(groupKey, groupAttributes)\n            }\n        }\n    }\n\n    private fun validatePropElement(\n        prop: XElement,\n        propAnnotation: Class<out Annotation>,\n        memoizer: Memoizer\n    ): Boolean {\n        return when (prop) {\n            is XExecutableElement -> validateExecutableElement(\n                prop,\n                propAnnotation,\n                1,\n                memoizer = memoizer\n            )\n            is XVariableElement -> validateVariableElement(prop, propAnnotation)\n            else -> {\n                logger.logError(\n                    prop,\n                    \"%s annotations can only be on a method or a field(element: %s)\",\n                    propAnnotation,\n                    prop\n                )\n                return false\n            }\n        }\n    }\n\n    private fun validateVariableElement(\n        field: XVariableElement,\n        annotationClass: Class<*>\n    ): Boolean {\n        return validateFieldAccessibleViaGeneratedCode(\n            field,\n            annotationClass,\n            logger\n        )\n    }\n\n    private fun validateExecutableElement(\n        element: XElement,\n        annotationClass: Class<*>,\n        paramCount: Int,\n        checkTypeParameters: List<TypeName>? = null,\n        memoizer: Memoizer\n    ): Boolean {\n        contract {\n            returns(true) implies (element is XMethodElement)\n        }\n\n        if (element !is XMethodElement) {\n            logger.logError(\n                element,\n                \"%s annotations can only be on a method (element: %s)\",\n                annotationClass::class.java.simpleName,\n                element\n            )\n            return false\n        }\n\n        val parameters = element.parameters\n        if (parameters.size != paramCount) {\n            logger.logError(\n                element,\n                \"Methods annotated with %s must have exactly %s parameter (method: %s)\",\n                annotationClass::class.java.simpleName, paramCount, element.name\n            )\n            return false\n        }\n\n        checkTypeParameters?.let { expectedTypeParameters ->\n            // Check also the parameter types\n            var hasErrors = false\n            parameters.forEachIndexed { i, parameter ->\n                val typeName = parameter.type.typeNameWithWorkaround(memoizer)\n                val expectedType = expectedTypeParameters[i]\n                hasErrors = hasErrors ||\n                    (typeName != expectedType.box() && typeName != expectedType.unbox())\n            }\n            if (hasErrors) {\n                logger.logError(\n                    element,\n                    \"Methods annotated with %s must have parameter types %s, \" +\n                        \"found: %s (method: %s)\",\n                    annotationClass::class.java.simpleName,\n                    expectedTypeParameters,\n                    parameters.map { it.type },\n                    element.name\n                )\n            }\n        }\n\n        if (element.isStatic() || element.isPrivate()) {\n            logger.logError(\n                element,\n                \"Methods annotated with %s cannot be private or static (method: %s)\",\n                annotationClass::class.java.simpleName, element.name\n            )\n            return false\n        }\n\n        return true\n    }\n\n    private fun processResetAnnotations(classTypes: List<XTypeElement>, memoizer: Memoizer) {\n        classTypes.getElementsAnnotatedWith(OnViewRecycled::class).mapNotNull { recycleMethod ->\n            if (!validateResetElement(recycleMethod, memoizer)) {\n                return@mapNotNull null\n            }\n\n            val info = getModelInfoForPropElement(recycleMethod)\n            if (info == null) {\n                logger.logError(\n                    \"%s annotation can only be used in classes annotated with %s\",\n                    OnViewRecycled::class.java, ModelView::class.java\n                )\n                return@mapNotNull null\n            }\n\n            recycleMethod.expectName to info\n        }.forEach { (methodName, modelInfo) ->\n            // Do this after, synchronously, to preserve function ordering in the view.\n            // If there are multiple functions with this annotation this allows them\n            // to be called in predictable order from top to bottom of the class, which\n            // some users may depend on.\n            modelInfo.addOnRecycleMethod(methodName)\n        }\n    }\n\n    private fun processVisibilityStateChangedAnnotations(\n        classTypes: List<XTypeElement>,\n        memoizer: Memoizer\n    ) {\n        classTypes.getElementsAnnotatedWith(OnVisibilityStateChanged::class)\n            .mapNotNull { visibilityMethod ->\n                if (!validateVisibilityStateChangedElement(visibilityMethod, memoizer)) {\n                    return@mapNotNull null\n                }\n\n                val info = getModelInfoForPropElement(visibilityMethod)\n                if (info == null) {\n                    logger.logError(\n                        \"%s annotation can only be used in classes annotated with %s\",\n                        OnVisibilityStateChanged::class.java, ModelView::class.java\n                    )\n                    return@mapNotNull null\n                }\n\n                visibilityMethod.expectName to info\n            }.forEach { (methodName, modelInfo) ->\n                // Do this after, synchronously, to preserve function ordering in the view.\n                // If there are multiple functions with this annotation this allows them\n                // to be called in predictable order from top to bottom of the class, which\n                // some users may depend on.\n                modelInfo.addOnVisibilityStateChangedMethod(methodName)\n            }\n    }\n\n    private fun processVisibilityChangedAnnotations(\n        classTypes: List<XTypeElement>,\n        memoizer: Memoizer\n    ) {\n        classTypes.getElementsAnnotatedWith(OnVisibilityChanged::class).mapNotNull { visibilityMethod ->\n            if (!validateVisibilityChangedElement(visibilityMethod, memoizer)) {\n                return@mapNotNull null\n            }\n\n            val info = getModelInfoForPropElement(visibilityMethod)\n            if (info == null) {\n                logger.logError(\n                    visibilityMethod,\n                    \"%s annotation can only be used in classes annotated with %s\",\n                    OnVisibilityChanged::class.java, ModelView::class.java\n                )\n                return@mapNotNull null\n            }\n\n            visibilityMethod.expectName to info\n        }.forEach { (methodName, modelInfo) ->\n            // Do this after, synchronously, to preserve function ordering in the view.\n            // If there are multiple functions with this annotation this allows them\n            // to be called in predictable order from top to bottom of the class, which\n            // some users may depend on.\n            modelInfo.addOnVisibilityChangedMethod(methodName)\n        }\n    }\n\n    private fun processAfterBindAnnotations(classTypes: List<XTypeElement>, memoizer: Memoizer) {\n        classTypes.getElementsAnnotatedWith(AfterPropsSet::class).mapNotNull { afterPropsMethod ->\n            if (!validateAfterPropsMethod(afterPropsMethod, memoizer)) {\n                return@mapNotNull null\n            }\n\n            val info = getModelInfoForPropElement(afterPropsMethod)\n            if (info == null) {\n                logger.logError(\n                    afterPropsMethod,\n                    \"%s annotation can only be used in classes annotated with %s\",\n                    AfterPropsSet::class.java, ModelView::class.java\n                )\n                return@mapNotNull null\n            }\n\n            afterPropsMethod.expectName to info\n        }.forEach { (methodName, modelInfo) ->\n            // Do this after, synchronously, to preserve function ordering in the view.\n            // If there are multiple functions with this annotation this allows them\n            // to be called in predictable order from top to bottom of the class, which\n            // some users may depend on.\n            modelInfo.addAfterPropsSetMethod(methodName)\n        }\n    }\n\n    private fun validateAfterPropsMethod(method: XElement, memoizer: Memoizer): Boolean {\n        contract {\n            returns(true) implies (method is XMethodElement)\n        }\n        return validateExecutableElement(method, AfterPropsSet::class.java, 0, memoizer = memoizer)\n    }\n\n    /** Include props and reset methods from super class views.  */\n    private fun updateViewsForInheritedViewAnnotations(memoizer: Memoizer) {\n\n        modelClassMap.values.forEach { view ->\n            // We walk up the super class tree and look for any elements with epoxy annotations.\n            // This approach lets us capture views that we've already processed as well as views\n            // in other libraries that we wouldn't have otherwise processed.\n\n            view.viewElement.iterateSuperClasses { superViewElement ->\n                val annotationsOnViewSuperClass = memoizer.getAnnotationsOnViewSuperClass(\n                    superViewElement,\n                    logger,\n                    resourceProcessor\n                )\n\n                val isSamePackage by lazy {\n                    annotationsOnViewSuperClass.viewPackageName == view.viewElement.packageName\n                }\n\n                fun forEachElementWithAnnotation(\n                    annotations: List<KClass<out Annotation>>,\n                    function: (Memoizer.ViewElement) -> Unit\n                ) {\n\n                    annotationsOnViewSuperClass.annotatedElements\n                        .filterKeys { annotation ->\n                            annotation in annotations\n                        }\n                        .values\n                        .flatten()\n                        .filter { viewElement ->\n                            isSamePackage || !viewElement.isPackagePrivate\n                        }\n                        .forEach {\n                            function(it)\n                        }\n                }\n\n                forEachElementWithAnnotation(modelPropAnnotations) {\n                    // todo Include view interfaces for the super class in this model\n                    // 1. we should only do that if all methods in the super class are accessible to this (ie not package private and in a different package)\n                    // 2. We also need to handle the case the that super view is abstract - right now interfaces are not generated for abstract views\n                    // 3. If an abstract view only implements part of the interface it would mess up the way we check which methods count in the interface\n\n                    // We don't want the attribute from the super class replacing an attribute in the\n                    // subclass if the subclass overrides it, since the subclass definition could include\n                    // different annotation parameter settings, or we could end up with duplicates\n\n                    // If an annotated prop method has a default value it will also have @JvmOverloads\n                    // so java source in KAPT sees both a zero param and and 1 param method. We just\n                    // ignore the empty param version.\n                    if (it.element is XMethodElement && it.element.parameters.size != 1) {\n                        return@forEachElementWithAnnotation\n                    }\n\n                    view.addAttributeIfNotExists(it.attributeInfo.value)\n                }\n\n                forEachElementWithAnnotation(listOf(OnViewRecycled::class)) {\n                    view.addOnRecycleMethod(it.simpleName)\n                }\n\n                forEachElementWithAnnotation(listOf(OnVisibilityStateChanged::class)) {\n                    view.addOnVisibilityStateChangedMethod(it.simpleName)\n                }\n\n                forEachElementWithAnnotation(listOf(OnVisibilityChanged::class)) {\n                    view.addOnVisibilityChangedMethod(it.simpleName)\n                }\n\n                forEachElementWithAnnotation(listOf(AfterPropsSet::class)) {\n                    view.addAfterPropsSetMethod(it.simpleName)\n                }\n            }\n        }\n    }\n\n    /**\n     * If a view defines a base model that its generated model should extend we need to check if that\n     * base model has [com.airbnb.epoxy.EpoxyAttribute] fields and include those in our model if\n     * so.\n     */\n    private fun updatesViewsForInheritedBaseModelAttributes(memoizer: Memoizer) {\n        modelClassMap.values.forEach { modelViewInfo ->\n            // Skip generated model super classes since it will already contain all of the functions\n            // necessary for included attributes, and duplicating them is a waste.\n            if (modelViewInfo.isSuperClassAlsoGenerated(memoizer)) return@forEach\n\n            memoizer.getInheritedEpoxyAttributes(\n                modelViewInfo.safeSuperClassElement(memoizer).type,\n                modelViewInfo.generatedName.packageName(),\n                logger\n            ).let { modelViewInfo.addAttributes(it) }\n        }\n    }\n\n    private fun addStyleAttributes() {\n        modelClassMap\n            .values\n            .filter(\"addStyleAttributes\") { it.viewElement.hasStyleableAnnotation() }\n            .also { styleableModelsToWrite.addAll(it) }\n    }\n\n    private fun validateResetElement(resetMethod: XElement, memoizer: Memoizer): Boolean {\n        contract {\n            returns(true) implies (resetMethod is XMethodElement)\n        }\n        return validateExecutableElement(\n            resetMethod,\n            OnViewRecycled::class.java,\n            0,\n            memoizer = memoizer\n        )\n    }\n\n    private fun validateVisibilityStateChangedElement(\n        visibilityMethod: XElement,\n        memoizer: Memoizer\n    ): Boolean {\n        contract {\n            returns(true) implies (visibilityMethod is XMethodElement)\n        }\n\n        return validateExecutableElement(\n            visibilityMethod,\n            OnVisibilityStateChanged::class.java,\n            1,\n            checkTypeParameters = listOf(TypeName.INT),\n            memoizer = memoizer\n        )\n    }\n\n    private fun validateVisibilityChangedElement(visibilityMethod: XElement, memoizer: Memoizer): Boolean {\n        contract {\n            returns(true) implies (visibilityMethod is XMethodElement)\n        }\n\n        return validateExecutableElement(\n            visibilityMethod,\n            OnVisibilityChanged::class.java,\n            4,\n            checkTypeParameters = listOf(TypeName.FLOAT, TypeName.FLOAT, TypeName.INT, TypeName.INT),\n            memoizer = memoizer\n        )\n    }\n\n    private fun writeJava(processingEnv: XProcessingEnv, memoizer: Memoizer, timer: Timer) {\n        val modelsToWrite = modelClassMap.values.toMutableList()\n        modelsToWrite.removeAll(styleableModelsToWrite)\n\n        val hasStyleableModels = styleableModelsToWrite.isNotEmpty()\n\n        styleableModelsToWrite.filter {\n            tryAddStyleBuilderAttribute(it, processingEnv, memoizer)\n        }.let {\n            modelsToWrite.addAll(it)\n            styleableModelsToWrite.removeAll(it)\n        }\n        if (hasStyleableModels) {\n            timer.markStepCompleted(\"update models with Paris Styleable builder\")\n        }\n\n        val modelWriter = createModelWriter(memoizer)\n        ModelViewWriter(modelWriter, this)\n            .writeModels(modelsToWrite, originatingConfigElements(), memoizer)\n\n        if (styleableModelsToWrite.isEmpty()) {\n            // Make sure all models have been processed and written before we generate interface information\n            modelWriter.writeFilesForViewInterfaces()\n        }\n\n        timer.markStepCompleted(\"write generated files\")\n    }\n\n    private fun getModelInfoForPropElement(element: XElement): ModelViewInfo? =\n        element.enclosingTypeElement?.let { modelClassMap[it] }\n\n    companion object {\n        val modelPropAnnotations: List<KClass<out Annotation>> = listOf(\n            ModelProp::class,\n            TextProp::class,\n            CallbackProp::class\n        )\n\n        val modelPropAnnotationsArray: Array<KClass<out Annotation>> =\n            modelPropAnnotations.toTypedArray()\n\n        val modelPropAnnotationSimpleNames: Set<String> =\n            modelPropAnnotations.mapNotNull { it.simpleName }.toSet()\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeSpec\nimport javax.lang.model.element.Modifier\n\n/**\n * Used for writing the java code for models generated with @ModelView.\n */\ninternal class ModelViewWriter(\n    private val modelWriter: GeneratedModelWriter,\n    asyncable: Asyncable\n) : Asyncable by asyncable {\n\n    fun writeModels(\n        models: List<ModelViewInfo>,\n        originatingConfigElements: List<XElement>,\n        memoizer: Memoizer\n    ) {\n        models.forEach(\"Write model view classes\") { modelInfo ->\n            modelWriter.generateClassForModel(\n                modelInfo,\n                originatingElements = originatingConfigElements + modelInfo.originatingElements(memoizer),\n                builderHooks = generateBuilderHook(modelInfo)\n            )\n        }\n    }\n\n    private fun generateBuilderHook(modelInfo: ModelViewInfo) =\n        object : GeneratedModelWriter.BuilderHooks() {\n            override fun addToBindMethod(\n                methodBuilder: MethodSpec.Builder,\n                boundObjectParam: ParameterSpec\n            ) {\n\n                for (attributeGroup in modelInfo.attributeGroups) {\n                    val attrCount = attributeGroup.attributes.size\n                    fun attr(index: Int) = attributeGroup.attributes[index] as ViewAttributeInfo\n\n                    // If there are multiple attributes, or a default kotlin value, then we need to generate code to\n                    // check which properties have been set.\n                    val noConditionals = !hasConditionals(attributeGroup)\n\n                    for (i in 0 until attrCount) {\n                        val viewAttribute = attr(i)\n\n                        if (noConditionals) {\n                            // When there is only one attribute we can simply set the\n                            // value. Otherwise we need to handle attibute group checking.\n                            methodBuilder\n                                .addCode(\n                                    buildCodeBlockToSetAttribute(\n                                        boundObjectParam.name,\n                                        viewAttribute\n                                    )\n                                )\n                            continue\n                        }\n\n                        if (i == 0) {\n                            methodBuilder.beginControlFlow(\n                                \"if (\\$L)\",\n                                GeneratedModelWriter.isAttributeSetCode(\n                                    modelInfo,\n                                    viewAttribute\n                                )\n                            )\n                        } else if (i == attrCount - 1 && attributeGroup.isRequired) {\n                            methodBuilder.beginControlFlow(\n                                \"else\"\n                            )\n                        } else {\n                            methodBuilder.beginControlFlow(\n                                \"else if (\\$L)\",\n                                GeneratedModelWriter.isAttributeSetCode(\n                                    modelInfo,\n                                    viewAttribute\n                                )\n                            )\n                        }\n\n                        methodBuilder\n                            .addCode(\n                                buildCodeBlockToSetAttribute(\n                                    boundObjectParam.name,\n                                    viewAttribute\n                                )\n                            )\n                            .endControlFlow()\n                    }\n\n                    if (!attributeGroup.isRequired && !noConditionals) {\n                        val defaultAttribute =\n                            attributeGroup.defaultAttribute as ViewAttributeInfo\n\n                        methodBuilder.beginControlFlow(\n                            \"else\"\n                        )\n                            .addCode(\n                                buildCodeBlockToSetAttribute(\n                                    objectName = boundObjectParam.name,\n                                    attr = defaultAttribute,\n                                    useKotlinDefaultIfAvailable = true\n                                )\n                            )\n                            .endControlFlow()\n                    }\n                }\n            }\n\n            override fun addToBindWithDiffMethod(\n                methodBuilder: MethodSpec.Builder,\n                boundObjectParam: ParameterSpec,\n                previousModelParam: ParameterSpec\n            ) {\n\n                for (attributeGroup in modelInfo.attributeGroups) {\n                    val attributes = attributeGroup.attributes\n                    val noConditionals = !hasConditionals(attributeGroup)\n\n                    methodBuilder.addCode(\"\\n\")\n\n                    for ((index, attribute) in attributes.withIndex()) {\n                        if (noConditionals) {\n                            methodBuilder.apply {\n                                GeneratedModelWriter.startNotEqualsControlFlow(\n                                    this,\n                                    attribute\n                                )\n\n                                addCode(\n                                    buildCodeBlockToSetAttribute(\n                                        boundObjectParam.name,\n                                        attribute as ViewAttributeInfo\n                                    )\n                                )\n\n                                endControlFlow()\n                            }\n\n                            continue\n                        }\n\n                        val isAttributeSetCode = GeneratedModelWriter.isAttributeSetCode(\n                            modelInfo,\n                            attribute\n                        )\n\n                        methodBuilder.apply {\n                            beginControlFlow(\n                                \"${if (index != 0) \"else \" else \"\"}if (\\$L)\",\n                                isAttributeSetCode\n                            )\n\n                            // For primitives we do a simple != check to check if the prop changed from the previous model.\n                            // For objects we first check if the prop was not set on the previous model to be able to skip the equals check in some cases\n                            if (attribute.isPrimitive) {\n                                GeneratedModelWriter.startNotEqualsControlFlow(\n                                    this,\n                                    attribute\n                                )\n                            } else {\n                                beginControlFlow(\n                                    \"if (!that.\\$L || \\$L)\", isAttributeSetCode,\n                                    GeneratedModelWriter.notEqualsCodeBlock(attribute)\n                                )\n                            }\n\n                            addCode(\n                                buildCodeBlockToSetAttribute(\n                                    boundObjectParam.name,\n                                    attribute as ViewAttributeInfo\n                                )\n                            )\n\n                            endControlFlow()\n                            endControlFlow()\n                        }\n                    }\n\n                    if (!attributeGroup.isRequired && !noConditionals) {\n                        val defaultAttribute =\n                            attributeGroup.defaultAttribute as ViewAttributeInfo\n\n                        val ifConditionArgs = StringBuilder().apply {\n                            attributes.indices.forEach {\n                                if (it != 0) {\n                                    append(\" || \")\n                                }\n                                append(\"that.\\$L\")\n                            }\n                        }\n\n                        val ifConditionValues = attributes.map {\n                            GeneratedModelWriter.isAttributeSetCode(modelInfo, it)\n                        }\n\n                        methodBuilder\n                            .addComment(\n                                \"A value was not set so we should use the default value, \" +\n                                    \"but we only need to set it if the previous model \" +\n                                    \"had a custom value set.\"\n                            )\n                            .beginControlFlow(\n                                \"else if ($ifConditionArgs)\",\n                                *ifConditionValues.toTypedArray()\n                            )\n                            .addCode(\n                                buildCodeBlockToSetAttribute(\n                                    objectName = boundObjectParam.name,\n                                    attr = defaultAttribute,\n                                    useKotlinDefaultIfAvailable = true\n                                )\n                            )\n                            .endControlFlow()\n                    }\n                }\n            }\n\n            override fun addToHandlePostBindMethod(\n                postBindBuilder: MethodSpec.Builder,\n                boundObjectParam: ParameterSpec\n            ) {\n\n                addAfterPropsAddedMethodsToBuilder(\n                    postBindBuilder, modelInfo,\n                    boundObjectParam\n                )\n            }\n\n            override fun addToUnbindMethod(\n                unbindBuilder: MethodSpec.Builder,\n                unbindParamName: String\n            ) {\n                modelInfo.viewAttributes\n                    .filter { it.resetWithNull }\n                    .forEach {\n                        unbindBuilder.addCode(\n                            buildCodeBlockToSetAttribute(\n                                objectName = unbindParamName,\n                                attr = it,\n                                setToNull = true\n                            )\n                        )\n                    }\n\n                addResetMethodsToBuilder(\n                    unbindBuilder,\n                    modelInfo,\n                    unbindParamName\n                )\n            }\n\n            override fun addToVisibilityStateChangedMethod(\n                visibilityBuilder: MethodSpec.Builder,\n                visibilityParamName: String\n            ) {\n                addVisibilityStateChangedMethodsToBuilder(\n                    visibilityBuilder,\n                    modelInfo,\n                    visibilityParamName\n                )\n            }\n\n            override fun addToVisibilityChangedMethod(\n                visibilityBuilder: MethodSpec.Builder,\n                visibilityParamName: String\n            ) {\n                addVisibilityChangedMethodsToBuilder(\n                    visibilityBuilder,\n                    modelInfo,\n                    visibilityParamName\n                )\n            }\n\n            override fun beforeFinalBuild(builder: TypeSpec.Builder) {\n                if (modelInfo.saveViewState) {\n                    builder.addMethod(\n                        buildSaveStateMethod()\n                    )\n                }\n\n                if (modelInfo.fullSpanSize) {\n                    builder.addMethod(buildFullSpanSizeMethod())\n                }\n            }\n        }\n\n    private fun buildCodeBlockToSetAttribute(\n        objectName: String,\n        attr: ViewAttributeInfo,\n        setToNull: Boolean = false,\n        useKotlinDefaultIfAvailable: Boolean = false\n    ): CodeBlock {\n\n        val usingDefaultArg = useKotlinDefaultIfAvailable && attr.hasDefaultKotlinValue\n\n        val expression = \"\\$L.\\$L\" + when {\n            attr.viewAttributeTypeName == ViewAttributeType.Field -> if (setToNull) \" = (\\$T) null\" else \" = \\$L\"\n            setToNull -> \"((\\$T) null)\"\n            usingDefaultArg -> \"()\\$L\" // The kotlin default doesn't need a variable, but this let's us share the code with the other case\n            else -> \"(\\$L)\"\n        }\n\n        return CodeBlock.builder().addStatement(\n            expression,\n            objectName,\n            attr.viewAttributeName,\n            when {\n                usingDefaultArg -> \"\"\n                setToNull -> attr.typeName\n                else -> getValueToSetOnView(attr, objectName)\n            }\n        ).build()\n    }\n\n    private fun getValueToSetOnView(\n        viewAttribute: ViewAttributeInfo,\n        objectName: String\n    ): String {\n        val fieldName = viewAttribute.fieldName\n\n        return if (viewAttribute.generateStringOverloads) {\n            \"$fieldName.toString($objectName.getContext())\"\n        } else {\n            fieldName\n        }\n    }\n\n    private fun buildSaveStateMethod(): MethodSpec {\n        return MethodSpec.methodBuilder(\"shouldSaveViewState\")\n            .addAnnotation(Override::class.java)\n            .returns(TypeName.BOOLEAN)\n            .addModifiers(Modifier.PUBLIC)\n            .addStatement(\"return true\")\n            .build()\n    }\n\n    private fun buildFullSpanSizeMethod(): MethodSpec {\n        return MethodSpec.methodBuilder(\"getSpanSize\")\n            .addAnnotation(Override::class.java)\n            .returns(TypeName.INT)\n            .addModifiers(Modifier.PUBLIC)\n            .addParameter(TypeName.INT, \"totalSpanCount\")\n            .addParameter(TypeName.INT, \"position\")\n            .addParameter(TypeName.INT, \"itemCount\")\n            .addStatement(\"return totalSpanCount\")\n            .build()\n    }\n\n    private fun addResetMethodsToBuilder(\n        builder: MethodSpec.Builder,\n        modelViewInfo: ModelViewInfo,\n        unbindParamName: String\n    ) {\n        for (methodName in modelViewInfo.resetMethodNames) {\n            builder.addStatement(\"$unbindParamName.$methodName()\")\n        }\n    }\n\n    private fun addVisibilityStateChangedMethodsToBuilder(\n        builder: MethodSpec.Builder,\n        modelViewInfo: ModelViewInfo,\n        visibilityParamName: String\n    ) {\n        for (methodName in modelViewInfo.visibilityStateChangedMethodNames) {\n            builder.addStatement(\"$visibilityParamName.$methodName(visibilityState)\")\n        }\n    }\n\n    private fun addVisibilityChangedMethodsToBuilder(\n        builder: MethodSpec.Builder,\n        modelViewInfo: ModelViewInfo,\n        visibilityParamName: String\n    ) {\n        for (methodName in modelViewInfo.visibilityChangedMethodNames) {\n            builder.addStatement(\n                \"$visibilityParamName.$methodName\" +\n                    \"(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth)\"\n            )\n        }\n    }\n\n    private fun addAfterPropsAddedMethodsToBuilder(\n        methodBuilder: MethodSpec.Builder,\n        modelInfo: ModelViewInfo,\n        boundObjectParam: ParameterSpec\n    ) {\n        for (methodName in modelInfo.afterPropsSetMethodNames) {\n            methodBuilder.addStatement(boundObjectParam.name + \".\" + methodName + \"()\")\n        }\n    }\n\n    companion object {\n        fun hasConditionals(attributeGroup: GeneratedModelInfo.AttributeGroup?): Boolean {\n            if (attributeGroup == null) return false\n\n            return attributeGroup.attributes.size > 1 || (attributeGroup.defaultAttribute as ViewAttributeInfo?)?.hasDefaultKotlinValue == true\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/MultiParamAttribute.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.ParameterSpec\n\n/**\n * Allows an attribute to have multiple parameters in the model setter method. Those params are then\n * combined into a single object to be set on the attribute.\n *\n *\n * This is useful for things like\n * combining a StringRes and format arguments into a single string.\n */\ninterface MultiParamAttribute {\n    val params: List<ParameterSpec>\n    /**\n     * This code should combine the params into a single object which can then be set on the\n     * attribute.\n     */\n    val valueToSetOnAttribute: CodeBlock\n\n    fun varargs(): Boolean\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/PackageConfigSettings.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XAnnotation\nimport com.airbnb.epoxy.PackageEpoxyConfig\n\n/**\n * Stores configuration settings for a package.\n */\nclass PackageConfigSettings private constructor(\n    val requireHashCode: Boolean,\n    val requireAbstractModels: Boolean,\n    val implicitlyAddAutoModels: Boolean\n) {\n\n    companion object {\n\n        fun forDefaults() = PackageConfigSettings(\n            PackageEpoxyConfig.REQUIRE_HASHCODE_DEFAULT,\n            PackageEpoxyConfig.REQUIRE_ABSTRACT_MODELS_DEFAULT,\n            PackageEpoxyConfig.IMPLICITLY_ADD_AUTO_MODELS_DEFAULT\n        )\n\n        fun create(configAnnotation: XAnnotation) = PackageConfigSettings(\n            configAnnotation.getAsBoolean(\"requireHashCode\"),\n            configAnnotation.getAsBoolean(\"requireAbstractModels\"),\n            configAnnotation.getAsBoolean(\"implicitlyAddAutoModels\")\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/PackageModelViewSettings.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XAnnotation\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.isVoid\nimport androidx.room.compiler.processing.isVoidObject\nimport com.airbnb.epoxy.PackageModelViewConfig\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceValue\nimport com.squareup.javapoet.ClassName\n\nclass PackageModelViewSettings(\n    rClassName: XTypeElement,\n    annotation: XAnnotation\n) {\n\n    // The R class may be R or R2. We create the class name again to make sure we don't use R2.\n    val rClass: ClassName = ClassName.get(rClassName.packageName, \"R\", \"layout\")\n    val layoutName: String = annotation.getAsString(\"defaultLayoutPattern\")\n    val includeAlternateLayouts: Boolean = annotation.getAsBoolean(\"useLayoutOverloads\")\n    val generatedModelSuffix: String = annotation.getAsString(\"generatedModelSuffix\")\n    val disableGenerateBuilderOverloads: Boolean? = PackageModelViewConfig.Option.valueOf(\n        annotation.getAsEnum(\"disableGenerateBuilderOverloads\").name\n    ).toBoolean()\n    val disableGenerateGetters: Boolean? = PackageModelViewConfig.Option.valueOf(\n        annotation.getAsEnum(\"disableGenerateGetters\").name\n    ).toBoolean()\n    val disableGenerateReset: Boolean? = PackageModelViewConfig.Option.valueOf(\n        annotation.getAsEnum(\"disableGenerateReset\").name\n    ).toBoolean()\n\n    // Store the qualified name as a String instead of XType to avoid holding stale KSP references.\n    // In KSP2, accessing XType from previous rounds triggers \"PSI has changed since creation\" errors.\n    // The type must be resolved fresh each round using the current environment.\n    val defaultBaseModelClassName: String? = annotation.getAsType(\"defaultBaseModelClass\")\n        .takeIf {\n            // The default value of the annotation parameter is Void.class to signal that the user\n            // does not want to provide a custom base class\n            !it.isVoid() && !it.isVoidObject()\n        }?.typeElement?.qualifiedName\n\n    fun getNameForView(viewElement: XTypeElement): ResourceValue {\n        val viewName = Utils.toSnakeCase(viewElement.name)\n        val resourceName = layoutName.replace(\"%s\", viewName)\n        return ResourceValue(rClass, resourceName, 0)\n    }\n\n    private fun PackageModelViewConfig.Option.toBoolean(): Boolean? {\n        return when (this) {\n            PackageModelViewConfig.Option.Default -> null\n            PackageModelViewConfig.Option.Enabled -> true\n            PackageModelViewConfig.Option.Disabled -> false\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ParisStyleAttributeInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XTypeElement\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\n\nconst val BUILDER_STYLE_METHOD_PREFIX = \"add\"\nconst val PARIS_DEFAULT_STYLE_CONSTANT_NAME = \"DEFAULT_PARIS_STYLE\"\nconst val PARIS_STYLE_ATTR_NAME = \"style\"\n\nfun weakReferenceFieldForStyle(styleName: String) = \"parisStyleReference_$styleName\"\n\n/**\n * Represents a Paris Style option for a model.\n * This is added automatically for models generated with [ModelView] that also have Paris's Stylable annotation.\n */\nclass ParisStyleAttributeInfo(\n    modelInfo: GeneratedModelInfo,\n    packageName: String,\n    styleBuilderClassName: ClassName,\n    val styleBuilderElement: XTypeElement,\n    memoizer: Memoizer\n) : AttributeInfo(memoizer) {\n\n    val styles: List<ParisStyle>\n    val styleApplierClass: ClassName\n    val styleBuilderClass: ClassName\n\n    init {\n        fieldName = PARIS_STYLE_ATTR_NAME\n        rootClass = modelInfo.generatedName.simpleName()\n        this.packageName = packageName\n        // Use the memoizer parameter from the current round, not modelInfo.memoizer from round 1.\n        // modelInfo may have been created in a previous round and its memoizer holds stale KSP references.\n        // In KSP2, accessing types from previous rounds triggers \"PSI has changed since creation\" errors.\n        setXType(memoizer.parisStyleType, memoizer)\n        styleBuilderClass = styleBuilderClassName\n        ignoreRequireHashCode = true\n        isGenerated = true\n        useInHash = true\n        isNullable = false\n        styles = findStyleNames(styleBuilderElement)\n\n        // the builder is nested in the style applier class\n        styleApplierClass = styleBuilderClassName.topLevelClassName()\n\n        codeToSetDefault.explicit = CodeBlock.of(PARIS_DEFAULT_STYLE_CONSTANT_NAME)\n    }\n\n    private fun findStyleNames(styleBuilderElement: XTypeElement): List<ParisStyle> {\n        return styleBuilderElement\n            .getDeclaredMethodsLight(memoizer)\n            .filter {\n                it.name.startsWith(BUILDER_STYLE_METHOD_PREFIX)\n            }\n            .map {\n                val name = it.name\n                    .removePrefix(BUILDER_STYLE_METHOD_PREFIX)\n                    .lowerCaseFirstLetter()\n\n                ParisStyle(name, it.docComment)\n            }\n    }\n}\n\ndata class ParisStyle(\n    val name: String,\n    val javadoc: String?\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/PoetExtensions.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.TypeName\nimport com.squareup.kotlinpoet.ANY\nimport com.squareup.kotlinpoet.BOOLEAN\nimport com.squareup.kotlinpoet.BYTE\nimport com.squareup.kotlinpoet.CHAR\nimport com.squareup.kotlinpoet.DOUBLE\nimport com.squareup.kotlinpoet.FLOAT\nimport com.squareup.kotlinpoet.INT\nimport com.squareup.kotlinpoet.KModifier\nimport com.squareup.kotlinpoet.LONG\nimport com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy\nimport com.squareup.kotlinpoet.SHORT\nimport com.squareup.kotlinpoet.STAR\nimport com.squareup.kotlinpoet.UNIT\nimport com.squareup.kotlinpoet.WildcardTypeName\nimport javax.lang.model.element.Modifier\n\ntypealias JavaClassName = com.squareup.javapoet.ClassName\ntypealias JavaTypeName = com.squareup.javapoet.TypeName\ntypealias JavaWildcardTypeName = com.squareup.javapoet.WildcardTypeName\ntypealias JavaArrayTypeName = com.squareup.javapoet.ArrayTypeName\ntypealias JavaTypeVariableName = com.squareup.javapoet.TypeVariableName\ntypealias JavaParametrizedTypeName = com.squareup.javapoet.ParameterizedTypeName\n\ntypealias JavaParameterSpec = com.squareup.javapoet.ParameterSpec\ntypealias JavaFieldSpec = com.squareup.javapoet.FieldSpec\ntypealias JavaAnnotationSpec = com.squareup.javapoet.AnnotationSpec\ntypealias JavaTypeSpec = com.squareup.javapoet.TypeSpec\n\ntypealias KotlinClassName = com.squareup.kotlinpoet.ClassName\ntypealias KotlinParameterizedTypeName = com.squareup.kotlinpoet.ParameterizedTypeName\ntypealias KotlinTypeName = com.squareup.kotlinpoet.TypeName\ntypealias KotlinWildcardTypeName = com.squareup.kotlinpoet.WildcardTypeName\ntypealias KotlinTypeVariableName = com.squareup.kotlinpoet.TypeVariableName\n\ntypealias KotlinParameterSpec = com.squareup.kotlinpoet.ParameterSpec\ntypealias KotlinAnnotationSpec = com.squareup.kotlinpoet.AnnotationSpec\ntypealias KotlinTypeSpec = com.squareup.kotlinpoet.TypeSpec\n\nprivate val javaUtilPkg = \"java.util\"\nprivate val javaLangPkg = \"java.lang\"\nprivate val kotlinJvmFunction = \"kotlin.jvm.functions\"\nprivate val kotlinCollectionsPkg = \"kotlin.collections\"\nprivate val kotlinPkg = \"kotlin\"\nfun JavaClassName.toKPoet(): KotlinClassName {\n\n    val simpleNames = getSimpleNamesInKotlin()\n    val packageName = getPackageNameInKotlin()\n\n    return KotlinClassName(\n        packageName,\n        simpleNames.first(),\n        *simpleNames.drop(1).toTypedArray()\n    )\n}\n\n/** Some classes, like List or Byte have the same class name but a different package for their kotlin equivalent. */\nprivate fun JavaClassName.getPackageNameInKotlin(): String {\n    if (packageName() in listOf(\n            javaUtilPkg,\n            javaLangPkg,\n            kotlinJvmFunction\n        ) && simpleNames().size == 1\n    ) {\n\n        val transformedPkg = when {\n            isBoxedPrimitive -> kotlinPkg\n            isLambda(this) -> kotlinPkg\n            else -> when (simpleName()) {\n                \"Collection\",\n                \"List\",\n                \"Map\",\n                \"Set\",\n                \"Iterable\" -> kotlinCollectionsPkg\n                \"String\" -> kotlinPkg\n                \"CharSequence\" -> kotlinPkg\n                else -> null\n            }\n        }\n\n        if (transformedPkg != null) {\n            return transformedPkg\n        }\n    }\n\n    return packageName()\n}\n\nfun isLambda(type: JavaTypeName): Boolean {\n    return type.toString().contains(\"Function\") && type.toString().contains(\"kotlin\")\n}\n\n/** Some classes, notably Integer and Character, have a different simple name in Kotlin. */\nprivate fun JavaClassName.getSimpleNamesInKotlin(): List<String> {\n    val originalNames = simpleNames()\n\n    if (isBoxedPrimitive) {\n        val transformedName = when (originalNames.first()) {\n            \"Integer\" -> \"Int\"\n            \"Character\" -> \"Char\"\n            else -> null\n        }\n\n        if (transformedName != null) {\n            return listOf(transformedName)\n        }\n    }\n\n    return originalNames\n}\n\n// Does not support transferring complex annotations which\n// have parameters and values associated with them.\nfun JavaAnnotationSpec.toKPoet(): KotlinAnnotationSpec? {\n    // If the annotation has any members (params), then we\n    // return null since we don't yet support translating\n    // params from Java annotation to Kotlin annotation.\n    if (members.isNotEmpty()) {\n        return null\n    }\n    val annotationClass = KotlinClassName.bestGuess(type.toString())\n    return KotlinAnnotationSpec.builder(annotationClass).build()\n}\n\nfun JavaClassName.setPackage(packageName: String) =\n    JavaClassName.get(packageName, simpleName(), *simpleNames().drop(1).toTypedArray())!!\n\n// Does not support transferring annotations\nfun JavaWildcardTypeName.toKPoet(): WildcardTypeName {\n    return if (lowerBounds.isNotEmpty()) {\n        KotlinWildcardTypeName.consumerOf(lowerBounds.first().toKPoet())\n    } else when (val upperBound = upperBounds[0]) {\n        TypeName.OBJECT -> STAR\n        else -> KotlinWildcardTypeName.producerOf(upperBound.toKPoet())\n    }\n}\n\n// Does not support transferring annotations\nfun JavaParametrizedTypeName.toKPoet() =\n    this.rawType.toKPoet().parameterizedBy(*typeArguments.toKPoet().toTypedArray())\n\n// Does not support transferring annotations\nfun JavaArrayTypeName.toKPoet(): KotlinTypeName {\n\n    // Kotlin has special classes for primitive arrays\n    if (componentType.isPrimitive) {\n        val kotlinArrayType = when (componentType) {\n            TypeName.BYTE -> \"ByteArray\"\n            TypeName.SHORT -> \"ShortArray\"\n            TypeName.CHAR -> \"CharArray\"\n            TypeName.INT -> \"IntArray\"\n            TypeName.FLOAT -> \"FloatArray\"\n            TypeName.DOUBLE -> \"DoubleArray\"\n            TypeName.LONG -> \"LongArray\"\n            TypeName.BOOLEAN -> \"BooleanArray\"\n            else -> null\n        }\n\n        if (kotlinArrayType != null) {\n            return KotlinClassName(kotlinPkg, kotlinArrayType)\n        }\n    }\n\n    return KotlinClassName(kotlinPkg, \"Array\").parameterizedBy(this.componentType.toKPoet())\n}\n\n// Does not support transferring annotations\nfun JavaTypeVariableName.toKPoet() = KotlinTypeVariableName.invoke(\n    if (name == \"?\") \"*\" else name,\n    *bounds.toKPoet().toTypedArray()\n)\n\nfun JavaTypeName.toKPoet(nullable: Boolean = false): KotlinTypeName {\n    val type = when (this) {\n        JavaTypeName.BOOLEAN -> BOOLEAN\n        JavaTypeName.BYTE -> BYTE\n        JavaTypeName.SHORT -> SHORT\n        JavaTypeName.CHAR -> CHAR\n        JavaTypeName.INT -> INT\n        JavaTypeName.LONG -> LONG\n        JavaTypeName.FLOAT -> FLOAT\n        JavaTypeName.DOUBLE -> DOUBLE\n        JavaTypeName.OBJECT -> ANY\n        JavaTypeName.VOID -> UNIT\n        is JavaClassName -> toKPoet()\n        is JavaParametrizedTypeName -> toKPoet()\n        is JavaArrayTypeName -> toKPoet()\n        is JavaTypeVariableName -> toKPoet()\n        is JavaWildcardTypeName -> toKPoet()\n        else -> throw IllegalArgumentException(\"Unsupported type: ${this::class.simpleName}\")\n    }\n\n    if (nullable) {\n        return type.copy(nullable = true)\n    }\n\n    return type\n}\n\nfun <T : JavaTypeName> Iterable<T>.toKPoet() = map { it.toKPoet() }\n\nfun JavaParameterSpec.toKPoet(): KotlinParameterSpec {\n\n    // A param name in java might be reserved in kotlin\n    val paramName = if (name in KOTLIN_KEYWORDS) name + \"Param\" else name\n\n    val nullable = annotations.any { (it.type as? JavaClassName)?.simpleName() == \"Nullable\" }\n\n    val kotlinAnnotations: List<KotlinAnnotationSpec> = annotations.mapNotNull { it.toKPoet() }\n\n    return KotlinParameterSpec.builder(\n        paramName,\n        // Not using built in javapoet interop because of bug https://github.com/square/kotlinpoet/issues/1181\n        type.toKPoet(nullable),\n        *modifiers.toKModifier().toTypedArray()\n    ).apply {\n        if (isLambda(type)) {\n            addModifiers(KModifier.NOINLINE)\n        }\n        addAnnotations(kotlinAnnotations)\n    }.build()\n}\n\nfun Iterable<Modifier>.toKModifier(): List<KModifier> = mapNotNull { it.toKModifier() }\n\nfun Modifier.toKModifier() = when (this) {\n    Modifier.PUBLIC -> KModifier.PUBLIC\n    Modifier.PRIVATE -> KModifier.PRIVATE\n    Modifier.PROTECTED -> KModifier.PROTECTED\n    Modifier.FINAL -> KModifier.FINAL\n    Modifier.ABSTRACT -> KModifier.ABSTRACT\n    else -> null\n}\n\n// https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/renderer/KeywordStringsGenerated.java\nprivate val KOTLIN_KEYWORDS = setOf(\n    \"package\",\n    \"as\",\n    \"typealias\",\n    \"class\",\n    \"this\",\n    \"super\",\n    \"val\",\n    \"var\",\n    \"fun\",\n    \"for\",\n    \"null\",\n    \"true\",\n    \"false\",\n    \"is\",\n    \"in\",\n    \"throw\",\n    \"return\",\n    \"break\",\n    \"continue\",\n    \"object\",\n    \"if\",\n    \"try\",\n    \"else\",\n    \"while\",\n    \"do\",\n    \"when\",\n    \"interface\",\n    \"typeof\"\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/StringOverloadWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.annotation.NonNull\nimport androidx.annotation.Nullable\nimport androidx.annotation.PluralsRes\nimport androidx.annotation.StringRes\nimport com.airbnb.epoxy.processor.GeneratedModelWriter.Companion.addOnMutationCall\nimport com.airbnb.epoxy.processor.GeneratedModelWriter.Companion.addParameterNullCheckIfNeeded\nimport com.airbnb.epoxy.processor.GeneratedModelWriter.Companion.setBitSetIfNeeded\nimport com.squareup.javapoet.ArrayTypeName\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.MethodSpec.Builder\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport java.util.ArrayList\nimport javax.lang.model.element.Modifier.PUBLIC\n\ninternal class StringOverloadWriter(\n    private val modelInfo: GeneratedModelInfo,\n    private val attr: AttributeInfo,\n    private val configManager: ConfigManager\n) {\n    private val fieldName: String = attr.fieldName\n    private val nullable: Boolean = attr.isNullable == true\n\n    fun buildMethods(): List<MethodSpec> {\n        val methods = ArrayList<MethodSpec>()\n        methods.add(buildGetter())\n\n        methods.add(finishSetter(buildCharSequenceSetter(baseSetter())))\n        methods.add(finishSetter(buildStringResSetter(baseSetter())))\n        methods.add(finishSetter(buildStringResWithArgsSetter(baseSetter())))\n        methods.add(finishSetter(buildQuantityStringResSetter(baseSetter(\"QuantityRes\"))))\n\n        return methods\n    }\n\n    private fun buildCharSequenceSetter(builder: Builder): Builder {\n        val paramName = attr.generatedSetterName()\n        val paramBuilder = ParameterSpec.builder(CharSequence::class.java, paramName)\n\n        if (nullable) {\n            paramBuilder.addAnnotation(Nullable::class.java)\n        } else {\n            paramBuilder.addAnnotation(NonNull::class.java)\n        }\n\n        addJavaDoc(builder, false)\n\n        builder.addParameter(paramBuilder.build())\n\n        addParameterNullCheckIfNeeded(configManager, attr, paramName, builder)\n        builder.addStatement(\"\\$L.setValue(\\$L)\", fieldName, paramName)\n\n        return builder\n    }\n\n    private fun buildStringResSetter(builder: Builder): Builder {\n        builder.addParameter(\n            ParameterSpec.builder(TypeName.INT, STRING_RES_PARAM)\n                .addAnnotation(StringRes::class.java)\n                .build()\n        )\n\n        addJavaDoc(builder, true)\n        builder.addStatement(\"\\$L.setValue(\\$L)\", fieldName, STRING_RES_PARAM)\n\n        return builder\n    }\n\n    private fun buildStringResWithArgsSetter(builder: Builder): Builder {\n        builder.addParameter(\n            ParameterSpec.builder(TypeName.INT, STRING_RES_PARAM)\n                .addAnnotation(StringRes::class.java)\n                .build()\n        )\n\n        addJavaDoc(builder, true)\n\n        builder\n            .addParameter(\n                ParameterSpec.builder(\n                    ArrayTypeName.of(TypeName.OBJECT),\n                    ARGS_PARAM\n                ).build()\n            )\n\n        builder.addStatement(\"\\$L.setValue(\\$L, \\$L)\", fieldName, STRING_RES_PARAM, ARGS_PARAM)\n            .varargs()\n\n        return builder\n    }\n\n    private fun buildQuantityStringResSetter(builder: Builder): Builder {\n\n        builder.addParameter(\n            ParameterSpec.builder(TypeName.INT, PLURAL_RES_PARAM)\n                .addAnnotation(PluralsRes::class.java)\n                .build()\n        )\n\n        addJavaDoc(builder, true)\n\n        builder.addParameter(ParameterSpec.builder(TypeName.INT, QUANTITY_PARAM).build())\n\n        builder\n            .addParameter(\n                ParameterSpec.builder(\n                    ArrayTypeName.of(TypeName.OBJECT),\n                    ARGS_PARAM\n                ).build()\n            )\n\n        builder.addStatement(\n            \"\\$L.setValue(\\$L, \\$L, \\$L)\", fieldName, PLURAL_RES_PARAM,\n            QUANTITY_PARAM,\n            ARGS_PARAM\n        )\n            .varargs()\n\n        return builder\n    }\n\n    private fun baseSetter(suffix: String = \"\"): Builder {\n        val name = attr.generatedSetterName() + suffix\n\n        val builder = MethodSpec.methodBuilder(name)\n            .addModifiers(PUBLIC)\n            .returns(modelInfo.parameterizedGeneratedName)\n\n        addOnMutationCall(builder)\n        setBitSetIfNeeded(modelInfo, attr, builder)\n        return builder\n    }\n\n    private fun addJavaDoc(\n        builder: Builder,\n        forStringRes: Boolean\n    ) {\n        if (attr.javaDoc == null) {\n            return\n        }\n\n        val javaDoc = CodeBlock.builder()\n\n        if (forStringRes) {\n            if (attr.isRequired) {\n                javaDoc.add(\"Throws if a value <= 0 is set.\\n<p>\\n\")\n            } else {\n                javaDoc.add(\n                    \"If a value of 0 is set then this attribute will revert to its \" +\n                        \"default value.\\n<p>\\n\"\n                )\n            }\n        }\n\n        builder.addJavadoc(javaDoc.add(attr.javaDoc).build())\n    }\n\n    private fun buildGetter(): MethodSpec {\n        val getterName = attr.generatedGetterName(\n            isOverload = modelInfo.isOverload(attr)\n        )\n        val builder = MethodSpec.methodBuilder(getterName)\n            .addModifiers(PUBLIC)\n            .returns(CharSequence::class.java)\n\n        if (nullable) {\n            builder.addAnnotation(Nullable::class.java)\n        }\n\n        return builder\n            .addAnnotations(attr.getterAnnotations)\n            .addParameter(ClassNames.ANDROID_CONTEXT, \"context\")\n            .addStatement(\"return \\$L\", fieldName + \".toString(context)\")\n            .build()\n    }\n\n    companion object {\n        private val PLURAL_RES_PARAM = \"pluralRes\"\n        private val STRING_RES_PARAM = \"stringRes\"\n        private val ARGS_PARAM = \"formatArgs\"\n        private val QUANTITY_PARAM = \"quantity\"\n\n        private fun finishSetter(builder: MethodSpec.Builder): MethodSpec {\n            return builder\n                .addStatement(\"return this\")\n                .build()\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/StyleWriter.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport java.util.Objects\nimport javax.lang.model.element.Element\nimport javax.lang.model.util.Elements\n\ninternal fun addStyleApplierCode(\n    methodBuilder: MethodSpec.Builder,\n    styleInfo: ParisStyleAttributeInfo,\n    viewVariableName: String\n) {\n\n    methodBuilder.apply {\n\n        addStatement(\n            \"\\$T styleApplier = new \\$T(\\$L)\",\n            styleInfo.styleApplierClass, styleInfo.styleApplierClass, viewVariableName\n        )\n\n        addStatement(\"styleApplier.apply(\\$L)\", PARIS_STYLE_ATTR_NAME)\n\n        // By saving the style as a tag we can prevent applying it\n        // again when the view is recycled and the same style is used\n        addStatement(\n            \"\\$L.setTag(\\$T.id.epoxy_saved_view_style, \\$L)\",\n            viewVariableName, ClassNames.EPOXY_R, PARIS_STYLE_ATTR_NAME\n        )\n    }\n}\n\ninternal fun addBindStyleCodeIfNeeded(\n    modelInfo: GeneratedModelInfo,\n    methodBuilder: MethodSpec.Builder,\n    boundObjectParam: ParameterSpec,\n    hasPreviousModel: Boolean\n) {\n    val styleInfo = modelInfo.styleBuilderInfo ?: return\n\n    methodBuilder.apply {\n        // Compare against the style on the previous model if it exists,\n        // otherwise we look up the saved style from the view tag\n        if (hasPreviousModel) {\n            beginControlFlow(\n                \"\\nif (!\\$T.equals(\\$L, that.\\$L))\",\n                Objects::class.java, PARIS_STYLE_ATTR_NAME, PARIS_STYLE_ATTR_NAME\n            )\n        } else {\n            beginControlFlow(\n                \"\\nif (!\\$T.equals(\\$L, \\$L.getTag(\\$T.id.epoxy_saved_view_style)))\",\n                Objects::class.java, PARIS_STYLE_ATTR_NAME, boundObjectParam.name,\n                ClassNames.EPOXY_R\n            )\n        }\n\n        addStyleApplierCode(this, styleInfo, boundObjectParam.name)\n\n        endControlFlow()\n    }\n}\n\ninternal fun Element.hasStyleableAnnotation(elements: Elements) = annotationMirrorsThreadSafe\n    .map { it.annotationType.asElement() }\n    .any {\n        it.simpleName.toString() == \"Styleable\" &&\n            elements.getPackageOf(it).qualifiedName.contains(\"paris\")\n    }\n\ninternal fun XElement.hasStyleableAnnotation(): Boolean {\n    return getAllAnnotations().any {\n        it.name == \"Styleable\" && it.qualifiedName.contains(\"paris\")\n    }\n}\n\ninternal fun tryAddStyleBuilderAttribute(\n    styleableModel: GeneratedModelInfo,\n    processingEnv: XProcessingEnv,\n    memoizer: Memoizer\n): Boolean {\n    // if style applier is generated\n    val viewClass = (styleableModel.modelType as? ClassName) ?: return false\n    val styleBuilderClassName = ClassName.get(\n        viewClass.packageName(),\n        \"${viewClass.simpleName()}StyleApplier\",\n        \"StyleBuilder\"\n    )\n\n    val styleBuilderElement = processingEnv.findTypeElement(styleBuilderClassName.toString())\n        ?: return false\n\n    styleableModel.setStyleable(\n        ParisStyleAttributeInfo(\n            modelInfo = styleableModel,\n            packageName = viewClass.packageName(),\n            styleBuilderClassName = styleBuilderClassName,\n            styleBuilderElement = styleBuilderElement,\n            memoizer = memoizer\n        )\n    )\n    return true\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Synchronization.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport com.squareup.javapoet.JavaFile\nimport com.squareup.kotlinpoet.FileSpec\nimport com.squareup.kotlinpoet.OriginatingElementsHolder\nimport com.sun.tools.javac.code.Symbol\nimport com.sun.tools.javac.code.Type\nimport javax.annotation.processing.Filer\nimport javax.annotation.processing.RoundEnvironment\nimport javax.lang.model.element.AnnotationMirror\nimport javax.lang.model.element.Element\nimport javax.lang.model.element.ExecutableElement\nimport javax.lang.model.element.Modifier\nimport javax.lang.model.element.Parameterizable\nimport javax.lang.model.element.TypeElement\nimport javax.lang.model.element.TypeParameterElement\nimport javax.lang.model.element.VariableElement\nimport javax.lang.model.type.TypeMirror\nimport javax.tools.StandardLocation\nimport kotlin.reflect.KClass\n\nclass Mutex\n\nvar synchronizationEnabled = false\nprivate val mutexMap = mutableMapOf<Any, Mutex>()\n\n@Synchronized\nfun Any.mutex() = mutexMap.getOrPut(this) { Mutex() }\n\ninline fun <R> synchronizedByValue(value: Any, block: () -> R): R {\n    return if (synchronizationEnabled) {\n        synchronized(value.mutex(), block)\n    } else {\n        block()\n    }\n}\n\ninline fun <R> synchronizedByElement(element: Element, block: () -> R): R {\n    return if (synchronizationEnabled) {\n        element.ensureLoaded()\n        val name = if (element is TypeElement) element.qualifiedName else element.simpleName\n        synchronized(name.mutex(), block)\n    } else {\n        block()\n    }\n}\n\nval typeLookupMutex = Mutex()\ninline fun <R> synchronizedForTypeLookup(block: () -> R): R {\n    return if (synchronizationEnabled) {\n        synchronized(typeLookupMutex, block)\n    } else {\n        block()\n    }\n}\n\nfun <T : Element> T.ensureLoaded(): T {\n    if (!synchronizationEnabled || this !is Symbol) return this\n\n    // if already completed, can skip synchronization\n    completer ?: return this\n\n    synchronizedForTypeLookup {\n        complete()\n    }\n\n    return this\n}\n\nfun <T : TypeMirror> T.ensureLoaded(): T {\n    if (!synchronizationEnabled || this !is Type) return this\n\n    tsym?.completer ?: return this\n\n    synchronizedForTypeLookup {\n        complete()\n    }\n\n    return this\n}\n\nval Element.enclosedElementsThreadSafe: List<Element>\n    get() {\n        return if (!synchronizationEnabled) {\n            enclosedElements\n        } else {\n            ensureLoaded()\n            synchronizedForTypeLookup {\n                enclosedElements.onEach { it.ensureLoaded() }\n            }\n        }\n    }\n\nval ExecutableElement.parametersThreadSafe: List<VariableElement>\n    get() {\n        return if (!synchronizationEnabled) {\n            parameters\n        } else {\n            ensureLoaded()\n            // After being initially loaded, parameters are lazily built into a list and stored\n            // as a class field\n            synchronizedForTypeLookup {\n                parameters.onEach { it.ensureLoaded() }\n            }\n        }\n    }\n\nval Parameterizable.typeParametersThreadSafe: List<TypeParameterElement>\n    get() {\n        return if (!synchronizationEnabled) {\n            typeParameters\n        } else {\n            ensureLoaded()\n            // After being initially loaded, typeParameters are lazily built into a list and stored\n            // as a class field\n            synchronizedForTypeLookup {\n                typeParameters.onEach { it.ensureLoaded() }\n            }\n        }\n    }\n\nval Element.modifiersThreadSafe: Set<Modifier>\n    get() {\n        ensureLoaded()\n        return modifiers\n    }\n\nval ExecutableElement.isVarArgsThreadSafe: Boolean\n    get() {\n        ensureLoaded()\n        return isVarArgs\n    }\n\nval Element.annotationMirrorsThreadSafe: List<AnnotationMirror>\n    get() {\n        return if (!synchronizationEnabled) {\n            annotationMirrors\n        } else {\n            ensureLoaded()\n            synchronizedForTypeLookup {\n                annotationMirrors\n            }\n        }\n    }\n\nfun <A : Annotation> Element.getAnnotationThreadSafe(annotationClass: Class<A>): A? {\n    // Getting an annotation internally accesses type mirrors, so we have to make sure those are loaded first.\n    annotationMirrorsThreadSafe\n    return getAnnotation(annotationClass)\n}\n\ninline fun <reified A : Annotation> Element.getAnnotation(): A? =\n    getAnnotationThreadSafe(A::class.java)\n\n// Copied from javapoet and made threadsafe\nfun JavaFile.writeSynchronized(filer: Filer) {\n    val fileName =\n        if (packageName.isEmpty()) typeSpec.name else packageName.toString() + \".\" + typeSpec.name\n    val originatingElements = typeSpec.originatingElements\n\n    // JavacFiler does not properly synchronize its \"Set<FileObject> fileObjectHistory\" field,\n    // so parallel calls to createSourceFile can throw concurrent modification exceptions.\n    val filerSourceFile = synchronized(filer) {\n        filer.createSourceFile(\n            fileName,\n            *originatingElements.toTypedArray()\n        )\n    }\n\n    try {\n        filerSourceFile.openWriter().use { writer -> writeTo(writer) }\n    } catch (e: Exception) {\n        try {\n            filerSourceFile.delete()\n        } catch (ignored: Exception) {\n        }\n        throw e\n    }\n}\n\n// Copied from kotlinpoet and made threadsafe\nfun FileSpec.writeSynchronized(filer: Filer) {\n    val originatingElements = members.asSequence()\n        .filterIsInstance<OriginatingElementsHolder>()\n        .flatMap { it.originatingElements.asSequence() }\n        .toSet()\n\n    val filerSourceFile = synchronized(filer) {\n        filer.createResource(\n            StandardLocation.SOURCE_OUTPUT,\n            packageName,\n            \"$name.kt\",\n            *originatingElements.toTypedArray()\n        )\n    }\n\n    try {\n        filerSourceFile.openWriter().use { writer -> writeTo(writer) }\n    } catch (e: Exception) {\n        try {\n            filerSourceFile.delete()\n        } catch (ignored: Exception) {\n        }\n        throw e\n    }\n}\n\nfun RoundEnvironment.getElementsAnnotatedWith(\n    logger: Logger,\n    annotation: KClass<out Annotation>\n): Set<Element> {\n    return logger.measure(\"get annotations: ${annotation.simpleName}\") {\n        getElementsAnnotatedWith(annotation.java).onEach { it.ensureLoaded() }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Timer.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XMessager\nimport javax.tools.Diagnostic\nimport kotlin.math.pow\nimport kotlin.math.roundToInt\n\nclass Timer(val name: String) {\n    private val timingSteps = mutableListOf<TimingStep>()\n    private var startNanos: Long? = null\n    private var lastTimingNanos: Long? = null\n\n    fun start() {\n        timingSteps.clear()\n        startNanos = System.nanoTime()\n        lastTimingNanos = startNanos\n    }\n\n    fun markStepCompleted(stepDescription: String) {\n        val nowNanos = System.nanoTime()\n        val lastNanos = lastTimingNanos ?: error(\"Timer was not started\")\n        lastTimingNanos = nowNanos\n\n        timingSteps.add(TimingStep(nowNanos - lastNanos, stepDescription))\n    }\n\n    fun finishAndPrint(messager: XMessager) {\n        val start = startNanos ?: error(\"Timer was not started\")\n        val message = buildString {\n            appendLine(\"$name finished in ${formatNanos(System.nanoTime() - start)}\")\n            timingSteps.forEach { step ->\n                appendLine(\" - ${step.description} (${formatNanos(step.durationNanos)})\")\n            }\n        }\n\n        messager.printMessage(Diagnostic.Kind.WARNING, message)\n    }\n\n    private class TimingStep(val durationNanos: Long, val description: String)\n\n    private fun formatNanos(nanos: Long): String {\n        val diffMs = nanos.div(1_000_000.0).roundTo(3)\n        return \"$diffMs ms\"\n    }\n\n    private fun Double.roundTo(numFractionDigits: Int): Double {\n        val factor = 10.0.pow(numFractionDigits.toDouble())\n        return (this * factor).roundToInt() / factor\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Type.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.isInt\nimport androidx.room.compiler.processing.isLong\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.WildcardTypeName\n\n/**\n * This helps to memoize the look up of a type's information.\n */\nclass Type(val xType: XType, memoizer: Memoizer) {\n    // Compute both typeName and typeEnum eagerly to avoid accessing stale xType in later rounds\n    val typeName: TypeName = xType.typeNameWithWorkaround(memoizer)\n    val typeEnum: TypeEnum = TypeEnum.from(xType, memoizer)\n\n    enum class TypeEnum {\n        StringOrCharSequence,\n        Boolean,\n        Int,\n        Long,\n        Double,\n        ViewClickListener,\n        ViewLongClickListener,\n        ViewCheckedChangeListener,\n        StringList,\n        EpoxyModelList,\n        StringAttributeData,\n        Unknown;\n\n        companion object {\n            fun from(xType: XType, memoizer: Memoizer): TypeEnum {\n\n                val nonNullType by lazy { xType.makeNonNullable() }\n                val typeName by lazy { xType.typeNameWithWorkaround(memoizer) }\n\n                return when {\n                    xType.isInt() -> Int\n                    xType.isLong() -> Long\n                    xType.typeName == TypeName.BOOLEAN || xType.typeName == TypeName.BOOLEAN.box() -> Boolean\n                    xType.typeName == TypeName.DOUBLE || xType.typeName == TypeName.DOUBLE.box() -> Double\n                    xType.isTypeOf(CharSequence::class) || xType.isTypeOf(String::class) -> StringOrCharSequence\n                    xType.typeName == ClassNames.EPOXY_STRING_ATTRIBUTE_DATA -> StringAttributeData\n                    // We don't care about nullability for the purposes of type checking\n                    // Note, == does not work for type comparisons when comparing types between classpath\n                    // and compiled sources so we must use isSameType.\n                    nonNullType.isSameType(memoizer.viewOnClickListenerType) -> ViewClickListener\n                    nonNullType.isSameType(memoizer.viewOnLongClickListenerType) -> ViewLongClickListener\n                    nonNullType.isSameType(memoizer.viewOnCheckChangedType) -> ViewCheckedChangeListener\n                    xType.isTypeOf(List::class) -> {\n                        val listType = xType.typeArguments.singleOrNull()\n                        when {\n                            listType?.isTypeOf(String::class) == true -> StringList\n                            typeName == listOfGenericEpoxyModelType -> EpoxyModelList\n                            else -> Unknown\n                        }\n                    }\n\n                    else -> Unknown\n                }\n            }\n        }\n    }\n}\n\nprivate val listOfGenericEpoxyModelType = ParameterizedTypeName.get(\n    ClassNames.LIST,\n    WildcardTypeName.subtypeOf(\n        ParameterizedTypeName.get(\n            ClassNames.EPOXY_MODEL_UNTYPED,\n            WildcardTypeName.subtypeOf(TypeName.OBJECT)\n        )\n    )\n)\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/TypeNameWorkaround.kt",
    "content": "/**\n * This implementation is taken from Room XProcessing and patched to partially fix https://issuetracker.google.com/issues/204415667\n *\n * Changes are commented in the code below.\n */\npackage com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XType\nimport com.google.devtools.ksp.KspExperimental\nimport com.google.devtools.ksp.isOpen\nimport com.google.devtools.ksp.processing.Resolver\nimport com.google.devtools.ksp.symbol.KSDeclaration\nimport com.google.devtools.ksp.symbol.KSName\nimport com.google.devtools.ksp.symbol.KSType\nimport com.google.devtools.ksp.symbol.KSTypeAlias\nimport com.google.devtools.ksp.symbol.KSTypeArgument\nimport com.google.devtools.ksp.symbol.KSTypeParameter\nimport com.google.devtools.ksp.symbol.KSTypeReference\nimport com.google.devtools.ksp.symbol.Variance\nimport com.squareup.javapoet.ArrayTypeName\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeVariableName\nimport com.squareup.javapoet.WildcardTypeName\nimport kotlin.coroutines.Continuation\n\nfun XType.typeNameWithWorkaround(memoizer: Memoizer): TypeName {\n    return memoizer.typeNameWithWorkaround(this)\n}\n\n// Catch-all type name when we cannot resolve to anything. This is what KAPT uses as error type\n// and we use the same type in KSP for consistency.\n// https://kotlinlang.org/docs/reference/kapt.html#non-existent-type-correction\ninternal val ERROR_TYPE_NAME = ClassName.get(\"error\", \"NonExistentClass\")\n\n/**\n * To handle self referencing types and avoid infinite recursion, we keep a lookup map for\n * TypeVariables.\n */\nprivate typealias TypeArgumentTypeLookup = LinkedHashMap<KSName, TypeName>\n\ninternal fun TypeName.tryBox(): TypeName {\n    return try {\n        box()\n    } catch (err: AssertionError) {\n        this\n    }\n}\n\n/**\n * Turns a KSTypeReference into a TypeName in java's type system.\n */\ninternal fun KSTypeReference?.typeName(resolver: Resolver): TypeName =\n    typeName(\n        resolver = resolver,\n        typeArgumentTypeLookup = TypeArgumentTypeLookup()\n    )\n\nprivate fun KSTypeReference?.typeName(\n    resolver: Resolver,\n    typeArgumentTypeLookup: TypeArgumentTypeLookup\n): TypeName {\n    return if (this == null) {\n        ERROR_TYPE_NAME\n    } else {\n        resolve().typeName(resolver, typeArgumentTypeLookup)\n    }\n}\n\n/**\n * Turns a KSDeclaration into a TypeName in java's type system.\n */\ninternal fun KSDeclaration.typeName(resolver: Resolver): TypeName =\n    typeName(\n        resolver = resolver,\n        typeArgumentTypeLookup = TypeArgumentTypeLookup()\n    )\n\n@OptIn(KspExperimental::class)\nprivate fun KSDeclaration.typeName(\n    resolver: Resolver,\n    typeArgumentTypeLookup: TypeArgumentTypeLookup\n): TypeName {\n    if (this is KSTypeAlias) {\n        return this.type.typeName(resolver, typeArgumentTypeLookup)\n    }\n    if (this is KSTypeParameter) {\n        return this.typeName(resolver, typeArgumentTypeLookup)\n    }\n    // if there is no qualified name, it is a resolution error so just return shared instance\n    // KSP may improve that later and if not, we can improve it in Room\n    // TODO: https://issuetracker.google.com/issues/168639183\n    val qualified = qualifiedName?.asString() ?: return ERROR_TYPE_NAME\n\n    // Special case for kotlin.Unit - should map to kotlin.Unit, not java.lang.Void\n    if (qualified == \"kotlin.Unit\") {\n        return ClassName.get(\"kotlin\", \"Unit\")\n    }\n\n    val jvmSignature = resolver.mapToJvmSignature(this)\n    if (jvmSignature != null && jvmSignature.isNotBlank()) {\n        return jvmSignature.typeNameFromJvmSignature()\n    }\n\n    // fallback to custom generation, it is very likely that this is an unresolved type\n    // get the package name first, it might throw for invalid types, hence we use\n    // safeGetPackageName\n    val pkg = getNormalizedPackageName()\n    // using qualified name and pkg, figure out the short names.\n    val shortNames = if (pkg == \"\") {\n        qualified\n    } else {\n        qualified.substring(pkg.length + 1)\n    }.split('.')\n    return ClassName.get(pkg, shortNames.first(), *(shortNames.drop(1).toTypedArray()))\n}\n\n// see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.2-200\ninternal fun String.typeNameFromJvmSignature(): TypeName {\n    check(isNotEmpty())\n    return when (this[0]) {\n        'B' -> TypeName.BYTE\n        'C' -> TypeName.CHAR\n        'D' -> TypeName.DOUBLE\n        'F' -> TypeName.FLOAT\n        'I' -> TypeName.INT\n        'J' -> TypeName.LONG\n        'S' -> TypeName.SHORT\n        'Z' -> TypeName.BOOLEAN\n        'V' -> TypeName.VOID\n        'L' -> {\n            val end = lastIndexOf(\";\")\n            check(end > 0) {\n                \"invalid input $this\"\n            }\n            val simpleNamesSeparator = lastIndexOf('/')\n            val simpleNamesStart = if (simpleNamesSeparator < 0) {\n                1 // first char is 'L'\n            } else {\n                simpleNamesSeparator + 1\n            }\n            val packageName = if (simpleNamesSeparator < 0) {\n                // no package name\n                \"\"\n            } else {\n                substring(1, simpleNamesSeparator).replace('/', '.')\n            }\n            val firstSimpleNameSeparator = indexOf('$', startIndex = simpleNamesStart)\n            return if (firstSimpleNameSeparator < 0) {\n                // not nested\n                ClassName.get(packageName, substring(simpleNamesStart, end))\n            } else {\n                // nested class\n                val firstSimpleName = substring(simpleNamesStart, firstSimpleNameSeparator)\n                val restOfSimpleNames = substring(firstSimpleNameSeparator + 1, end)\n                    .split('$')\n                    .toTypedArray()\n                ClassName.get(packageName, firstSimpleName, *restOfSimpleNames)\n            }\n        }\n        '[' -> ArrayTypeName.of(substring(1).typeNameFromJvmSignature())\n        else -> error(\"unexpected jvm signature $this\")\n    }\n}\n\n/**\n * Turns a KSTypeArgument into a TypeName in java's type system.\n */\ninternal fun KSTypeArgument.typeName(\n    param: KSTypeParameter,\n    resolver: Resolver\n): TypeName = typeName(\n    param = param,\n    resolver = resolver,\n    typeArgumentTypeLookup = TypeArgumentTypeLookup()\n)\n\nprivate fun KSTypeParameter.typeName(\n    resolver: Resolver,\n    typeArgumentTypeLookup: TypeArgumentTypeLookup\n): TypeName {\n    // see https://github.com/square/javapoet/issues/842\n    typeArgumentTypeLookup[name]?.let {\n        return it\n    }\n    val mutableBounds = mutableListOf<TypeName>()\n    val typeName = createModifiableTypeVariableName(name = name.asString(), bounds = mutableBounds)\n    typeArgumentTypeLookup[name] = typeName\n    val resolvedBounds = bounds.map {\n        it.typeName(resolver, typeArgumentTypeLookup).tryBox()\n    }.toList()\n    if (resolvedBounds.isNotEmpty()) {\n        mutableBounds.addAll(resolvedBounds)\n        mutableBounds.remove(TypeName.OBJECT)\n    }\n    typeArgumentTypeLookup.remove(name)\n    return typeName\n}\n\n/**\n * This is the only function we change to fix https://issuetracker.google.com/issues/204415667\n */\nprivate fun KSTypeArgument.typeName(\n    param: KSTypeParameter,\n    resolver: Resolver,\n    typeArgumentTypeLookup: TypeArgumentTypeLookup\n): TypeName {\n\n    val typeName by lazy { type.typeName(resolver, typeArgumentTypeLookup).tryBox() }\n\n    if (variance == Variance.STAR) {\n        return WildcardTypeName.subtypeOf(TypeName.OBJECT)\n\n        // TODO: Always returning an explicit * is not correct. Given a named type parameter and\n        // a * in a use site declaration (eg Foo<A, *>) we need to be able to differentiate the two\n        // and return the param type name instead of *, but we don't seem to have a way to tell\n        // the two apart. The * case is more common for our use cases though, so preferring that for now.\n\n//        return if (type == null || typeName == TypeName.OBJECT) {\n//            // explicit *\n//            WildcardTypeName.subtypeOf(TypeName.OBJECT)\n//        } else {\n//            param.typeName(resolver, typeArgumentTypeLookup)\n//        }\n    }\n\n    // If the use site variance overrides declaration site variance (only in java sources)) we need to use that,\n    // otherwise declaration site variance is inherited. Invariance is the default, so we check for that.\n    return when (if (variance != Variance.INVARIANT) variance else param.variance) {\n        Variance.CONTRAVARIANT -> {\n            // It's impossible to have a super type of Object\n            if (typeName == ClassName.OBJECT) {\n                typeName\n            } else {\n                WildcardTypeName.supertypeOf(typeName)\n            }\n        }\n        Variance.COVARIANT -> {\n            // Cannot have a final type as an upper bound\n            if (this@typeName.type?.resolve()?.declaration?.isOpen() == true) {\n                WildcardTypeName.subtypeOf(typeName)\n            } else {\n                typeName\n            }\n        }\n        else -> typeName\n    }\n}\n\n/**\n * Turns a KSType into a TypeName in java's type system.\n */\ninternal fun KSType.typeName(resolver: Resolver): TypeName =\n    typeName(\n        resolver = resolver,\n        typeArgumentTypeLookup = TypeArgumentTypeLookup()\n    )\n\nprivate fun KSType.typeName(\n    resolver: Resolver,\n    typeArgumentTypeLookup: TypeArgumentTypeLookup\n): TypeName {\n    return if (this.arguments.isNotEmpty()) {\n        val args: Array<TypeName> = this.arguments\n            .mapIndexed { index, typeArg ->\n                typeArg.typeName(\n                    param = this.declaration.typeParameters[index],\n                    resolver = resolver,\n                    typeArgumentTypeLookup = typeArgumentTypeLookup\n                )\n            }\n            .map { it.tryBox() }\n            .let { args ->\n                if (this.isSuspendFunctionType) args.convertToSuspendSignature()\n                else args\n            }\n            .toTypedArray()\n\n        when (\n            val typeName = declaration\n                .typeName(resolver, typeArgumentTypeLookup).tryBox()\n        ) {\n            is ArrayTypeName -> ArrayTypeName.of(args.single())\n            is ClassName -> ParameterizedTypeName.get(\n                typeName,\n                *args\n            )\n            else -> error(\"Unexpected type name for KSType: $typeName\")\n        }\n    } else {\n        this.declaration.typeName(resolver, typeArgumentTypeLookup)\n    }\n}\n\n/**\n * Transforms [this] list of arguments to a suspend signature. For a [suspend] functional type, we\n * need to transform it to be a FunctionX with a [Continuation] with the correct return type. A\n * transformed SuspendFunction looks like this:\n *\n * FunctionX<[? super $params], ? super Continuation<? super $ReturnType>, ?>\n */\nprivate fun List<TypeName>.convertToSuspendSignature(): List<TypeName> {\n    val args = this\n\n    // The last arg is the return type, so take everything except the last arg\n    val actualArgs = args.subList(0, args.size - 1)\n    val continuationReturnType = WildcardTypeName.supertypeOf(args.last())\n    val continuationType = ParameterizedTypeName.get(\n        ClassName.get(Continuation::class.java),\n        continuationReturnType\n    )\n    return actualArgs + listOf(\n        WildcardTypeName.supertypeOf(continuationType),\n        WildcardTypeName.subtypeOf(TypeName.OBJECT)\n    )\n}\n\n/**\n * Root package comes as <root> instead of \"\" so we work around it here.\n */\ninternal fun KSDeclaration.getNormalizedPackageName(): String {\n    return packageName.asString().let {\n        if (it == \"<root>\") {\n            \"\"\n        } else {\n            it\n        }\n    }\n}\n\n/**\n * The private constructor of [TypeVariableName] which receives a list.\n * We use this in [createModifiableTypeVariableName] to create a [TypeVariableName] whose bounds\n * can be modified afterwards.\n */\nprivate val typeVarNameConstructor by lazy {\n    try {\n        TypeVariableName::class.java.getDeclaredConstructor(\n            String::class.java,\n            List::class.java\n        ).also {\n            it.isAccessible = true\n        }\n    } catch (ex: NoSuchMethodException) {\n        throw IllegalStateException(\n            \"\"\"\n            Room couldn't find the constructor it is looking for in JavaPoet.\n            Please file a bug.\n            \"\"\".trimIndent(),\n            ex\n        )\n    }\n}\n\n/**\n * Creates a TypeVariableName where we can change the bounds after constructor.\n * This is used to workaround a case for self referencing type declarations.\n * see b/187572913 for more details\n */\nprivate fun createModifiableTypeVariableName(\n    name: String,\n    bounds: List<TypeName>\n): TypeVariableName = typeVarNameConstructor.newInstance(\n    name,\n    bounds\n) as TypeVariableName\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Utils.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XExecutableParameterElement\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XHasModifiers\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XRawType\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.XTypeElement\nimport com.squareup.javapoet.MethodSpec\nimport com.squareup.javapoet.ParameterSpec\nimport com.squareup.javapoet.TypeName\nimport java.util.regex.Pattern\nimport kotlin.reflect.KClass\n\ninternal object Utils {\n    private val PATTERN_STARTS_WITH_SET =\n        Pattern.compile(\"set[A-Z]\\\\w*\")\n    const val EPOXY_MODEL_TYPE = \"com.airbnb.epoxy.EpoxyModel<?>\"\n    const val UNTYPED_EPOXY_MODEL_TYPE = \"com.airbnb.epoxy.EpoxyModel\"\n    const val EPOXY_VIEW_HOLDER_TYPE = \"com.airbnb.epoxy.EpoxyViewHolder\"\n    const val EPOXY_HOLDER_TYPE = \"com.airbnb.epoxy.EpoxyHolder\"\n    const val ANDROID_VIEW_TYPE = \"android.view.View\"\n    const val EPOXY_CONTROLLER_TYPE = \"com.airbnb.epoxy.EpoxyController\"\n    const val VIEW_CLICK_LISTENER_TYPE = \"android.view.View.OnClickListener\"\n    const val VIEW_LONG_CLICK_LISTENER_TYPE = \"android.view.View.OnLongClickListener\"\n    const val VIEW_CHECKED_CHANGE_LISTENER_TYPE =\n        \"android.widget.CompoundButton.OnCheckedChangeListener\"\n    const val GENERATED_MODEL_INTERFACE = \"com.airbnb.epoxy.GeneratedModel\"\n    const val MODEL_CLICK_LISTENER_TYPE = \"com.airbnb.epoxy.OnModelClickListener\"\n    const val MODEL_LONG_CLICK_LISTENER_TYPE = \"com.airbnb.epoxy.OnModelLongClickListener\"\n    const val MODEL_CHECKED_CHANGE_LISTENER_TYPE =\n        \"com.airbnb.epoxy.OnModelCheckedChangeListener\"\n    const val ON_BIND_MODEL_LISTENER_TYPE = \"com.airbnb.epoxy.OnModelBoundListener\"\n    const val ON_UNBIND_MODEL_LISTENER_TYPE = \"com.airbnb.epoxy.OnModelUnboundListener\"\n    const val WRAPPED_LISTENER_TYPE = \"com.airbnb.epoxy.WrappedEpoxyModelClickListener\"\n    const val WRAPPED_CHECKED_LISTENER_TYPE =\n        \"com.airbnb.epoxy.WrappedEpoxyModelCheckedChangeListener\"\n    const val ON_VISIBILITY_STATE_MODEL_LISTENER_TYPE =\n        \"com.airbnb.epoxy.OnModelVisibilityStateChangedListener\"\n    const val ON_VISIBILITY_MODEL_LISTENER_TYPE =\n        \"com.airbnb.epoxy.OnModelVisibilityChangedListener\"\n\n    @JvmStatic\n    @Throws(EpoxyProcessorException::class)\n    fun throwError(msg: String?, vararg args: Any?) {\n        throw EpoxyProcessorException(String.format(msg!!, *args))\n    }\n\n    @JvmStatic\n    fun buildEpoxyException(\n        msg: String?,\n        vararg args: Any?\n    ): EpoxyProcessorException {\n        return EpoxyProcessorException(String.format(msg!!, *args))\n    }\n\n    fun buildEpoxyException(\n        element: XElement,\n        msg: String?,\n        vararg args: Any?\n    ): EpoxyProcessorException {\n        return EpoxyProcessorException(\n            message = String.format(msg!!, *args),\n            element = element\n        )\n    }\n\n    @JvmStatic\n    fun isIterableType(element: XType, memoizer: Memoizer): Boolean {\n        return element.isSubTypeOf(memoizer.iterableType)\n    }\n\n    fun XType.isSet(processingEnv: XProcessingEnv): Boolean = isAssignableToRawType(processingEnv, Set::class)\n\n    fun XType.isMap(processingEnv: XProcessingEnv): Boolean = isAssignableToRawType(processingEnv, Map::class)\n\n    fun XType.isIterable(processingEnv: XProcessingEnv): Boolean = isAssignableToRawType(processingEnv, Iterable::class)\n\n    fun XType.isClass(processingEnv: XProcessingEnv): Boolean = isAssignableToRawType(processingEnv, Class::class)\n\n    fun XType.isAssignableToRawType(processingEnv: XProcessingEnv, targetClass: KClass<*>): Boolean {\n        if (this.isTypeOf(targetClass)) return true\n\n        val targetRawType = processingEnv.requireTypeElement(targetClass).type.rawType\n        return targetRawType.isAssignableFrom(this.rawType)\n    }\n\n    /**\n     * Checks if the given field has package-private visibility\n     */\n    @JvmStatic\n    fun isFieldPackagePrivate(element: XElement): Boolean {\n        if (element !is XHasModifiers) return false\n\n        return !element.isPrivate() && !element.isProtected() && !element.isPublic()\n    }\n\n    /**\n     * @return True if the clazz (or one of its superclasses) implements the given method. Returns\n     * false if the method doesn't exist anywhere in the class hierarchy or it is abstract.\n     */\n    fun implementsMethod(\n        clazz: XTypeElement,\n        method: MethodSpec,\n        environment: XProcessingEnv\n    ): Boolean {\n        val methodOnClass = getMethodOnClass(clazz, method, environment) ?: return false\n        return !methodOnClass.isAbstract()\n    }\n\n    /**\n     * @return The first element matching the given method in the class's hierarchy, or null if there\n     * is no match.\n     */\n    @JvmStatic\n    fun getMethodOnClass(\n        clazz: XTypeElement,\n        method: MethodSpec,\n        environment: XProcessingEnv,\n    ): XMethodElement? {\n        clazz.getDeclaredMethods()\n            .firstOrNull { methodElement ->\n                methodElement.name == method.name && areParamsTheSame(\n                    methodElement,\n                    method,\n                    environment\n                )\n            }?.let { return it }\n\n        val superClazz = clazz.superClass?.typeElement ?: return null\n        return getMethodOnClass(superClazz, method, environment)\n    }\n\n    private fun areParamsTheSame(\n        method1: XMethodElement,\n        method2: MethodSpec,\n        environment: XProcessingEnv,\n    ): Boolean {\n        val params1 = method1.parameters\n        val params2 = method2.parameters\n        if (params1.size != params2.size) {\n            return false\n        }\n\n        for (i in params1.indices) {\n            val param1: XExecutableParameterElement = params1[i]\n            val param2: ParameterSpec = params2[i]\n            val param1Type: XRawType = param1.type.rawType\n\n            val param2Type: XRawType = environment.requireType(param2.type.toString()).rawType\n\n            // If a param is a type variable then we don't need an exact type match, it just needs to\n            // be assignable\n            if (param1.type.extendsBound() == null) {\n                if (!param1Type.isAssignableFrom(param2Type)) {\n                    return false\n                }\n            } else if (param1Type != param2Type) {\n                return false\n            }\n        }\n        return true\n    }\n\n    /**\n     * Returns the type of the Epoxy model.\n     *\n     * Eg for \"class MyModel extends EpoxyModel<TextView>\" it would return TextView.\n     </TextView> */\n    fun getEpoxyObjectType(\n        clazz: XTypeElement,\n        memoizer: Memoizer\n    ): XType? {\n        val superTypeElement = clazz.superClass?.typeElement ?: return null\n\n        val recursiveResult = getEpoxyObjectType(superTypeElement, memoizer)\n        if (recursiveResult != null &&\n            // Make sure that the type isn't just the generic \"T\" and that it has at least\n            // some type information. if it has a type element then it is a concrete type\n            // or if it has some upper bound then it extends something concrete.\n            (recursiveResult.typeElement != null || recursiveResult.extendsBound()?.typeElement != null)\n        ) {\n            // Use the type on the parent highest in the class hierarchy so we can find the original type.\n            return recursiveResult\n        }\n\n        // Note, the \"superTypeElement\" loses the typing information, so we must use the\n        // superType directly off the class.\n        val superTypeArguments = clazz.superClass?.typeArguments ?: emptyList()\n\n        // If there is only one type then we use that\n        superTypeArguments.singleOrNull()?.let { return it }\n\n        for (superTypeArgument in superTypeArguments) {\n            // The user might have added additional types to their class which makes it more difficult\n            // to figure out the base model type. We just look for the first type that is a view or\n            // view holder.\n            // Also, XProcessing does not expose the type kind, so we can't directly tell if it is\n            // a bounded \"T\" type var, or a concrete type. We check for this instead by\n            // making sure a type element exists which indicates a concrete type.\n            if (superTypeArgument.isSubTypeOf(memoizer.androidViewType) ||\n                superTypeArgument.isSubTypeOf(memoizer.epoxyHolderType)\n            ) {\n                return superTypeArgument\n            }\n        }\n        return null\n    }\n\n    @JvmOverloads\n    fun validateFieldAccessibleViaGeneratedCode(\n        fieldElement: XElement,\n        annotationClass: Class<*>,\n        logger: Logger,\n        // KSP sees the backing field, not the property, which is private, and there isn't an\n        // easy way to lookup the corresponding property to check its visibility, so we just\n        // skip that for KSP since this is a legacy processor anyway.\n        skipPrivateFieldCheck: Boolean = fieldElement.isKsp\n    ): Boolean {\n        if (fieldElement !is XHasModifiers) return false\n        val enclosingElement = fieldElement.enclosingTypeElement!!\n\n        if (fieldElement !is XFieldElement) {\n            logger.logError(\n                fieldElement,\n                \"%s annotation must be on field. (class: %s, element: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName,\n                fieldElement.expectName\n            )\n            return false\n        }\n\n        if (fieldElement.isPrivate() && !skipPrivateFieldCheck) {\n            logger.logError(\n                fieldElement,\n                \"%s annotations must not be on private fields. (class: %s, field: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName,\n                fieldElement.expectName\n            )\n            return false\n        }\n\n        if (fieldElement.isStatic()) {\n            logger.logError(\n                fieldElement,\n                \"%s annotations must not be on static fields. (class: %s, field: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName,\n                fieldElement.expectName\n            )\n            return false\n        }\n\n        // Nested classes must be static\n        if (enclosingElement.enclosingTypeElement != null && !enclosingElement.isStatic()) {\n            logger.logError(\n                fieldElement,\n                \"Nested classes with %s annotations must be static. (class: %s, field: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName,\n                fieldElement.expectName\n            )\n            return false\n        }\n\n        // Verify containing type.\n        if (!enclosingElement.isClass()) {\n            logger.logError(\n                fieldElement,\n                \"%s annotations may only be contained in classes. (class: %s, field: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName, fieldElement.expectName\n            )\n            return false\n        }\n\n        // Verify containing class visibility is not private.\n        if (enclosingElement.isPrivate()) {\n            logger.logError(\n                fieldElement,\n                \"%s annotations may not be contained in private classes. (class: %s, field: %s)\",\n                annotationClass.simpleName,\n                enclosingElement.expectName, fieldElement.expectName\n            )\n            return false\n        }\n\n        return true\n    }\n\n    @JvmStatic\n    fun capitalizeFirstLetter(original: String?): String? {\n        return if (original == null || original.isEmpty()) {\n            original\n        } else original.substring(0, 1).uppercase() + original.substring(1)\n    }\n\n    @JvmStatic\n    fun startsWithIs(original: String): Boolean {\n        return original.startsWith(\"is\") && original.length > 2 && Character.isUpperCase(original[2])\n    }\n\n    fun isSetterMethod(element: XElement): Boolean {\n        val method = element as? XMethodElement ?: return false\n        return PATTERN_STARTS_WITH_SET.matcher(method.name).matches() &&\n            method.parameters.size == 1\n    }\n\n    fun removeSetPrefix(string: String): String {\n        return if (!PATTERN_STARTS_WITH_SET.matcher(string).matches()) {\n            string\n        } else string[3].toString()\n            .lowercase() + string.substring(4)\n    }\n\n    fun toSnakeCase(s: String): String {\n        return s.replace(\"([^_A-Z])([A-Z])\".toRegex(), \"$1_$2\").lowercase()\n    }\n\n    fun getDefaultValue(attributeType: TypeName): String {\n        return when {\n            attributeType === TypeName.BOOLEAN -> \"false\"\n            attributeType === TypeName.INT -> \"0\"\n            attributeType === TypeName.BYTE -> \"(byte) 0\"\n            attributeType === TypeName.CHAR -> \"(char) 0\"\n            attributeType === TypeName.SHORT -> \"(short) 0\"\n            attributeType === TypeName.LONG -> \"0L\"\n            attributeType === TypeName.FLOAT -> \"0.0f\"\n            attributeType === TypeName.DOUBLE -> \"0.0d\"\n            else -> \"null\"\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ViewAttributeInfo.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.annotation.NonNull\nimport androidx.annotation.Nullable\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XNullability\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.XVariableElement\nimport androidx.room.compiler.processing.isField\nimport androidx.room.compiler.processing.isMethod\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelProp.Option\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.processor.Utils.capitalizeFirstLetter\nimport com.airbnb.epoxy.processor.Utils.getDefaultValue\nimport com.airbnb.epoxy.processor.Utils.isFieldPackagePrivate\nimport com.airbnb.epoxy.processor.Utils.removeSetPrefix\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport com.squareup.javapoet.AnnotationSpec\nimport com.squareup.javapoet.ArrayTypeName\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.ParameterizedTypeName\nimport com.squareup.javapoet.TypeName\nimport com.squareup.javapoet.TypeVariableName\n\ninternal val NON_NULL_ANNOTATION_SPEC = AnnotationSpec.builder(NonNull::class.java).build()\ninternal val NULLABLE_ANNOTATION_SPEC = AnnotationSpec.builder(Nullable::class.java).build()\n\nsealed class ViewAttributeType {\n    object Method : ViewAttributeType()\n    object Field : ViewAttributeType()\n}\n\nclass ViewAttributeInfo(\n    private val viewElement: XTypeElement,\n    viewPackage: String,\n    val hasDefaultKotlinValue: Boolean,\n    val viewAttributeElement: XElement,\n    logger: Logger,\n    resourceProcessor: ResourceScanner,\n    memoizer: Memoizer\n) : AttributeInfo(memoizer) {\n    val propName: String\n    val viewAttributeName: String\n    val resetWithNull: Boolean\n    val generateStringOverloads: Boolean\n    val viewAttributeTypeName: ViewAttributeType?\n    var constantFieldNameForDefaultValue: String? = null\n\n    init {\n        val propAnnotation = viewAttributeElement.getAnnotation(ModelProp::class)\n        val textAnnotation = viewAttributeElement.getAnnotation(TextProp::class)\n        val callbackAnnotation = viewAttributeElement.getAnnotation(CallbackProp::class)\n\n        val options = HashSet<Option>()\n        val param: XVariableElement = when (viewAttributeElement) {\n            is XMethodElement -> viewAttributeElement.parameters.first()\n            is XVariableElement -> viewAttributeElement\n            else -> error(\"Unsupported element type $viewAttributeElement\")\n        }\n\n        viewAttributeTypeName = getViewAttributeType(viewAttributeElement, logger)\n\n        groupKey = \"\"\n        var defaultConstant = \"\"\n        if (propAnnotation != null) {\n            defaultConstant = propAnnotation.getAsString(\"defaultValue\")\n            groupKey = propAnnotation.getAsString(\"group\")\n            options.addAll(propAnnotation.getAsEnumList(\"options\").map { Option.valueOf(it.name) })\n            options.addAll(propAnnotation.getAsEnumList(\"value\").map { Option.valueOf(it.name) })\n        } else if (textAnnotation != null) {\n            val stringResValue = textAnnotation.getAsInt(\"defaultRes\")\n            if (stringResValue != 0) {\n                val stringResource = resourceProcessor.getResourceValue(\n                    TextProp::class,\n                    viewAttributeElement,\n                    \"defaultRes\",\n                    stringResValue\n                )\n                if (!stringResource.isStringResource()) {\n                    logger.logError(\n                        viewAttributeElement,\n                        \"@TextProp value for defaultRes must be a String resource.\"\n                    )\n                }\n                codeToSetDefault.explicit = stringResource.code\n            }\n            options.add(Option.GenerateStringOverloads)\n        } else if (callbackAnnotation != null) {\n            options.add(Option.DoNotHash)\n            if (param.isNullable()) {\n                options.add(Option.NullOnRecycle)\n            } else {\n                logger.logError(\n                    \"Setters with %s must be marked Nullable\",\n                    CallbackProp::class.java.simpleName\n                )\n            }\n        }\n\n        generateSetter = true\n        generateGetter = true\n        hasFinalModifier = false\n        isPackagePrivate = isFieldPackagePrivate(viewAttributeElement)\n        isGenerated = true\n\n        useInHash = Option.DoNotHash !in options\n        ignoreRequireHashCode = Option.IgnoreRequireHashCode in options\n        resetWithNull = Option.NullOnRecycle in options\n        generateStringOverloads = Option.GenerateStringOverloads in options\n\n        this.rootClass = viewElement.name\n        this.packageName = viewPackage\n\n        this.viewAttributeName = viewAttributeElement.expectName\n        propName = removeSetPrefix(viewAttributeName)\n        setXType(param.type, memoizer)\n        assignDefaultValue(defaultConstant, logger)\n        assignNullability(param)\n\n        // TODO: (eli_hart 9/26/17) Get the javadoc on the super method if this setter overrides\n        // something and doesn't have its own javadoc\n        createJavaDoc(\n            viewAttributeElement.docComment,\n            codeToSetDefault,\n            constantFieldNameForDefaultValue,\n            viewElement,\n            typeName,\n            viewAttributeName\n        )\n\n        validatePropOptions(logger, options, memoizer)\n\n        if (generateStringOverloads) {\n            setXType(\n                memoizer.stringAttributeType,\n                memoizer\n            )\n\n            if (codeToSetDefault.isPresent) {\n                if (codeToSetDefault.explicit != null) {\n                    codeToSetDefault.explicit = CodeBlock.of(\n                        \" new \\$T(\\$L)\", typeName,\n                        codeToSetDefault.explicit\n                    )\n                }\n\n                if (codeToSetDefault.implicit != null) {\n                    codeToSetDefault.implicit = CodeBlock.of(\n                        \" new \\$T(\\$L)\", typeName,\n                        codeToSetDefault.implicit\n                    )\n                }\n            } else {\n                codeToSetDefault.implicit = CodeBlock.of(\" new \\$T()\", typeName)\n            }\n        }\n\n        // Suffix the field name with the type to prevent collisions from overloaded setter methods\n        this.fieldName = propName + \"_\" + getSimpleName(typeName)\n\n        parseAnnotations(param, param.isNullable(), typeName)\n        if (generateStringOverloads) {\n            // Since we generate other setters like @StringRes it doesn't make sense to carryover\n            // annotations that might not apply to other param types\n            setterAnnotations.clear()\n            getterAnnotations.clear()\n        }\n    }\n\n    override val isRequired\n        get() = when {\n            hasDefaultKotlinValue -> false\n            generateStringOverloads -> !isNullable() && constantFieldNameForDefaultValue == null\n            else -> super.isRequired\n        }\n\n    private fun getViewAttributeType(\n        element: XElement,\n        logger: Logger\n    ): ViewAttributeType? = when {\n        element.isMethod() -> ViewAttributeType.Method\n        element.isField() -> ViewAttributeType.Field\n        else -> {\n            logger.logError(\n                element,\n                \"Element must be either method or field (element: %s)\",\n                element\n            )\n            null\n        }\n    }\n\n    private fun assignNullability(\n        paramElement: XVariableElement,\n    ) {\n        if (isPrimitive) {\n            return\n        }\n\n        // Default to not nullable\n        isNullable = false\n\n        if (paramElement.isNullable()) {\n            isNullable = true\n            // Need to cast the null because if there are other overloads with the same method\n            // name this can be ambiguous and fail to compile\n            codeToSetDefault.implicit = CodeBlock.of(\"(\\$T) null\", typeName)\n        }\n    }\n\n    private fun XVariableElement.isNullable(): Boolean {\n        // There are multiple packages/frameworks that define a Nullable annotation and we want\n        // to support all of them. We just check for a class named Nullable and ignore the\n        // package.\n        fun hasNullableAnnotation() = getAllAnnotations().any { it.name == \"Nullable\" }\n\n        // When processing with KSP nullability is reported differently - we can't look at nullability\n        // annotations as those are only generated for kotlin types in kapt.\n        // KSP can also report normal java types as nullable if there are no nullability annotations\n        // on them, but we consider the lack of a nullability annotation as not null\n        return if (memoizer.environment.backend == XProcessingEnv.Backend.KSP) {\n            if (isJavaSourceInKsp()) {\n                hasNullableAnnotation()\n            } else {\n                type.nullability == XNullability.NULLABLE\n            }\n        } else {\n            hasNullableAnnotation()\n        }\n    }\n\n    private fun assignDefaultValue(\n        defaultConstant: String,\n        logger: Logger,\n    ) {\n\n        if (hasDefaultKotlinValue) {\n            if (defaultConstant.isNotEmpty()) {\n                logger.logError(\n                    \"Default set via both kotlin parameter and annotation constant. Use only one. (%s#%s)\",\n                    viewElement.name,\n                    viewAttributeName\n                )\n            }\n            return\n        }\n\n        if (defaultConstant.isEmpty()) {\n            if (isPrimitive) {\n                codeToSetDefault.implicit = CodeBlock.of(getDefaultValue(typeName))\n            }\n\n            return\n        }\n\n        var viewClass: XTypeElement? = viewElement\n        while (viewClass != null) {\n            for (element in viewClass.getDeclaredFields()) {\n                if (checkElementForConstant(element, defaultConstant, logger)) {\n                    return\n                }\n            }\n\n            viewClass = viewClass.superClass?.typeElement\n        }\n\n        logger.logError(\n            viewElement,\n            \"The default value for (%s#%s) could not be found. Expected a constant named \" +\n                \"'%s' in the \" + \"view class.\",\n            viewElement.name, viewAttributeName, defaultConstant\n        )\n    }\n\n    private fun checkElementForConstant(\n        element: XFieldElement,\n        constantName: String,\n        logger: Logger\n    ): Boolean {\n        if (!element.isField() || element.name != constantName) {\n            return false\n        }\n\n        if (!element.isFinal() ||\n            !element.isStatic() ||\n            // KSP/XProcessing sees companion property fields as private even when they're not.\n            // It would be hard to look up the correct information with xprocessing, so we just\n            // ignore that check with ksp. If it is actually private it will be a compiler error\n            // when the generated code accesses it, which will still be fairly clear.\n            (element.isPrivate() && memoizer.environment.backend != XProcessingEnv.Backend.KSP)\n        ) {\n            logger.logError(\n                element,\n                \"Default values for view props must be static, final, and not private. \" +\n                    \"(%s#%s)\",\n                viewElement.name, viewAttributeName\n            )\n            return true\n        }\n\n        // Make sure that the type of the default value is a valid type for the prop\n        if (!element.type.isSubTypeOf(xType)) {\n            logger.logError(\n                element,\n                \"The default value for (%s#%s) must be a %s.\",\n                viewElement.name, viewAttributeName, typeName\n            )\n            return true\n        }\n        constantFieldNameForDefaultValue = constantName\n\n        codeToSetDefault.explicit = CodeBlock.of(\n            \"\\$T.\\$L\",\n            viewElement.asClassName().toJavaPoet(),\n            constantName\n        )\n\n        return true\n    }\n\n    private fun validatePropOptions(\n        logger: Logger,\n        options: Set<Option>,\n        memoizer: Memoizer\n    ) {\n        if (options.contains(Option.IgnoreRequireHashCode) && options.contains(Option.DoNotHash)) {\n            logger\n                .logError(\n                    \"Illegal to use both %s and %s options in an %s annotation. (%s#%s)\",\n                    Option.DoNotHash, Option.IgnoreRequireHashCode,\n                    ModelProp::class.java.simpleName, rootClass, viewAttributeName\n                )\n        }\n\n        if (options.contains(Option.GenerateStringOverloads) &&\n            !(xType.isSameType(memoizer.charSequenceType) || xType.isSameType(memoizer.charSequenceNullableType))\n        ) {\n            logger\n                .logError(\n                    viewAttributeElement,\n                    \"Setters with %s option must be a CharSequence. (%s#%s)\",\n                    Option.GenerateStringOverloads, rootClass, viewAttributeName\n                )\n        }\n\n        if (options.contains(Option.NullOnRecycle) && (!hasSetNullability() || !isNullable())) {\n            logger\n                .logError(\n                    \"Setters with %s option must have a type that is annotated with @Nullable. \" +\n                        \"(%s#%s)\",\n                    Option.NullOnRecycle, rootClass, viewAttributeName\n                )\n        }\n    }\n\n    /** Tries to return the simple name of the given type.  */\n    private fun getSimpleName(name: TypeName): String? {\n        if (name.isPrimitive) {\n            return capitalizeFirstLetter(name.withoutAnnotations().toString())\n        }\n\n        return when (name) {\n            is ClassName -> name.simpleName()\n            is ArrayTypeName -> getSimpleName(name.componentType)!! + \"Array\"\n            is ParameterizedTypeName -> getSimpleName(name.rawType)\n            is TypeVariableName -> capitalizeFirstLetter(name.name)\n            // Don't expect this to happen\n            else -> name.toString().replace(\".\", \"\")\n        }\n    }\n\n    private fun parseAnnotations(\n        paramElement: XVariableElement,\n        markedNullable: Boolean,\n        typeName: TypeName\n    ) {\n        for (xAnnotation in paramElement.getAllAnnotations()) {\n\n            if (xAnnotation.name in ModelViewProcessor.modelPropAnnotationSimpleNames ||\n                // Doesn't make sense for suppressed warnings on the original member to be\n                // carried over to the generated code.\n                xAnnotation.name == \"SuppressWarnings\"\n            ) {\n                continue\n            }\n\n            val annotationSpec = xAnnotation.toAnnotationSpec(memoizer)\n            setterAnnotations.add(annotationSpec)\n            getterAnnotations.add(annotationSpec)\n        }\n\n        // If a param is an object and not nullable we add a non null annotation if it doesn't\n        // already have it. This is to make the generated interface more effective for IDE\n        // nullability tooling since we know epoxy will enforce that the param value is\n        // non null at run time.\n\n        // When KAPT processes kotlin sources it sees java intermediary, which has automatically\n        // generated nullability annotations which we automatically inherit. However, with\n        // KSP we see the kotlin code directly so we don't get those annotations by default\n        // and our poet classnames lose nullability info, so we add it manually.\n\n        // primitives cannot be null\n        if (!typeName.isPrimitive) {\n\n            // Look at just simple name of annotation as there are many packages providing them (eg androidx, jetbrains)\n            val annotations = setterAnnotations.map { annotation ->\n                when (val type = annotation.type) {\n                    is ClassName -> type.simpleName()\n                    else -> annotation.toString().substringAfterLast(\".\")\n                }\n            }\n\n            if (markedNullable) {\n                if (annotations.none { it == \"Nullable\" }) {\n                    setterAnnotations.add(NULLABLE_ANNOTATION_SPEC)\n                    getterAnnotations.add(NULLABLE_ANNOTATION_SPEC)\n                }\n            } else {\n                if (annotations.none { it == \"NotNull\" || it == \"NonNull\" }) {\n                    setterAnnotations.add(NON_NULL_ANNOTATION_SPEC)\n                    getterAnnotations.add(NON_NULL_ANNOTATION_SPEC)\n                }\n            }\n        }\n    }\n\n    private fun createJavaDoc(\n        docComment: String?,\n        codeToSetDefault: DefaultValue,\n        constantFieldNameForDefaultValue: String?,\n        viewElement: XTypeElement,\n        attributeTypeName: TypeName,\n        viewAttributeName: String\n    ) {\n        setJavaDocString(docComment)\n\n        if (javaDoc == null) {\n            javaDoc = CodeBlock.of(\"\")\n        }\n\n        val builder = javaDoc!!.toBuilder()\n\n        if (!javaDoc!!.isEmpty) {\n            builder.add(\"\\n<p>\\n\")\n        }\n\n        if (isRequired) {\n            builder.add(\"<i>Required.</i>\")\n        } else {\n            builder.add(\"<i>Optional</i>: \")\n            when {\n                hasDefaultKotlinValue -> {\n                    builder.add(\"View function has a Kotlin default argument\")\n                }\n                constantFieldNameForDefaultValue == null -> {\n                    builder.add(\"Default value is \\$L\", codeToSetDefault.value())\n                }\n                else -> {\n                    builder.add(\n                        \"Default value is <b>{@value \\$T#\\$L}</b>\",\n                        viewElement.asClassName().toJavaPoet(),\n                        constantFieldNameForDefaultValue\n                    )\n                }\n            }\n        }\n\n        if (viewAttributeTypeName == ViewAttributeType.Field) {\n            builder.add(\n                \"\\n\\n@see \\$T#\\$L\",\n                viewElement.type.typeNameWithWorkaround(memoizer),\n                viewAttributeName\n            )\n        } else {\n            builder.add(\n                \"\\n\\n@see \\$T#\\$L(\\$T)\",\n                viewElement.type.typeNameWithWorkaround(memoizer),\n                viewAttributeName,\n                attributeTypeName\n            )\n        }\n\n        javaDoc = builder\n            .add(\"\\n\").build()\n    }\n\n    override fun generatedSetterName(): String = propName\n\n    override fun generatedGetterName(isOverload: Boolean): String {\n        if (isOverload) {\n            // Avoid method name collisions for overloaded method by appending the return type\n            return propName + getSimpleName(typeName)!!\n        } else if (generateStringOverloads) {\n            return \"get\" + capitalizeFirstLetter(propName)\n        }\n\n        return propName\n    }\n\n    override fun toString(): String {\n        return (\n            \"View Prop {\" +\n                \"view='\" + viewElement.name + '\\'' +\n                \", name='\" + viewAttributeName + '\\'' +\n                \", type=\" + typeName +\n                \", hasDefaultKotlinValue=\" + hasDefaultKotlinValue +\n                '}'\n            )\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/XProcessingUtils.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.room.compiler.codegen.toJavaPoet\nimport androidx.room.compiler.processing.XAnnotation\nimport androidx.room.compiler.processing.XAnnotationValue\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XEnumEntry\nimport androidx.room.compiler.processing.XExecutableElement\nimport androidx.room.compiler.processing.XFieldElement\nimport androidx.room.compiler.processing.XHasModifiers\nimport androidx.room.compiler.processing.XMethodElement\nimport androidx.room.compiler.processing.XType\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.XVariableElement\nimport androidx.room.compiler.processing.compat.XConverters.toJavac\nimport androidx.room.compiler.processing.isVoid\nimport androidx.room.compiler.processing.isVoidObject\nimport com.airbnb.epoxy.processor.ClassNames.KOTLIN_ANY\nimport com.airbnb.epoxy.processor.resourcescanning.getFieldWithReflection\nimport com.google.devtools.ksp.symbol.KSAnnotated\nimport com.google.devtools.ksp.symbol.KSAnnotation\nimport com.google.devtools.ksp.symbol.KSDeclaration\nimport com.google.devtools.ksp.symbol.KSFile\nimport com.google.devtools.ksp.symbol.KSNode\nimport com.google.devtools.ksp.symbol.KSPropertyDeclaration\nimport com.google.devtools.ksp.symbol.Origin\nimport com.squareup.javapoet.AnnotationSpec\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.ParameterSpec\nimport java.lang.Character.isISOControl\nimport javax.lang.model.element.Modifier\nimport kotlin.reflect.KClass\n\n/**\n * Look up enclosing type element if this is a field or function within a class.\n */\nval XElement.enclosingTypeElement: XTypeElement?\n    get() {\n        return when (this) {\n            is XExecutableElement -> enclosingElement as? XTypeElement\n            is XFieldElement -> enclosingElement as? XTypeElement\n            else -> null\n        }\n    }\n\nfun XTypeElement.hasOverload(element: XMethodElement, paramCount: Int): Boolean {\n    return findOverload(element, paramCount) != null\n}\n\nfun XTypeElement.findOverload(element: XMethodElement, paramCount: Int): XMethodElement? {\n    require(element.parameters.size != paramCount) { \"Element $element already has param count $paramCount\" }\n\n    return getDeclaredMethods()\n        .firstOrNull { it.parameters.size == paramCount && areOverloads(it, element) }\n}\n\n/**\n * True if the two elements represent overloads of the same function in a class.\n */\nfun areOverloads(e1: XMethodElement, e2: XMethodElement): Boolean {\n    return e1.parameters.size != e2.parameters.size &&\n        e1.name == e2.name &&\n        e1.enclosingElement == e2.enclosingElement &&\n        e1.returnType == e2.returnType &&\n        e1.isStatic() == e2.isStatic() &&\n        e1.isPrivate() == e2.isPrivate()\n}\n\n/** Return each of the classes in the class hierarchy, starting with the initial receiver and working upwards until Any. */\ntailrec fun XElement.iterateClassHierarchy(\n    classCallback: (classElement: XTypeElement) -> Unit\n) {\n    if (this !is XTypeElement) {\n        return\n    }\n\n    classCallback(this)\n\n    val superClazz = this.superClass?.typeElement\n    superClazz?.iterateClassHierarchy(classCallback)\n}\n\n/** Iterate each super class of the receiver, starting with the initial super class and going until Any. */\nfun XElement.iterateSuperClasses(\n    classCallback: (classElement: XTypeElement) -> Unit\n) {\n    iterateClassHierarchy {\n        // Skip the original class so that only super classes are passed to the callback\n        if (it != this) {\n            classCallback(it)\n        }\n    }\n}\n\n/**\n * Returns a list of annotations specs representing annotations on the given type element.\n *\n * @param annotationFilter Return false to exclude annotations with the given class name.\n */\nfun XTypeElement.buildAnnotationSpecs(\n    annotationFilter: (ClassName) -> Boolean,\n    memoizer: Memoizer\n): List<AnnotationSpec> {\n    val internalAnnotationFilter = { className: ClassName ->\n        if (className.reflectionName() == \"kotlin.Metadata\") {\n            // Don't include the generated kotlin metadata since it only applies to the original\n            // kotlin class and is wrong to put on our generated java classes.\n            false\n        } else {\n            annotationFilter(className)\n        }\n    }\n    return getAllAnnotations()\n        .map { it.toAnnotationSpec(memoizer) }\n        .filter { internalAnnotationFilter(it.type as ClassName) }\n}\n\nfun XAnnotation.toAnnotationSpec(memoizer: Memoizer): AnnotationSpec {\n\n    // Adapted from javapoet internals\n    fun AnnotationSpec.Builder.addMemberForValue(\n        memberName: String,\n        value: Any?,\n        memoizer: Memoizer\n    ): AnnotationSpec.Builder {\n        if (value is XType) {\n            return if (value.isVoid() || value.isVoidObject()) {\n                addMember(memberName, \"Void.class\")\n            } else {\n                addMember(memberName, \"\\$T.class\", value.typeNameWithWorkaround(memoizer))\n            }\n        }\n        if (value is XEnumEntry) {\n            return addMember(\n                memberName,\n                \"\\$T.\\$L\",\n                value.enclosingElement.asClassName().toJavaPoet(),\n                value.name\n            )\n        }\n        if (value is XAnnotation) {\n            return addMember(memberName, \"\\$L\", value.toAnnotationSpec(memoizer))\n        }\n        if (value is XAnnotationValue) {\n            return addMemberForValue(value.name, value.value, memoizer)\n        }\n        if (value is List<*>) {\n            if (value.isEmpty()) {\n                addMember(memberName, \"{}\")\n            } else {\n                value.forEach { listValue ->\n                    addMemberForValue(\n                        memberName,\n                        listValue ?: error(\"Unexpected null item in annotation value list\"),\n                        memoizer\n                    )\n                }\n            }\n            return this\n        }\n        if (value is String) {\n            return addMember(memberName, \"\\$S\", value)\n        }\n        if (value is Float) {\n            return addMember(memberName, \"\\$Lf\", value)\n        }\n        if (value is Char) {\n            return addMember(\n                memberName,\n                \"'\\$L'\",\n                characterLiteralWithoutSingleQuotes(value)\n            )\n        }\n        return addMember(memberName, \"\\$L\", value)\n    }\n    return AnnotationSpec.builder(ClassName.get(packageName, name)).apply {\n        // Use declaredAnnotationValues instead of annotationValues to exclude default values.\n        // This ensures consistent behavior across KSP runs, as annotationValues has been observed\n        // to non-deterministically return different results in KSP (sometimes including defaults,\n        // sometimes not).\n        //\n        // This approach mirrors Room's implementation in JavaPoetExt.kt:\n        // @see androidx.room.compiler.processing.toAnnotationSpec\n        declaredAnnotationValues.forEach { annotationValue ->\n            addMemberForValue(annotationValue.name, annotationValue.value, memoizer)\n        }\n    }.build()\n}\n\nfun XVariableElement.toParameterSpec(memoizer: Memoizer): ParameterSpec {\n    val builder = ParameterSpec.builder(\n        type.typeNameWithWorkaround(memoizer),\n        name\n    )\n    for (annotation in getAllAnnotations()) {\n        builder.addAnnotation(annotation.toAnnotationSpec(memoizer))\n    }\n\n    return builder.build()\n}\n\nfun characterLiteralWithoutSingleQuotes(c: Char): String {\n    // see https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.6\n    return when (c) {\n        '\\b' -> \"\\\\b\" /* \\u0008: backspace (BS) */\n        '\\t' -> \"\\\\t\" /* \\u0009: horizontal tab (HT) */\n        '\\n' -> \"\\\\n\" /* \\u000a: linefeed (LF) */\n        '\\r' -> \"\\\\r\" /* \\u000d: carriage return (CR) */\n        '\\\"' -> \"\\\"\" /* \\u0022: double quote (\") */\n        '\\'' -> \"\\\\'\" /* \\u0027: single quote (') */\n        '\\\\' -> \"\\\\\\\\\" /* \\u005c: backslash (\\) */\n        else -> if (isISOControl(c)) String.format(\"\\\\u%04x\", c.code) else c.toString()\n    }\n}\n\nval XAnnotation.packageName: String get() = qualifiedName.substringBeforeLast(\".$name\")\n\nfun XTypeElement.isEpoxyModel(memoizer: Memoizer): Boolean {\n    return isSubTypeOf(memoizer.epoxyModelClassElementUntyped)\n}\n\nfun XType.isEpoxyModel(memoizer: Memoizer): Boolean {\n    return typeElement?.isEpoxyModel(memoizer) == true\n}\n\nfun XType.isDataBindingEpoxyModel(memoizer: Memoizer): Boolean {\n    val databindingType = memoizer.epoxyDataBindingModelBaseClass?.type ?: return false\n    return isSubTypeOf(databindingType)\n}\n\nfun XType.isEpoxyModelWithHolder(memoizer: Memoizer): Boolean {\n    return isSubTypeOf(memoizer.epoxyModelWithHolderTypeUntyped)\n}\n\nfun XType.isEpoxyModelCollector(memoizer: Memoizer): Boolean {\n    return isSubTypeOf(memoizer.epoxyModelCollectorType)\n}\n\nfun XTypeElement.isEpoxyController(memoizer: Memoizer): Boolean {\n    return isSubTypeOf(memoizer.epoxyControllerType)\n}\n\nval XHasModifiers.javacModifiers: Set<Modifier>\n    get() {\n        return setOfNotNull(\n            if (isPublic()) Modifier.PUBLIC else null,\n            if (isProtected()) Modifier.PROTECTED else null,\n            if (isAbstract()) Modifier.ABSTRACT else null,\n            if (isPrivate()) Modifier.PRIVATE else null,\n            if (isStatic()) Modifier.STATIC else null,\n            if (isFinal()) Modifier.FINAL else null,\n            if (isTransient()) Modifier.TRANSIENT else null,\n        )\n    }\n\nval XElement.expectName: String\n    get() = when (this) {\n        is XVariableElement -> this.name\n        is XMethodElement -> this.name\n        is XTypeElement -> this.name\n        else -> throw EpoxyProcessorException(\n            \"Expected this to be a variable or method $this\",\n            element = this\n        )\n    }\n\nfun XType.isSubTypeOf(otherType: XType): Boolean {\n    // Using the normal \"isAssignableFrom\" on XType doesn't always work correctly or predictably\n    // with generics, so when we just want to check if something is a subclass without considering\n    // that this is the simplest approach.\n    // This is especially because we generally just use this to check class type hierarchies, not\n    // parameter/field types.\n    return otherType.rawType.isAssignableFrom(this)\n}\n\nfun XTypeElement.isSubTypeOf(otherType: XTypeElement): Boolean {\n    return type.isSubTypeOf(otherType.type)\n}\n\nfun XTypeElement.isSubTypeOf(otherType: XType): Boolean {\n    return type.isSubTypeOf(otherType)\n}\n\nfun XTypeElement.isInSamePackageAs(class2: XTypeElement): Boolean {\n    return packageName == class2.packageName\n}\n\nfun XType.isObjectOrAny(): Boolean = typeName == KOTLIN_ANY || typeName == ClassName.OBJECT\n\nval KSAnnotation.containingPackage: String?\n    get() = parent?.containingPackage\n\nval KSNode.containingPackage: String?\n    get() {\n        return when (this) {\n            is KSFile -> packageName.asString()\n            is KSDeclaration -> packageName.asString()\n            else -> parent?.containingPackage\n        }\n    }\n\nfun XElement.isJavaSourceInKsp(): Boolean {\n    return try {\n        val declaration = getFieldWithReflection<KSAnnotated>(\"declaration\")\n        // If getting the declaration succeeded then we are in KSP and we can check the source origin.\n        declaration.origin == Origin.JAVA || declaration.origin == Origin.JAVA_LIB\n    } catch (e: Throwable) {\n        // Not KSP\n        false\n    }\n}\n\nfun XElement.isKotlinSourceInKsp(): Boolean {\n    return try {\n        val declaration = getFieldWithReflection<KSAnnotated>(\"declaration\")\n        // If getting the declaration succeeded then we are in KSP and we can check the source origin.\n        declaration.origin == Origin.KOTLIN_LIB || declaration.origin == Origin.KOTLIN\n    } catch (e: Throwable) {\n        // Not KSP\n        false\n    }\n}\n\nval XFieldElement.declaration: KSPropertyDeclaration get() = getFieldWithReflection(\"declaration\")\n\nfun KSDeclaration.isKotlinOrigin(): Boolean {\n    return when (origin) {\n        Origin.KOTLIN -> true\n        Origin.KOTLIN_LIB -> true\n        Origin.JAVA -> false\n        Origin.JAVA_LIB -> false\n        Origin.SYNTHETIC -> false\n    }\n}\n\nval XElement.isKsp: Boolean\n    get() = try {\n        toJavac()\n        false\n    } catch (e: Throwable) {\n        true\n    }\n\nfun XTypeElement.getElementsAnnotatedWith(annotationClass: KClass<out Annotation>): List<XElement> {\n    return listOf(this).getElementsAnnotatedWith(annotationClass)\n}\n\nfun List<XTypeElement>.getElementsAnnotatedWith(annotationClass: KClass<out Annotation>): List<XElement> {\n    return flatMap { typeElement ->\n        (typeElement.getDeclaredMethods() + typeElement.getDeclaredFields()).filter { xElement ->\n            xElement.hasAnnotation(annotationClass)\n        }\n    }\n}\n\ndata class MethodInfoLight(\n    val name: String,\n    val docComment: String?,\n)\n\nfun XTypeElement.getDeclaredMethodsLight(memoizer: Memoizer): List<MethodInfoLight> {\n    return memoizer.getDeclaredMethodsLight(this)\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/resourcescanning/JavacResourceScanner.kt",
    "content": "package com.airbnb.epoxy.processor.resourcescanning\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport androidx.room.compiler.processing.compat.XConverters.toJavac\nimport com.squareup.javapoet.ClassName\nimport com.sun.source.util.Trees\nimport com.sun.tools.javac.code.Symbol.VarSymbol\nimport com.sun.tools.javac.tree.JCTree\nimport com.sun.tools.javac.tree.JCTree.JCFieldAccess\nimport com.sun.tools.javac.tree.TreeScanner\nimport java.util.HashMap\nimport javax.annotation.processing.ProcessingEnvironment\nimport javax.lang.model.element.AnnotationMirror\nimport javax.lang.model.element.Element\nimport javax.lang.model.type.MirroredTypeException\nimport javax.lang.model.util.Elements\nimport javax.lang.model.util.Types\nimport kotlin.reflect.KClass\n\nclass JavacResourceScanner(\n    processingEnv: ProcessingEnvironment,\n    environmentProvider: () -> XProcessingEnv\n) : ResourceScanner(environmentProvider) {\n    private val typeUtils: Types = processingEnv.typeUtils\n    private val elementUtils: Elements = processingEnv.elementUtils\n    private var trees: Trees? = null\n\n    init {\n        trees = try {\n            Trees.instance(processingEnv)\n        } catch (ignored: IllegalArgumentException) {\n            try {\n                // Get original ProcessingEnvironment from Gradle-wrapped one or KAPT-wrapped one.\n                // In Kapt, its field is called \"delegate\". In Gradle's, it's called \"processingEnv\"\n                processingEnv.javaClass.declaredFields.firstNotNullOfOrNull { field ->\n                    if (field.name == \"delegate\" || field.name == \"processingEnv\") {\n                        field.isAccessible = true\n                        val javacEnv = field[processingEnv] as ProcessingEnvironment\n                        Trees.instance(javacEnv)\n                    } else {\n                        null\n                    }\n                }\n            } catch (ignored2: Throwable) {\n                null\n            }\n        }\n    }\n\n    override fun getResourceValueListInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        values: List<Int>,\n    ): List<ResourceValue> {\n        val results = getResults(annotation.java, element.toJavac())\n        return results.values.filter { it.value in values }\n    }\n\n    override fun getResourceValueInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        value: Int\n    ): ResourceValue? {\n        val results = getResults(annotation.java, element.toJavac())\n        return if (results.containsKey(value)) {\n            results[value]\n        } else {\n            null\n        }\n    }\n\n    override fun getImports(classElement: XTypeElement): List<String> {\n        return trees?.getPath(classElement.toJavac())\n            ?.compilationUnit\n            ?.imports?.map { it.qualifiedIdentifier.toString() }\n            ?: emptyList()\n    }\n\n    private fun getResults(\n        annotation: Class<out Annotation?>,\n        element: Element\n    ): Map<Int, ResourceValue> {\n        val scanner = AnnotationScanner()\n        val tree = trees?.getTree(\n            element,\n            getMirror(element, annotation)\n        ) as JCTree?\n        tree?.accept(scanner)\n        return scanner.results()\n    }\n\n    private inner class AnnotationScanner : TreeScanner() {\n        private val results: MutableMap<Int, ResourceValue> = HashMap()\n\n        override fun visitSelect(jcFieldAccess: JCFieldAccess) {\n            val symbol = jcFieldAccess.sym\n            if ((symbol as? VarSymbol)?.enclosingElement?.enclosingElement?.enclClass() != null) {\n                parseResourceSymbol(symbol)\n            }\n        }\n\n        private fun parseResourceSymbol(symbol: VarSymbol) {\n            // eg com.airbnb.paris.R\n            val rClass = symbol.enclosingElement.enclosingElement.enclClass().className()\n            // eg styleable\n            val rTypeClass = symbol.enclosingElement.simpleName.toString()\n            // eg View_background\n            val resourceName = symbol.simpleName.toString()\n            val value = symbol.constantValue as? Int ?: return\n            val androidResourceId =\n                ResourceValue(getClassName(rClass, rTypeClass), resourceName, value)\n            results[androidResourceId.value] = androidResourceId\n        }\n\n        fun results(): Map<Int, ResourceValue> = results\n    }\n\n    private fun getClassName(rClass: String, rTypeClass: String): ClassName {\n        val rClassElement: Element? = try {\n            elementUtils.getTypeElement(rClass)\n        } catch (mte: MirroredTypeException) {\n            typeUtils.asElement(mte.typeMirror)\n        }\n        val rClassPackageName = elementUtils.getPackageOf(rClassElement).qualifiedName.toString()\n        return ClassName.get(rClassPackageName, \"R\", rTypeClass)\n    }\n\n    companion object {\n        private fun getMirror(\n            element: Element,\n            annotation: Class<out Annotation?>\n        ): AnnotationMirror? {\n            val targetName = annotation.canonicalName\n            return element.annotationMirrors.firstOrNull { it.annotationType.toString() == targetName }\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/resourcescanning/KspResourceScanner.kt",
    "content": "package com.airbnb.epoxy.processor.resourcescanning\n\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.airbnb.epoxy.processor.containingPackage\nimport com.airbnb.epoxy.processor.resourcescanning.KspResourceScanner.ImportMatch.Normal\nimport com.airbnb.epoxy.processor.resourcescanning.KspResourceScanner.ImportMatch.TypeAlias\nimport com.google.devtools.ksp.impl.symbol.java.KSAnnotationJavaImpl\nimport com.google.devtools.ksp.impl.symbol.kotlin.KSAnnotationImpl\nimport com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl\nimport com.google.devtools.ksp.impl.symbol.kotlin.KSFileImpl\nimport com.google.devtools.ksp.impl.symbol.kotlin.KSFileJavaImpl\nimport com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSAnnotationResolvedImpl\nimport com.google.devtools.ksp.symbol.KSAnnotation\nimport com.google.devtools.ksp.symbol.KSClassDeclaration\nimport com.squareup.javapoet.ClassName\nimport ksp.com.intellij.psi.PsiAnnotation\nimport ksp.com.intellij.psi.PsiJavaFile\nimport ksp.com.intellij.psi.PsiNameValuePair\nimport ksp.org.jetbrains.kotlin.analysis.api.annotations.KaAnnotation\nimport ksp.org.jetbrains.kotlin.name.FqName\nimport ksp.org.jetbrains.kotlin.name.Name\nimport ksp.org.jetbrains.kotlin.psi.KtAnnotationEntry\nimport ksp.org.jetbrains.kotlin.psi.KtCollectionLiteralExpression\nimport ksp.org.jetbrains.kotlin.psi.KtDotQualifiedExpression\nimport ksp.org.jetbrains.kotlin.psi.KtExpression\nimport ksp.org.jetbrains.kotlin.psi.KtFile\nimport ksp.org.jetbrains.kotlin.psi.KtSimpleNameExpression\nimport ksp.org.jetbrains.kotlin.psi.ValueArgument\nimport java.util.Locale.getDefault\nimport java.util.regex.PatternSyntaxException\nimport kotlin.reflect.KClass\n\nclass KspResourceScanner(environmentProvider: () -> XProcessingEnv) :\n    ResourceScanner(environmentProvider) {\n    private val cache =\n        mutableMapOf<Pair<KClass<out Annotation>, XElement>, List<AnnotationWithReferenceValue>>()\n\n    override fun clearCachesForNewRound() {\n        // Clear the cache to avoid holding references to stale XElement objects from previous rounds.\n        // In KSP2, accessing elements from previous rounds triggers \"PSI has changed since creation\" errors.\n        cache.clear()\n    }\n\n    override fun getResourceValueListInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        values: List<Int>,\n    ): List<ResourceValue> {\n        val annotationArgs = getAnnotationArgs(annotation, element)\n\n        return annotationArgs.filter { it.name == property }.mapNotNull { it.toResourceValue() }\n    }\n\n    override fun getResourceValueInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        value: Int\n    ): ResourceValue? {\n        val annotationArgs = getAnnotationArgs(annotation, element)\n\n        val matchingArg = annotationArgs.firstOrNull { it.name == property } ?: return null\n\n        return matchingArg.toResourceValue()\n    }\n\n    private fun getAnnotationArgs(\n        annotation: KClass<out Annotation>,\n        element: XElement\n    ): List<AnnotationWithReferenceValue> {\n        return cache.getOrPut(annotation to element) {\n            val xAnnotation = element.getAnnotation(annotation) ?: return@getOrPut emptyList()\n            val ksAnnotation = xAnnotation.getFieldWithReflection<KSAnnotation>(\"ksAnnotated\")\n            processAnnotationWithResource(ksAnnotation)\n        }\n    }\n\n    override fun getImports(classElement: XTypeElement): List<String> {\n        val ksClassDeclaration =\n            classElement.getFieldWithReflection<KSClassDeclaration>(\"declaration\")\n        return when (ksClassDeclaration) {\n            is KSClassDeclarationImpl -> {\n                when (val fileImpl = ksClassDeclaration.containingFile) {\n                    is KSFileImpl -> {\n                        fileImpl.getFieldWithReflection<KtFile>(\"psi\")\n                            .importDirectives\n                            .mapNotNull { it.importPath?.toString() }\n                    }\n                    is KSFileJavaImpl -> {\n                        fileImpl.psi\n                            .importList\n                            ?.importStatements\n                            ?.mapNotNull { it.qualifiedName }\n                            ?: emptyList()\n                    }\n                    else -> emptyList()\n                }\n            }\n            else -> emptyList()\n        }\n    }\n\n    private fun processAnnotationWithResource(annotation: KSAnnotation): List<AnnotationWithReferenceValue> {\n        val packageName = annotation.containingPackage.orEmpty()\n        return when (annotation) {\n            is KSAnnotationImpl -> processKtAnnotation(\n                annotation.getFieldWithReflection(\"ktAnnotationEntry\"),\n                annotation,\n                packageName\n            )\n            is KSAnnotationJavaImpl -> processJavaAnnotation(\n                annotation.getFieldWithReflection(\"psi\"),\n                annotation,\n                packageName\n            )\n            is KSAnnotationResolvedImpl -> processKtAnnotation(\n                annotation.getFieldWithReflection<KaAnnotation>(\"annotationApplication\").psi as? KtAnnotationEntry\n                    ?: return emptyList(),\n                annotation,\n                packageName\n            )\n            else -> {\n                // One possible case is KSAnnotationDescriptorImpl, which happens when the annotation\n                // is in source files instead of classpath (I think), but we don't need to handle\n                // that since epoxy annotations are always on classpath.\n                error(\"Unknown annotation implementation type ${annotation.javaClass}\")\n            }\n        }\n    }\n\n    private fun processJavaAnnotation(\n        psi: PsiAnnotation,\n        annotation: KSAnnotationJavaImpl,\n        packageName: String\n    ): List<AnnotationWithReferenceValue> {\n        return psi.parameterList\n            .attributes\n            .zip(annotation.arguments)\n            .map { (psiNameValue, ksValueArgument) ->\n                AnnotationWithReferenceValue(\n                    name = ksValueArgument.name?.asString(),\n                    value = ksValueArgument.value,\n                    reference = extractJavaReferenceAnnotationArgument(\n                        psiNameValue,\n                        psi,\n                        packageName\n                    )\n                )\n            }\n    }\n\n    private fun extractJavaReferenceAnnotationArgument(\n        psiNameValue: PsiNameValuePair,\n        psi: PsiAnnotation,\n        packageName: String\n    ): String? {\n        // eg: R.layout.foo, com.example.R.layout.foo, layout.foo, etc\n        return psiNameValue.value?.text?.let { annotationReference ->\n            extractReferenceAnnotationArgument(annotationReference) { annotationReferencePrefix ->\n                findMatchingImportPackageJava(\n                    psi,\n                    annotationReference,\n                    annotationReferencePrefix,\n                    packageName\n                )\n            }\n        }\n    }\n\n    private fun extractReferenceAnnotationArgument(\n        // eg: R.layout.foo, com.example.R.layout.foo, layout.foo, etc\n        annotationReference: String,\n        /**\n         * Given the name referenced in source code, return the matching import for that name.\n         */\n        importLookup: (annotationReferencePrefix: String) -> ImportMatch,\n    ): String? {\n        // First part of dot reference, eg: \"R\"\n        // If no dots, then it could be fully statically imported, so we take the full string.\n        val annotationReferencePrefix =\n            annotationReference.substringBefore(\".\").ifEmpty { return null }\n\n        val importMatch = importLookup(annotationReferencePrefix)\n\n        return importMatch.fullyQualifiedReference\n    }\n\n    private fun processKtAnnotation(\n        annotationEntry: KtAnnotationEntry,\n        annotation: KSAnnotation,\n        packageName: String\n    ): List<AnnotationWithReferenceValue> {\n        return annotationEntry.valueArguments\n            .zip(annotation.arguments)\n            .flatMap { (valueArgument, ksValueArgument) ->\n\n                val references = extractKotlinResourceReferencesInAnnotationArgument(\n                    valueArgument,\n                    annotationEntry,\n                    packageName\n                )\n\n                if (references.isEmpty()) {\n                    // This property isn't used for resources, so return early.\n                    // It may still have non resource values, so don't continue to collect those.\n                    return@flatMap emptyList()\n                }\n\n                val values = (ksValueArgument.value as? Iterable<*>)?.toList() ?: listOf(\n                    ksValueArgument.value\n                )\n\n                val propertyName = ksValueArgument.name?.asString()\n                if (values.size != references.size) {\n                    error(\"Resource reference count does not match value count. Resources: $references values: $values annotation: ${annotation.shortName.asString()} property: $propertyName\")\n                }\n\n                values.zip(references).map { (value, resourceReference) ->\n                    AnnotationWithReferenceValue(\n                        name = propertyName,\n                        value = value,\n                        reference = resourceReference\n                    )\n                }\n            }\n    }\n\n    private fun extractKotlinResourceReferencesInAnnotationArgument(\n        valueArgument: ValueArgument,\n        annotationEntry: KtAnnotationEntry,\n        packageName: String\n    ): List<String> {\n        return valueArgument.getArgumentExpression()?.let { ex ->\n\n            val resourceNames = getResourceNamesFromAnnotationExpression(ex)\n\n            resourceNames.mapNotNull { resourceName ->\n\n                extractReferenceAnnotationArgument(resourceName) { annotationReferencePrefix ->\n                    findMatchingImportPackageKt(\n                        annotationEntry,\n                        resourceName,\n                        annotationReferencePrefix,\n                        packageName\n                    )\n                }\n            }\n        } ?: emptyList()\n    }\n\n    private fun getResourceNamesFromAnnotationExpression(expression: KtExpression): List<String> {\n        return if (expression is KtCollectionLiteralExpression) {\n            // annotation argument is a array of resources\n            expression.innerExpressions\n                .flatMap { getResourceNamesFromAnnotationExpression(expression) }\n        } else {\n\n            // eg: R.layout.foo, com.example.R.layout.foo, layout.foo, etc\n            val annotationReference = fqNameFromExpression(expression)?.asString()\n\n            listOfNotNull(annotationReference)\n        }\n    }\n\n    private fun findMatchingImportPackageJava(\n        annotationEntry: PsiAnnotation,\n        annotationReference: String,\n        annotationReferencePrefix: String,\n        packageName: String\n    ): ImportMatch {\n        // Note: Star imports are not included in this, and there doesn't seem to be a way to resolve them, so\n        // they are not included or supported.\n        val importedNames = (annotationEntry.containingFile as? PsiJavaFile)\n            ?.importList\n            ?.importStatements\n            ?.mapNotNull { it.qualifiedName }\n            ?: emptyList()\n\n        return findMatchingImportPackage(\n            importedNames,\n            annotationReference,\n            annotationReferencePrefix,\n            packageName\n        )\n    }\n\n    private fun findMatchingImportPackageKt(\n        annotationEntry: KtAnnotationEntry,\n        annotationReference: String,\n        annotationReferencePrefix: String,\n        packageName: String\n    ): ImportMatch {\n        val importedNames = annotationEntry\n            .containingKtFile\n            .importDirectives\n            .mapNotNull { it.importPath?.toString() }\n\n        return findMatchingImportPackage(\n            importedNames,\n            annotationReference,\n            annotationReferencePrefix,\n            packageName\n        )\n    }\n\n    sealed class ImportMatch {\n        abstract val fullyQualifiedReference: String\n\n        class TypeAlias(val import: String, alias: String, annotationReference: String) :\n            ImportMatch() {\n            // Example: Type alias \"com.airbnb.paris.test.R2 as typeAliasedR\"\n            // import - com.airbnb.paris.test.R2\n            // alias - typeAliasedR\n            // annotationReference - typeAliasedR.layout.my_layout\n            // actual fqn - com.airbnb.paris.test.R2.layout.my_layout\n            override val fullyQualifiedReference: String =\n                import.trim() + annotationReference.substringAfter(alias)\n        }\n\n        class Normal(val referenceImportPrefix: String, val annotationReference: String) :\n            ImportMatch() {\n            override val fullyQualifiedReference: String =\n                referenceImportPrefix + (if (referenceImportPrefix.isNotEmpty()) \".\" else \"\") + annotationReference\n        }\n    }\n\n    data class AnnotationWithReferenceValue(\n        val name: String?,\n        val value: Any?,\n        val reference: String?\n    ) {\n        fun toResourceValue(): ResourceValue? {\n            if (value !is Int || reference == null || reference.toIntOrNull() != null) return null\n\n            val resourceInfo = when {\n                \".R2.\" in reference || reference.startsWith(\"R2.\") -> {\n                    extractResourceInfo(reference, \"R2\")\n                }\n                \".R.\" in reference || reference.startsWith(\"R.\") -> {\n                    extractResourceInfo(reference, \"R\")\n                }\n                else -> {\n                    error(\"Unsupported resource reference $reference\")\n                }\n            }\n\n            return ResourceValue(\n                // Regardless of if the input is R or R2, we always need the generated code to reference R\n                ClassName.get(resourceInfo.packageName, \"R\", resourceInfo.rSubclassName),\n                resourceName = resourceInfo.resourceName,\n                value,\n            )\n        }\n\n        /**\n         * @param reference fully qualified resource reference. eg com.example.R.layout.my_view\n         * @param rClassSimpleName ie R or R2\n         */\n        private fun extractResourceInfo(\n            reference: String,\n            rClassSimpleName: String\n        ): ResourceReferenceInfo {\n            // get package before R and resource details after R\n            val packageAndResourceType = reference.split(\".$rClassSimpleName.\").also {\n                check(it.size == 2) { \"Unexpected annotation value reference pattern $reference\" }\n            }\n\n            val packageName = packageAndResourceType[0]\n\n            val (rSubclass, resourceName) = packageAndResourceType[1].split(\".\").also {\n                check(it.size == 2) { \"Unexpected annotation value reference pattern $reference\" }\n            }\n\n            return ResourceReferenceInfo(\n                packageName = packageName,\n                rSimpleName = rClassSimpleName,\n                rSubclassName = rSubclass,\n                resourceName = resourceName\n            )\n        }\n    }\n\n    private data class ResourceReferenceInfo(\n        val packageName: String,\n        val rSimpleName: String,\n        val rSubclassName: String,\n        val resourceName: String\n    )\n\n    // From https://github.com/JetBrains/kotlin/blob/92d200e093c693b3c06e53a39e0b0973b84c7ec5/compiler/psi/src/org/jetbrains/kotlin/psi/KtImportDirective.java\n    private fun fqNameFromExpression(expression: KtExpression): FqName? {\n        return when (expression) {\n            is KtDotQualifiedExpression -> {\n                val parentFqn: FqName? = fqNameFromExpression(expression.receiverExpression)\n                val child: Name = expression.selectorExpression?.let { nameFromExpression(it) }\n                    ?: return parentFqn\n                parentFqn?.child(child)\n            }\n            is KtSimpleNameExpression -> {\n                FqName.topLevel(expression.getReferencedNameAsName())\n            }\n            else -> {\n                null\n            }\n        }\n    }\n\n    private fun nameFromExpression(expression: KtExpression): Name? {\n        return if (expression is KtSimpleNameExpression) {\n            expression.getReferencedNameAsName()\n        } else {\n            null\n        }\n    }\n\n    companion object {\n        internal fun findMatchingImportPackage(\n            importedNames: List<String>,\n            annotationReference: String,\n            annotationReferencePrefix: String,\n            packageName: String\n        ): ImportMatch {\n            // Match something like \"com.airbnb.paris.test.R2 as typeAliasedR\"\n            val typeAliasRegex = try {\n                Regex(\"(.*)\\\\s+as\\\\s+$annotationReferencePrefix\\$\")\n            } catch (e: PatternSyntaxException) {\n                // Provide more information in this case so we can better debug https://github.com/airbnb/epoxy/issues/1265\n                throw IllegalStateException(\"Failed to create regex for resource reference '$annotationReferencePrefix'\", e)\n            }\n\n            return importedNames.firstNotNullOfOrNull { importedName ->\n\n                when {\n                    importedName.endsWith(\".$annotationReferencePrefix\") -> {\n                        // import com.example.R\n                        // R.layout.my_layout -> R\n                        Normal(\n                            referenceImportPrefix = importedName.substringBeforeLast(\".$annotationReferencePrefix\"),\n                            annotationReference = annotationReference\n                        )\n                    }\n                    importedName.contains(typeAliasRegex) -> {\n                        typeAliasRegex.find(importedName)?.groupValues?.getOrNull(1)\n                            ?.let { import ->\n                                TypeAlias(import, annotationReferencePrefix, annotationReference)\n                            }\n                    }\n                    (!importedName.contains(\".\") && importedName == annotationReferencePrefix) -> {\n                        // import foo\n                        // foo.R.layout.my_layout -> foo\n                        Normal(\"\", annotationReference)\n                    }\n                    else -> null\n                }\n            } ?: run {\n                // If first character in the reference is upper case, and we didn't find a matching import,\n                // assume that it is a class reference in the same package (ie R class is in the same package, so we use the same package name)\n                if (annotationReferencePrefix.firstOrNull()?.isUpperCase() == true) {\n                    Normal(packageName, annotationReference)\n                } else {\n                    // Reference is already fully qualified so we don't need to prepend package info to the reference\n                    Normal(\"\", annotationReference)\n                }\n            }\n        }\n    }\n}\n\n/**\n * Easy way to retrieve the value of a field via reflection.\n *\n * @param fieldName Name of the field on this class\n * @param U The type of the field..\n */\ninline fun <reified U> Any.getFieldWithReflection(fieldName: String): U {\n    val value = try {\n        val field = this.javaClass.getDeclaredField(fieldName)\n        field.isAccessible = true\n        field.get(this)\n    } catch (_: NoSuchFieldException) {\n        // Kotlin sometimes does not have a field backing a property, so we try a getter method\n        // for it.\n        val methodName = \"get\" + fieldName.replaceFirstChar {\n            if (it.isLowerCase()) it.titlecase(getDefault()) else it.toString()\n        }\n        val method = try {\n            this.javaClass.getMethod(methodName)\n        } catch (_: NoSuchMethodException) {\n            this.javaClass.getDeclaredMethod(methodName)\n        }\n        method.isAccessible = true\n        method.invoke(this)\n    }\n\n    check(value is U) {\n        \"Expected field '$fieldName' to be ${U::class.java.simpleName} but got a ${value.javaClass.simpleName}\"\n    }\n    @Suppress(\"NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS\")\n    return value\n}\n\ninline fun <reified U> Any.getFieldWithReflectionOrNull(fieldName: String): U? {\n    return kotlin.runCatching<U> {\n        getFieldWithReflection(fieldName)\n    }.getOrNull()\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/resourcescanning/ResourceScanner.kt",
    "content": "package com.airbnb.epoxy.processor.resourcescanning\n\nimport androidx.room.compiler.processing.XAnnotation\nimport androidx.room.compiler.processing.XElement\nimport androidx.room.compiler.processing.XProcessingEnv\nimport androidx.room.compiler.processing.XTypeElement\nimport com.squareup.javapoet.ClassName\nimport kotlin.reflect.KClass\n\nabstract class ResourceScanner(val environmentProvider: () -> XProcessingEnv) {\n    val rClassNames: List<ClassName>\n        get() = mutableRClasses.toList()\n\n    private val mutableRClasses = mutableSetOf<ClassName>()\n\n    /**\n     * Returns the [ResourceValue] that is used as an annotation value of the given [XElement]\n     */\n    fun getResourceValue(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n    ): ResourceValue? {\n        // The annotation box class doesn't allow us to query properties by name, so we get an\n        // XAnnotation which has that information.\n        val xAnnotation = element.getXAnnotation(annotation) ?: return null\n\n        val value = (\n            xAnnotation.annotationValues\n                .firstOrNull { it.name == property }\n                ?.value as? Int\n            )\n            ?: return null\n\n        return getResourceValue(annotation, element, property, value)\n    }\n\n    private fun XElement.getXAnnotation(\n        annotation: KClass<out Annotation>\n    ): XAnnotation? {\n        return getAllAnnotations().firstOrNull {\n            // optimization to not resolve full annotation for fqn unless the simple name matches\n            it.name == annotation.simpleName && it.qualifiedName == annotation.qualifiedName\n        }\n    }\n\n    /**\n     * Returns the [ResourceValue] that is used as an annotation value of the given [XElement]\n     */\n    fun getResourceValue(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        value: Int\n    ): ResourceValue {\n        return getResourceValueInternal(annotation, element, property, value).also { resourceValue ->\n            resourceValue?.className?.let { mutableRClasses.add(it) }\n        } ?: ResourceValue(value)\n    }\n\n    /**\n     * Returns the list of [ResourceValue] that is used as an annotation value of the given [XElement]\n     */\n    fun getResourceValueList(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n    ): List<ResourceValue>? {\n        val xAnnotation = element.getXAnnotation(annotation) ?: return null\n\n        val values = (\n            xAnnotation.annotationValues\n                .firstOrNull { it.name == property }\n                ?.asIntList()\n            )\n            ?: return null\n\n        return getResourceValueListInternal(annotation, element, property, values).also { list ->\n            list.forEach { resourceValue ->\n                resourceValue.rClass?.let { mutableRClasses.add(it) }\n            }\n        }\n    }\n\n    protected abstract fun getResourceValueListInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        values: List<Int>,\n    ): List<ResourceValue>\n\n    protected abstract fun getResourceValueInternal(\n        annotation: KClass<out Annotation>,\n        element: XElement,\n        property: String,\n        value: Int\n    ): ResourceValue?\n\n    /**\n     * Returns a list of layout resources whose name contains the given layout as a prefix.\n     */\n    fun getAlternateLayouts(layout: ResourceValue): List<ResourceValue> {\n        val layoutClassName = layout.className ?: return emptyList()\n\n        val rLayoutClassElement: XTypeElement =\n            environmentProvider().requireTypeElement(layoutClassName.toString())\n        val target = layout.resourceName + \"_\"\n\n        return rLayoutClassElement\n            .getDeclaredFields()\n            .map { it.name }\n            .filter {\n                it.startsWith(target)\n            }\n            .map {\n                ResourceValue(\n                    layout.className,\n                    it,\n                    value = 0 // Don't care about this for our use case\n                )\n            }\n    }\n\n    abstract fun getImports(classElement: XTypeElement): List<String>\n\n    /**\n     * Clears any caches that may hold references to KSP elements.\n     * This must be called at the start of each round to avoid accessing stale PSI elements\n     * in KSP2, which would trigger \"PSI has changed since creation\" errors.\n     */\n    open fun clearCachesForNewRound() {\n        // Default implementation does nothing. KspResourceScanner overrides this to clear its cache.\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/java/com/airbnb/epoxy/processor/resourcescanning/ResourceValue.kt",
    "content": "package com.airbnb.epoxy.processor.resourcescanning\n\nimport com.airbnb.epoxy.processor.ClassNames.ANDROID_R\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\n\n/**\n * Represents a resource used as an annotation parameter.\n *\n *\n * Inspired by Butterknife. https://github.com/JakeWharton/butterknife/pull/613\n */\nclass ResourceValue {\n\n    val className: ClassName?\n    val resourceName: String?\n    val value: Int\n    val code: CodeBlock\n    val qualified: Boolean\n    val resourceType: String? get() = className?.simpleName()\n    val rClass: ClassName? get() = className?.topLevelClassName()\n\n    constructor(value: Int) {\n        this.value = value\n        code = CodeBlock.of(\"\\$L\", value)\n        qualified = false\n        resourceName = null\n        className = null\n    }\n\n    /**\n     * @param className eg com.airbnb.epoxy.R.layout\n     */\n    constructor(\n        className: ClassName,\n        resourceName: String,\n        value: Int\n    ) {\n        this.className = className\n        this.resourceName = resourceName\n        this.value = value\n        code = if (className.topLevelClassName() == ANDROID_R)\n            CodeBlock.of(\"\\$L.\\$N\", className, resourceName)\n        else\n            CodeBlock.of(\"\\$T.\\$N\", className, resourceName)\n        qualified = true\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other?.javaClass != javaClass) return false\n\n        other as ResourceValue\n\n        if (value != other.value) return false\n        if (code != other.code) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = value\n        result = 31 * result + code.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        throw UnsupportedOperationException(\"Please use value or code explicitly\")\n    }\n\n    fun debugDetails(): String = code.toString()\n\n    fun isStringResource(): Boolean = resourceType == \"string\"\n}\n"
  },
  {
    "path": "epoxy-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider",
    "content": "com.airbnb.epoxy.processor.EpoxyProcessorProvider\ncom.airbnb.epoxy.processor.ControllerProcessorProvider\ncom.airbnb.epoxy.processor.DataBindingProcessorProvider\ncom.airbnb.epoxy.processor.ModelViewProcessorProvider"
  },
  {
    "path": "epoxy-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor",
    "content": "com.airbnb.epoxy.processor.EpoxyProcessor\ncom.airbnb.epoxy.processor.ControllerProcessor\ncom.airbnb.epoxy.processor.DataBindingProcessor\ncom.airbnb.epoxy.processor.ModelViewProcessor"
  },
  {
    "path": "epoxy-processor/src/test/java/com/airbnb/epoxy/KspResourceScannerTest.kt",
    "content": "package com.airbnb.epoxy\n\nimport androidx.room.compiler.processing.compat.XConverters.toJavac\nimport androidx.room.compiler.processing.util.XTestInvocation\nimport com.airbnb.epoxy.processor.resourcescanning.JavacResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.KspResourceScanner\nimport com.airbnb.epoxy.processor.resourcescanning.ResourceScanner\nimport org.junit.Test\nimport strikt.api.expectThat\nimport strikt.assertions.isEqualTo\n\nclass KspResourceScannerTest {\n    @Test\n    fun findMatchingImportPackage_TypeAlias() {\n        val import = KspResourceScanner.findMatchingImportPackage(\n            importedNames = listOf(\"com.airbnb.paris.test.R2 as typeAliasedR\"),\n            annotationReference = \"typeAliasedR.layout.my_layout\",\n            annotationReferencePrefix = \"typeAliasedR\",\n            packageName = \"com.airbnb.paris\"\n        )\n\n        expectThat(import.fullyQualifiedReference).isEqualTo(\"com.airbnb.paris.test.R2.layout.my_layout\")\n    }\n\n    @Test\n    fun findMatchingImportPackage_TypeAliasDoesNotMatch() {\n        val import = KspResourceScanner.findMatchingImportPackage(\n            importedNames = listOf(\"com.airbnb.paris.test.R2 as typeAliasedR2\"),\n            annotationReference = \"typeAliasedR.layout.my_layout\",\n            annotationReferencePrefix = \"typeAliasedR\",\n            packageName = \"com.airbnb.paris\"\n        )\n\n        // falls back to annotation reference, since import should not match\n        expectThat(import.fullyQualifiedReference).isEqualTo(\"typeAliasedR.layout.my_layout\")\n    }\n\n    @Test\n    fun findMatchingImportPackage_fullyStaticImport() {\n        val import = KspResourceScanner.findMatchingImportPackage(\n            importedNames = listOf(\"com.airbnb.n2.comp.designsystem.hostdls.R2.styleable.n2_CarouselCheckedActionCard_n2_layoutStyle\"),\n            annotationReference = \"n2_CarouselCheckedActionCard_n2_layoutStyle\",\n            annotationReferencePrefix = \"n2_CarouselCheckedActionCard_n2_layoutStyle\",\n            packageName = \"com.airbnb.n2.comp.designsystem.hostdls\"\n        )\n\n        // falls back to annotation reference, since import should not match\n        expectThat(import.fullyQualifiedReference).isEqualTo(\"com.airbnb.n2.comp.designsystem.hostdls.R2.styleable.n2_CarouselCheckedActionCard_n2_layoutStyle\")\n    }\n\n//    @Test\n//    fun extractResourceValueListFromKotlinSource() {\n//        runProcessorTest() { invocation ->\n//            val type = invocation.processingEnv.requireTypeElement(\"com.airbnb.epoxy.MyTestKotlinObjectWithResourceArray\")\n//\n//            val scanner = createResourceScanner(invocation)\n//\n//            val resourceValues =\n//                scanner.getResourceValueList(EpoxyDataBindingLayouts::class, type, \"value\")\n//\n//            // TODO\n//            println(resourceValues)\n//        }\n//    }\n//\n//    // TODO: Java source version\n//\n//    @Test\n//    fun extractResourceValueFromKotlinSource() {\n//        runProcessorTest() { invocation ->\n//            val type = invocation.processingEnv.requireTypeElement(\"com.airbnb.epoxy.MyTestKotlinObjectWithSingleResource\")\n//\n//            val scanner = createResourceScanner(invocation)\n//\n//            val resourceValue =\n//                scanner.getResourceValue(EpoxyModelClass::class, type, \"layout\")\n//\n//            println(resourceValue?.code)\n//        }\n//    }\n\n    private fun createResourceScanner(invocation: XTestInvocation): ResourceScanner {\n        val scanner = if (invocation.isKsp) {\n            KspResourceScanner({ invocation.processingEnv })\n        } else {\n            JavacResourceScanner(\n                invocation.processingEnv.toJavac(),\n                { invocation.processingEnv }\n            )\n        }\n        return scanner\n    }\n}\n\n@EpoxyDataBindingLayouts(value = [R.Layout.mylayout, R.Layout.mylayout2])\nprivate object MyTestKotlinObjectWithResourceArray\n\n@EpoxyModelClass(layout = R.Layout.mylayout)\nprivate object MyTestKotlinObjectWithSingleResource\n\nobject R {\n    object Layout {\n        const val mylayout = 1\n        const val mylayout2 = 3\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/test/java/com/airbnb/epoxy/PoetExtensionsTest.kt",
    "content": "package com.airbnb.epoxy.processor\n\nimport androidx.annotation.FloatRange\nimport androidx.annotation.NonNull\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.squareup.kotlinpoet.asTypeName\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertFalse\nimport org.junit.Assert.assertNotNull\nimport org.junit.Assert.assertNull\nimport org.junit.Assert.assertTrue\nimport org.junit.Test\n\nclass PoetExtensionsTest {\n\n    @Test\n    fun testAnnotationSpecToKPoet() {\n        val annotation = EpoxyModelClass::class.java\n        val type = annotation.asTypeName()\n        val javaAnnotation = JavaAnnotationSpec.builder(annotation).build()\n\n        val kotlinAnnotation = javaAnnotation.toKPoet()\n        assertNotNull(kotlinAnnotation)\n        assertEquals(type, kotlinAnnotation?.className)\n    }\n\n    @Test\n    fun testAnnotationSpecToKPoetWithParams() {\n        val annotation = FloatRange::class.java\n        val javaAnnotation = JavaAnnotationSpec.builder(annotation)\n            .addMember(\"from\", \"0.0\")\n            .addMember(\"to\", \"1.0\")\n            .build()\n\n        val kotlinAnnotation = javaAnnotation.toKPoet()\n        assertNull(kotlinAnnotation)\n    }\n\n    @Test\n    fun testIsLambdaWithString() {\n        val stringType = JavaClassName.bestGuess(\"java.lang.String\")\n        assertFalse(isLambda(stringType))\n    }\n\n    @Test\n    fun testIsLambdaWithLambda() {\n        val lambdaType = JavaClassName.bestGuess(\"kotlin.Function2\")\n        assertTrue(isLambda(lambdaType))\n    }\n\n    @Test\n    fun testJavaParameterSpecToKPoet() {\n        val name = \"android\"\n        val javaParameter = JavaParameterSpec.builder(\n            JavaClassName.bestGuess(\"java.lang.String\"), name\n        )\n            .addAnnotation(NonNull::class.java)\n            .build()\n        val kotlinString = KotlinClassName(\"kotlin\", \"String\")\n\n        val kotlinParameter = javaParameter.toKPoet()\n        assertEquals(name, kotlinParameter.name)\n        assertEquals(kotlinString, kotlinParameter.type)\n        assertEquals(javaParameter.annotations.size, kotlinParameter.annotations.size)\n        assertEquals(NonNull::class.java.asTypeName(), kotlinParameter.annotations[0].className)\n    }\n\n    @Test\n    fun testJavaTypeNameToKPoet() {\n        val javaType = JavaParametrizedTypeName.get(\n            JavaClassName.bestGuess(\"java.util.List\"),\n            JavaClassName.bestGuess(\"java.lang.String\")\n        )\n\n        val kotlinType = javaType.toKPoet()\n        val kotlinList = KotlinClassName(\"kotlin.collections\", \"List\")\n        val kotlinString = KotlinClassName(\"kotlin\", \"String\")\n        assertEquals(kotlinList, kotlinType.rawType)\n        assertEquals(kotlinString, kotlinType.typeArguments[0])\n    }\n\n    @Test\n    fun testJavaArrayTypeNameToKPoet() {\n        val javaIntArray = JavaArrayTypeName.of(JavaClassName.INT)\n        val kotlinIntArray = javaIntArray.toKPoet()\n\n        assertEquals(\"kotlin.IntArray\", kotlinIntArray.toString())\n\n        val javaFloatArray = JavaArrayTypeName.of(\n            JavaClassName.bestGuess(\"java.lang.Float\")\n        )\n        val kotlinFloatArray = javaFloatArray.toKPoet()\n\n        assertEquals(\"kotlin.Array<kotlin.Float>\", kotlinFloatArray.toString())\n    }\n\n    @Test\n    fun testJavaClassNameToKPoet() {\n        val javaClassName = JavaClassName.bestGuess(\"java.lang.Integer\")\n        val kotlinClassName = javaClassName.toKPoet()\n\n        val javaByteName = JavaClassName.BYTE\n        val kotlinByteName = javaByteName.toKPoet()\n\n        assertEquals(\"kotlin.Int\", kotlinClassName.toString())\n        assertEquals(\"kotlin.Byte\", kotlinByteName.toString())\n    }\n}\n"
  },
  {
    "path": "epoxy-processor/src/test/java/com/airbnb/epoxy/UtilsTests.kt",
    "content": "package com.airbnb.epoxy\n\nimport androidx.room.compiler.processing.util.Source\nimport androidx.room.compiler.processing.util.XTestInvocation\nimport androidx.room.compiler.processing.util.runProcessorTest\nimport com.airbnb.epoxy.processor.Logger\nimport com.airbnb.epoxy.processor.Memoizer\nimport com.airbnb.epoxy.processor.Utils.isMap\nimport com.airbnb.epoxy.processor.typeNameWithWorkaround\nimport org.junit.Test\nimport strikt.api.expectThat\nimport strikt.assertions.isEqualTo\nimport strikt.assertions.isTrue\nimport java.io.Serializable\n\nclass UtilsTests {\n\n    @Test\n    fun detectNestedClass() {\n        val libSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class KotlinClass {\n                inner class MyInnerClass\n                class MyNestedClass\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(libSource)) { invocation ->\n            val innerType = invocation.processingEnv.requireTypeElement(\"KotlinClass.MyInnerClass\")\n            val nestedType =\n                invocation.processingEnv.requireTypeElement(\"KotlinClass.MyNestedClass\")\n\n            expectThat(!innerType.isStatic())\n            expectThat(nestedType.isStatic())\n        }\n    }\n\n    @Test\n    fun typeEnumCreation() {\n        val libSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class KotlinClass {\n                inner class MyInnerClass\n                class MyNestedClass\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(libSource)) { invocation ->\n            val innerType = invocation.processingEnv.requireTypeElement(\"KotlinClass.MyInnerClass\")\n            val nestedType =\n                invocation.processingEnv.requireTypeElement(\"KotlinClass.MyNestedClass\")\n\n            expectThat(!innerType.isStatic())\n            expectThat(nestedType.isStatic())\n        }\n    }\n\n    @Test\n    fun testListVariance() {\n        val libSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class KotlinClass {\n                fun foo(list: List<CharSequence>) {}\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(libSource)) { invocation ->\n            val clazz = invocation.processingEnv.requireTypeElement(\"KotlinClass\")\n            val param = clazz.getDeclaredMethods().single().parameters.single()\n\n            // Bug in KSP leads to invariance when it should be covariant?\n            val memoizer = invocation.createMemoizer()\n            if (invocation.isKsp) {\n                expectThat(param.type.typeNameWithWorkaround(memoizer).toString())\n                    .isEqualTo(\"java.util.List<? extends java.lang.CharSequence>\")\n            } else {\n                expectThat(param.type.typeNameWithWorkaround(memoizer).toString())\n                    .isEqualTo(\"java.util.List<? extends java.lang.CharSequence>\")\n            }\n        }\n    }\n\n    @Test\n    fun typeNameWorkaround() {\n        val kotlinSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class KotlinClass<out A, in B, C, D :  CharSequence, out E : List<*>, in F : List<*>> {\n                fun <T> foo(\n                    list: List<CharSequence>,\n                    func3: (Integer, List<CharSequence>, String) -> Unit,\n                    stringList: List<String>,\n                    funcUnit: (Unit) -> Integer,\n                    funcAny: (Any?) -> Integer,\n                    keyedListener: com.airbnb.epoxy.KeyedListener<*, Map<*, *>>,\n                    dataList: List<com.airbnb.epoxy.MyData>,\n                    kotlinClass: KotlinClass<*, *, C, D, *, *>,\n                    linkedHashSet: LinkedHashSet<com.airbnb.epoxy.DataPoint<Pair<Any, String>, Double>>,\n                    set: Set<com.airbnb.epoxy.DataPoint<Pair<Any, String>, Double>>,\n                    b: B,\n                    bList: List<B>,\n                    c: C,\n                    d: D,\n                    dList: List<D>,\n                    f: F,\n                    fList: List<F>,\n                    t: T,\n                    listT: List<T>,\n                ){}\n            }\n            \"\"\".trimIndent()\n        )\n        val javaSource = Source.java(\n            \"foo.JavaClass\",\n            \"\"\"\n            package foo;\n            import java.util.List;\n            import java.util.Map;\n            import java.lang.Integer;\n            \n            class JavaClass<T extends List<?>> {\n                <T> void foo(\n                    List<CharSequence> j1,\n                    List<? extends CharSequence> j2,\n                    List<String> j3,\n                    com.airbnb.epoxy.KeyedListener<?, ? extends Map<Integer, ?>> j4,\n                    List<com.airbnb.epoxy.MyData> j5,\n                    T j6\n                ){}\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(kotlinSource, javaSource)) { invocation ->\n\n            val kotlinClass = invocation.processingEnv.requireTypeElement(\"KotlinClass\")\n            val javaClass = invocation.processingEnv.requireTypeElement(\"foo.JavaClass\")\n\n            val javaParams = javaClass.getDeclaredMethods().single().parameters\n            val kotlinParams = kotlinClass.getDeclaredMethods().single().parameters\n\n            val memoizer = invocation.createMemoizer()\n            val params = javaParams.plus(kotlinParams).associate {\n                it.name to lazy { it.type.typeNameWithWorkaround(memoizer).toString() }\n            }\n\n            infix fun String.named(expectedName: String) {\n                expectThat(this) {\n                    assert(\"in ${if (invocation.isKsp) \"ksp\" else \"javac\"} expected $expectedName\") {\n                        when (val value = params[this@named]?.value) {\n                            null -> fail(\"but got null\")\n                            expectedName -> {\n                                pass()\n                            }\n                            else -> {\n                                fail(\"but got $value\")\n                            }\n                        }\n                    }\n                }\n            }\n\n            // TODO: KSP sees \"java.util.Set<com.airbnb.epoxy.DataPoint<kotlin.Pair<?, java.lang.String>, java.lang.Double>>\" which seems like it might be correct, but is still different from javac\n//            \"set\" named \"java.util.Set<com.airbnb.epoxy.DataPoint<kotlin.Pair<java.lang.Object, java.lang.String>, java.lang.Double>>\"\n\n            // TODO: KSP sees only LinkedHashSet<E>\n//            \"linkedHashSet\" named \"java.util.LinkedHashSet<com.airbnb.epoxy.DataPoint<kotlin.Pair<java.lang.Object, java.lang.String>, java.lang.Double>>\"\n\n            \"j1\" named \"java.util.List<java.lang.CharSequence>\"\n            \"j2\" named \"java.util.List<? extends java.lang.CharSequence>\"\n            \"j3\" named \"java.util.List<java.lang.String>\"\n            \"j4\" named \"com.airbnb.epoxy.KeyedListener<?, ? extends java.util.Map<java.lang.Integer, ?>>\"\n            \"j5\" named \"java.util.List<com.airbnb.epoxy.MyData>\"\n            \"j6\" named \"T\"\n            \"list\" named \"java.util.List<? extends java.lang.CharSequence>\"\n            \"func3\" named \"kotlin.jvm.functions.Function3<? super java.lang.Integer, ? super java.util.List<? extends java.lang.CharSequence>, ? super java.lang.String, kotlin.Unit>\"\n            \"stringList\" named \"java.util.List<java.lang.String>\"\n            \"funcUnit\" named \"kotlin.jvm.functions.Function1<? super kotlin.Unit, java.lang.Integer>\"\n            \"funcAny\" named \"kotlin.jvm.functions.Function1<java.lang.Object, java.lang.Integer>\"\n            \"keyedListener\" named \"com.airbnb.epoxy.KeyedListener<?, java.util.Map<?, ?>>\"\n            \"dataList\" named \"java.util.List<com.airbnb.epoxy.MyData>\"\n            // TODO: STAR wildcard case in KSP is not differentiable from type param name\n//            \"kotlinClass\" named \"KotlinClass<?, ?, C, D, ?, ?>\"\n            // TODO: ksp expected B : but got java.lang.Object\n//            \"b\" named \"B\"\n//            \"bList\" named \"java.util.List<? extends B>\"\n//            \"c\" named \"C\"\n//            \"d\" named \"D\"\n//            \"dList\" named \"java.util.List<? extends D>\"\n//            \"f\" named \"F\"\n//            \"fList\" named \"java.util.List<? extends F>\"\n//            \"t\" named \"T\"\n//            \"listT\" named \"java.util.List<? extends T>\"\n        }\n    }\n\n    @Test\n    fun testWildcardInPoetName() {\n        val libSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class MyClass {\n                fun setList(list: List<*>) {}\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(libSource)) { invocation ->\n            val clazz = invocation.processingEnv.requireTypeElement(\"MyClass\")\n            val param = clazz.getDeclaredMethods().single().parameters.single()\n\n            val memoizer = invocation.createMemoizer()\n            expectThat(\n                param.type.typeNameWithWorkaround(memoizer).toString()\n            ).isEqualTo(\"java.util.List<?>\")\n            println(\n                \"${if (invocation.isKsp) \"ksp\" else \"javac\"} : \" + param.type.typeNameWithWorkaround(\n                    memoizer\n                )\n            )\n            // Prints:\n            // javac : java.util.List<?>\n            // ksp : java.util.List<E>\n        }\n    }\n\n    @Test\n    fun checkMapType() {\n        val libSource = Source.kotlin(\n            \"lib.kt\",\n            \"\"\"\n            class MyClass {\n                val map: Map<Int, Int> = emptyMap()\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(libSource)) { invocation ->\n            val clazz = invocation.processingEnv.requireTypeElement(\"MyClass\")\n\n            val field = clazz.getDeclaredFields().single()\n            expectThat(field.type.isMap(invocation.processingEnv)).isTrue()\n        }\n\n        val javaSource = Source.java(\n            \"foo.MyClass\",\n            \"\"\"\n            package foo;\n            import java.util.Map;\n            \n            class MyClass {\n                Map<Integer, Integer> map;\n            }\n            \"\"\".trimIndent()\n        )\n        runProcessorTest(listOf(javaSource)) { invocation ->\n            val clazz = invocation.processingEnv.requireTypeElement(\"foo.MyClass\")\n\n            val field = clazz.getDeclaredFields().single()\n            expectThat(field.type.isMap(invocation.processingEnv)).isTrue()\n        }\n    }\n}\n\nclass Foo<out A, in B, C, D : CharSequence, out E : List<*>, in F : List<*>> {\n    fun foo(dataSet: LinkedHashSet<DataPoint<Pair<Any, String>, Double>>) {\n        bar(dataSet)\n    }\n\n    fun bar(data: Set<DataPoint<Pair<Any, String>, Double>>) {\n    }\n}\n\nfun XTestInvocation.createMemoizer() =\n    Memoizer(processingEnv, Logger(processingEnv.messager, false))\n\ndata class KeyedListener<Key, Listener>(val identifier: Key, val listener: Listener)\n\ndata class MyData(val int: Int)\n\ndata class DataPoint<X : Serializable, Y>(\n    val x: X,\n    val y: Y?\n) where Y : Number, Y : Comparable<Y>\n"
  },
  {
    "path": "epoxy-processortest/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-processortest/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.processortest'\n\n  defaultConfig {\n    minSdkVersion rootProject.PARIS_MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n  }\n\n  testOptions {\n    unitTests {\n      includeAndroidResources = true\n      all {\n        jvmArgs(\n            '--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',\n            '--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'\n        )\n      }\n    }\n  }\n\n  dataBinding {\n    enabled = true\n  }\n}\n\nkotlin {\n  jvmToolchain(17)\n}\n\ndependencies {\n  implementation rootProject.deps.androidRecyclerView\n  implementation project(':epoxy-annotations')\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-databinding')\n  implementation project(':epoxy-processortest2')\n  // The processor uses coroutines, and for some reason we need to include it here too for the\n  // compiler tester to be able to instantiate the processor, otherwise the coroutine classes\n  // aren't found.\n  implementation rootProject.deps.kotlinCoroutines\n\n  kapt project(':epoxy-processor')\n  // Need to include the processor directly as well since we create an instance of it in code for testing\n  implementation project(':epoxy-processor')\n  implementation rootProject.deps.ksp\n\n  implementation rootProject.deps.paris\n  kapt rootProject.deps.parisProcessor\n  // Need to include the processor directly since we create an instance of it in code for testing\n  testImplementation rootProject.deps.parisProcessor\n\n  kapt rootProject.deps.autoValue\n\n  testImplementation files(rootProject.file(\"libs/rt.jar\"))\n  testImplementation files(rootProject.file(\"libs/tools.jar\"))\n  testImplementation rootProject.deps.googleTestingCompile\n  // (javax.annotation.Nullable) needed for test compilation\n  testImplementation \"com.google.code.findbugs:jsr305:3.0.2\"\n  testImplementation \"io.github.java-diff-utils:java-diff-utils:4.12\"\n  testImplementation \"io.strikt:strikt-core:0.34.1\"\n  testImplementation rootProject.deps.kotlinCompileTesting\n  // This is included in kotlinCompileTesting, but the version can be out of date with our kotlin\n  // compiler version, so we include it to force the right version\n  testImplementation rootProject.deps.kotlinAnnotationProcessingEmbeddable\n}\n\n// Java files in the \"resources\" folder are not included in the build for some reason (seems like source files are skipped?)\n// This files are needed to test the annotation processor, so we manually copy them into the build.\ntask('copyDebugTestResources', type: Copy) {\n  from(\"${projectDir}/src/test/resources\")\n  into(\"${buildDir}/intermediates/sourceFolderJavaResources/debug\")\n}\n\ntask('copyReleaseTestResources', type: Copy) {\n  from(\"${projectDir}/src/test/resources\")\n  into(\"${buildDir}/intermediates/sourceFolderJavaResources/release\")\n}\n\npreBuild.dependsOn copyReleaseTestResources\npreBuild.dependsOn copyDebugTestResources\n"
  },
  {
    "path": "epoxy-processortest/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-processortest/src/main/java/com/airbnb/integrationtest/processortest/ProcessorTestModel.java",
    "content": "package com.airbnb.integrationtest.processortest;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model;\n\npublic class ProcessorTestModel extends ProcessorTest2Model<View> {\n  @EpoxyAttribute public int publicValue;\n  @EpoxyAttribute protected int protectedValue;\n  @EpoxyAttribute int packagePrivateValue;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/main/java/com/airbnb/integrationtest/processortest/differentpackage/Model.java",
    "content": "package com.airbnb.integrationtest.processortest.differentpackage;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.integrationtest.processortest.ProcessorTestModel;\n\npublic class Model extends ProcessorTestModel {\n  @EpoxyAttribute int subclassValue;\n}\n"
  },
  {
    "path": "epoxy-processortest/src/main/res/layout/model_with_data_binding_without_donothash.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data>\n\n        <variable\n            name=\"stringValue\"\n            type=\"String\" />\n\n        <variable\n            name=\"clickListener\"\n            type=\"android.view.View.OnClickListener\" />\n    </data>\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:onClick=\"@{clickListener}\"\n        android:text=\"@{stringValue}\" />\n\n</layout>"
  },
  {
    "path": "epoxy-processortest/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Processor Test</string>\n</resources>\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/ConfigTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGenerationError\nimport com.airbnb.epoxy.ProcessorTestUtils.options\nimport com.airbnb.epoxy.ProcessorTestUtils.processors\nimport com.google.testing.compile.JavaFileObjects\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\n\nclass ConfigTest {\n\n    @Test\n    fun testSubPackageOverridesParent() {\n        val subPackageConfig = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.configtest.sub.EpoxyNestedConfig\",\n            \"\"\"package com.airbnb.epoxy.configtest.sub;\n                    import com.airbnb.epoxy.PackageEpoxyConfig;\n                    @PackageEpoxyConfig(\n                        requireHashCode = false\n                    )\n                    interface EpoxyNestedConfig {}\n                    \"\"\"\n        )\n        val model =\n            JavaFileObjects.forResource(\"ModelConfigSubPackageOverridesParent.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model, subPackageConfig),\n            generatedFileObjects = emptyList(),\n        )\n    }\n\n    @Test\n    fun testPackageWithNoConfigInheritsNearestParentConfig() {\n        val topLevelParentConfig = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.configtest.EpoxyConfig1\",\n            \"\"\"package com.airbnb.epoxy.configtest;\n                        import com.airbnb.epoxy.PackageEpoxyConfig;\n                        @PackageEpoxyConfig(\n                            requireHashCode = false\n                        )\n                        interface EpoxyConfig1 {}\n                        \"\"\"\n        )\n        val secondLevelParentConfig = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.configtest.sub.EpoxyConfig2\",\n            \"\"\"package com.airbnb.epoxy.configtest.sub;\n                    import com.airbnb.epoxy.PackageEpoxyConfig;\n                    @PackageEpoxyConfig(\n                        requireHashCode = true\n                    )\n                    interface EpoxyConfig2 {}\n                    \"\"\"\n        )\n        val model = JavaFileObjects.forResource(\n            \"ModelPackageWithNoConfigInheritsNearestParentConfig.java\".patchResource()\n        )\n\n        assertGenerationError(\n            sources = listOf(topLevelParentConfig, secondLevelParentConfig, model),\n            errorMessage = \"Attribute does not implement hashCode\",\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCode() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeFailsBasicObject.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            errorMessage = \"Attribute does not implement hashCode\",\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testConfigRequireEquals() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresEqualsFailsBasicObject.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            errorMessage = \"Attribute does not implement equals\",\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeIterableFails() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeIterableFails.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            errorMessage = \"Type in Iterable does not implement hashCode\"\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeIterablePasses() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeIterableSucceeds.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeArrayFails() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeArrayFails.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            errorMessage = \"Type in array does not implement hashCode\"\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeArrayPasses() {\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeArraySucceeds.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeEnumAttributePasses() {\n        // Verify that enum attributes pass the hashcode requirement\n        val model =\n            JavaFileObjects.forResource(\"ModelRequiresHashCodeEnumPasses.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeCharSequencePasses() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model =\n            JavaFileObjects.forResource(\"ModelConfigRequireHashCodeCharSequencePasses.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeInterfaceWithHashCodePasses() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model = JavaFileObjects.forResource(\n            \"ModelConfigRequireHashCodeInterfaceWithHashCodePasses.java\".patchResource()\n        )\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeAutoValueAttributePasses() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model = JavaFileObjects\n            .forResource(\"ModelRequiresHashCodeAutoValueClassPasses.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireHashCodeAllowsMarkedAttributes() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model = JavaFileObjects\n            .forResource(\n                \"ModelConfigRequireHashCodeAllowsMarkedAttributes.java\".patchResource()\n            )\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireAbstractModelPassesClassWithAttribute() {\n        // Verify that AutoValue class attributes pass the hashcode requirement. Only works for\n        // classes in the module since AutoValue has a retention of Source so it is discarded after\n        // compilation\n        val model =\n            JavaFileObjects.forResource(\"RequireAbstractModelPassesClassWithAttribute.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_HASH, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireAbstractModelFailsClassWithAttribute() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model =\n            JavaFileObjects.forResource(\"RequireAbstractModelFailsClassWithAttribute.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_ABSTRACT, model),\n            errorMessage = \"Epoxy model class must be abstract (RequireAbstractModelFailsClassWithAttribute)\"\n        )\n    }\n\n    @Test\n    fun testConfigRequireAbstractModelPassesEpoxyModelClass() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model =\n            JavaFileObjects.forResource(\"RequireAbstractModelPassesEpoxyModelClass.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(CONFIG_CLASS_REQUIRE_ABSTRACT, model),\n            generatedFileObjects = listOf()\n        )\n    }\n\n    @Test\n    fun testConfigRequireAbstractModelFailsEpoxyModelClass() {\n        // Verify that AutoValue class attributes pass the hashcode requirement\n        val model =\n            JavaFileObjects.forResource(\"RequireAbstractModelFailsEpoxyModelClass.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(CONFIG_CLASS_REQUIRE_ABSTRACT, model),\n            errorMessage = \"Epoxy model class must be abstract (RequireAbstractModelFailsEpoxyModelClass)\"\n        )\n    }\n\n    @Test\n    fun testConfigNoModelValidation() {\n        val model = JavaFileObjects.forResource(\"ModelNoValidation.java\".patchResource())\n        val generatedModel = JavaFileObjects.forResource(\"ModelNoValidation_.java\".patchResource())\n\n        googleCompileJava(listOf(model))\n            .withCompilerOptions(options(true, false))\n            .processedWith(processors())\n            .compilesWithoutError()\n            .and()\n            .generatesSources(generatedModel)\n    }\n\n    companion object {\n        private val CONFIG_CLASS_REQUIRE_HASH = JavaFileObjects\n            .forSourceString(\n                \"com.airbnb.epoxy.configtest.EpoxyConfig\",\n                \"\"\"package com.airbnb.epoxy.configtest;\n                        import com.airbnb.epoxy.PackageEpoxyConfig;\n                        @PackageEpoxyConfig(\n                            requireHashCode = true\n                        )\n                        interface EpoxyConfig {}\n                        \"\"\"\n            )\n        private val CONFIG_CLASS_REQUIRE_ABSTRACT = JavaFileObjects\n            .forSourceString(\n                \"com.airbnb.epoxy.configtest.EpoxyConfig\",\n                \"\"\"package com.airbnb.epoxy.configtest;\n                        import com.airbnb.epoxy.PackageEpoxyConfig;\n                        @PackageEpoxyConfig(\n                            requireAbstractModels = true\n                        )\n                        interface EpoxyConfig {}\n                        \"\"\"\n            )\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/ControllerProcessorTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGenerationError\nimport com.airbnb.epoxy.ProcessorTestUtils.options\nimport com.airbnb.epoxy.ProcessorTestUtils.processors\nimport com.google.testing.compile.JavaFileObjects\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\n\nclass ControllerProcessorTest {\n\n    @Test\n    fun controllerWithAutoModel() {\n        val model = JavaFileObjects\n            .forResource(\"BasicModelWithAttribute.java\".patchResource())\n        val controller = JavaFileObjects\n            .forResource(\"ControllerWithAutoModel.java\".patchResource())\n        val generatedHelper = JavaFileObjects\n            .forResource(\"ControllerWithAutoModel_EpoxyHelper.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, controller),\n            generatedFileObjects = listOf(generatedHelper),\n            // Kotlin compile testing does not like that the source file has an unknown type initially\n            // since its generated and logs an error, but the processing and generation completes fine, so we just\n            // ignore that error.\n            ignoreCompilationError = true,\n        )\n    }\n\n    @Test\n    fun controllerWithAutoModel_kotlin() {\n        val model = JavaFileObjects\n            .forResource(\"ControllerProcessorTest/controllerWithAutoModel/BasicModelWithAttribute.kt\".patchResource())\n        val controller = JavaFileObjects\n            .forResource(\"ControllerProcessorTest/controllerWithAutoModel/ControllerWithAutoModel.kt\".patchResource())\n        val generatedHelper = JavaFileObjects\n            .forResource(\"ControllerProcessorTest/controllerWithAutoModel/ControllerWithAutoModel_EpoxyHelper.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, controller),\n            generatedFileObjects = listOf(generatedHelper),\n            compilationMode = CompilationMode.KSP,\n        )\n    }\n\n    @Test\n    fun controllerWithAutoModelWithoutValidation() {\n        val model = JavaFileObjects\n            .forResource(\"BasicModelWithAttribute.java\".patchResource())\n        val controller = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelWithoutValidation.java\".patchResource())\n        val generatedHelper = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelWithoutValidation_EpoxyHelper.java\".patchResource())\n\n        googleCompileJava(listOf(model, controller))\n            .withCompilerOptions(options(true, false))\n            .processedWith(processors())\n            .compilesWithoutError()\n            .and()\n            .generatesSources(generatedHelper)\n    }\n\n    @Test\n    fun controllerWithSuperClassWithAutoModel() {\n        val model = JavaFileObjects\n            .forResource(\"BasicModelWithAttribute.java\".patchResource())\n        val controller = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelWithSuperClass.java\".patchResource())\n        val generatedHelper = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelWithSuperClass_EpoxyHelper.java\".patchResource())\n        val generatedSubHelper = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelWithSuperClass\\$SubControllerWithAutoModelWithSuperClass_EpoxyHelper.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, controller),\n            generatedFileObjects = listOf(generatedHelper, generatedSubHelper),\n            // Kotlin compile testing does not like that the source file has an unknown type initially\n            // since its generated and logs an error, but the processing and generation completes fine, so we just\n            // ignore that error.\n            ignoreCompilationError = true,\n        )\n    }\n\n    @Test\n    fun autoModelNotInAutoAdapterFails() {\n        val badClass = JavaFileObjects\n            .forResource(\"AutoModelNotInAutoAdapter.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(badClass),\n            errorMessage = \"\"\n        )\n    }\n\n    @Test\n    fun autoModelAnnotationNotOnModelFails() {\n        val badClass = JavaFileObjects\n            .forResource(\"AutoModelNotOnModelField.java\".patchResource())\n\n        assertGenerationError(\n            sources = listOf(badClass),\n            errorMessage = \"\"\n        )\n    }\n\n    @Test\n    fun setsStagingControllerWhenImplicitlyAddingModels() {\n        val model = JavaFileObjects\n            .forResource(\"BasicModelWithAttribute.java\".patchResource())\n        val controller = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelAndImplicitAdding.java\".patchResource())\n        val generatedHelper = JavaFileObjects\n            .forResource(\"ControllerWithAutoModelAndImplicitAdding_EpoxyHelper.java\".patchResource())\n\n        googleCompileJava(listOf(model, controller))\n            .withCompilerOptions(options(false, true))\n            .processedWith(processors())\n            .compilesWithoutError()\n            .and()\n            .generatesSources(generatedHelper)\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/DataBindingModelTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.airbnb.epoxy.ProcessorTestUtils.options\nimport com.airbnb.epoxy.ProcessorTestUtils.processors\nimport com.google.testing.compile.JavaFileObjects\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\n\nclass DataBindingModelTest {\n\n    @Test\n    fun testSimpleModel() {\n        val model = JavaFileObjects\n            .forResource(\"DataBindingModelWithAllFieldTypes.java\".patchResource())\n        val generatedModel =\n            JavaFileObjects.forResource(\"DataBindingModelWithAllFieldTypes_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, BR_CLASS, R),\n            generatedFileObjects = listOf(generatedModel),\n        )\n    }\n\n    @Test\n    fun testSimpleModelNoValidation() {\n        val model = JavaFileObjects\n            .forResource(\"DataBindingModelWithAllFieldTypesNoValidation.java\".patchResource())\n        val generatedModel =\n            JavaFileObjects.forResource(\"DataBindingModelWithAllFieldTypesNoValidation_.java\".patchResource())\n\n        googleCompileJava(listOf(model, BR_CLASS, R))\n            .withCompilerOptions(options(withNoValidation = true, withImplicitAdding = false))\n            .processedWith(processors())\n            .compilesWithoutError()\n            .and()\n            .generatesSources(generatedModel)\n    }\n\n    companion object {\n        private val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\"\"package com.airbnb.epoxy;\npublic final class R {\n  public static final class array {\n    public static final int res = 0x7f040001;\n  }\n  public static final class bool {\n    public static final int res = 0x7f040002;\n  }\n  public static final class color {\n    public static final int res = 0x7f040003;\n  }\n  public static final class layout {\n    public static final int res = 0x7f040008;\n    public static final int model_with_data_binding=0x7f040009;\n    public static final int model_with_data_binding_without_donothash=0x7f0f002b;\n  }\n  public static final class integer {\n    public static final int res = 0x7f040004;\n  }\n  public static final class styleable {\n    public static final int[] ActionBar = { 0x7f010001, 0x7f010003 };\n  }\n}\"\"\"\n        )\n        private val BR_CLASS = JavaFileObjects\n            .forSourceString(\n                \"com.airbnb.epoxy.BR\",\n                \"\"\"package com.airbnb.epoxy;\n\npublic class BR {\n  public static final int _all = 0;\n  public static final int valueInt = 1;\n  public static final int valueInteger = 2;\n  public static final int valueShort = 3;\n  public static final int valueShortWrapper = 4;\n  public static final int valueChar = 5;\n  public static final int valueCharacter = 6;\n  public static final int valuebByte = 7;\n  public static final int valueByteWrapper = 8;\n  public static final int valueLong = 9;\n  public static final int valueLongWrapper = 10;\n  public static final int valueDouble = 11;\n  public static final int valueDoubleWrapper = 12;\n  public static final int valueFloat = 13;\n  public static final int valueFloatWrapper = 14;\n  public static final int valueBoolean = 15;\n  public static final int valueBooleanWrapper = 16;\n  public static final int valueIntArray = 17;\n  public static final int valueObjectArray = 18;\n  public static final int valueString = 19;\n  public static final int valueObject = 20;\n  public static final int valueList = 21;\n  public static final int stringValue = 22;\n  public static final int clickListener = 23;\n}\"\"\"\n            )\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/EpoxyResourceProcessorTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.google.testing.compile.JavaFileObjects\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\n\nclass EpoxyResourceProcessorTest {\n\n    @Test\n    fun testGenerateDefaultLayoutMethod() {\n        val model = JavaFileObjects\n            .forResource(\"ModelForRProcessingTest.java\".patchResource())\n        val generatedModel = JavaFileObjects\n            .forResource(\"ModelForRProcessingTest_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun testRFilesWithSameValue() {\n        // These two models use different R classes, but their layout value within each R class is\n        // the same. This tests that the resource processor namespaces the R classes correctly to\n        // avoid collisions between the two identical layout values.\n        val model = JavaFileObjects\n            .forResource(\"ModelForRProcessingTest.java\".patchResource())\n\n        val modelWithDifferentRClass = JavaFileObjects\n            .forResource(\"ModelForTestingDuplicateRValues.java\".patchResource())\n\n        val generatedModel = JavaFileObjects\n            .forResource(\"ModelForRProcessingTest_.java\".patchResource())\n\n        val generatedModelWithDifferentRClass = JavaFileObjects\n            .forResource(\"ModelForTestingDuplicateRValues_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(\n                model,\n                modelWithDifferentRClass,\n                R,\n                R_FROM_DIFFERENT_PACKAGE_WITH_SAME_VALUE\n            ),\n            generatedFileObjects = listOf(generatedModel, generatedModelWithDifferentRClass),\n            // Issue with kotlin compile testing prevents us from having two files with the same name\n            // (the R class)\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    companion object {\n        private val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\"\"package com.airbnb.epoxy;\n                        public final class R {\n                          public static final class array {\n                            public static final int res = 0x7f040001;\n                          }\n                          public static final class bool {\n                            public static final int res = 0x7f040002;\n                          }\n                          public static final class color {\n                            public static final int res = 0x7f040003;\n                          }\n                          public static final class layout {\n                            public static final int res = 0x7f040008;\n                          }\n                          public static final class integer {\n                            public static final int res = 0x7f040004;\n                          }\n                          public static final class styleable {\n                            public static final int[] ActionBar = { 0x7f010001, 0x7f010003 };\n                          }\n                        }\"\"\"\n        )\n        private val R_FROM_DIFFERENT_PACKAGE_WITH_SAME_VALUE = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.othermodule.R\",\n            \"\"\"package com.airbnb.epoxy.othermodule;\n                    public final class R {\n                      public static final class layout {\n                        public static final int res_in_other_module = 0x7f040008;\n                      }\n                    }\"\"\"\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/GuavaPatch.kt",
    "content": "@file:JvmName(\"GuavaPatch\")\npackage com.airbnb.epoxy\n\nimport java.io.File\nimport java.net.URL\n\n/**\n * Since AGP 3.6.0, the class-loader behavior has been modified.\n * Unfortunately Guava (via compile-testing) uses a class-loader based mechanism\n * which is valid on JVM but not supposed to be supported on Android.\n * As the project paths are simple enough, we can hardcode them for now.\n */\nfun String.patchResource(): URL =\n    File(\"build/intermediates/sourceFolderJavaResources/debug/$this\").toURI().toURL()\n\nfun File.unpatchResource(): File = File(\n    canonicalPath.replace(\n        \"build/intermediates/sourceFolderJavaResources/debug/\",\n        \"src/test/resources/\"\n    )\n)\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/ModelProcessorTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGenerationError\nimport com.airbnb.epoxy.ProcessorTestUtils.checkFileCompiles\nimport com.google.testing.compile.JavaFileObjects\nimport junit.framework.Assert\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\n\n/**\n * These processor tests are in their own module since the processor module can't depend on the\n * android EpoxyAdapter library that contains the EpoxyModel.\n */\nclass ModelProcessorTest {\n    @Test\n    fun testSimpleModel() {\n        assertGeneration(\"BasicModelWithAttribute.java\", \"BasicModelWithAttribute_.java\")\n    }\n\n    @Test\n    fun testModelWithAllFieldTypes() {\n        assertGeneration(\"ModelWithAllFieldTypes.java\", \"ModelWithAllFieldTypes_.java\")\n    }\n\n    @Test\n    fun testModelWithConstructors() {\n        assertGeneration(\"ModelWithConstructors.java\", \"ModelWithConstructors_.java\")\n    }\n\n    @Test\n    fun testModelWithSuper() {\n        assertGeneration(\"ModelWithSuper.java\", \"ModelWithSuper_.java\")\n    }\n\n    @Test\n    fun testModelWithFieldAnnotation() {\n        assertGeneration(\"ModelWithFieldAnnotation.java\", \"ModelWithFieldAnnotation_.java\")\n    }\n\n    @Test\n    fun testModelWithSuperClass() {\n        val model = JavaFileObjects.forResource(\"ModelWithSuperAttributes.java\".patchResource())\n\n        val generatedModel =\n            JavaFileObjects.forResource(\"ModelWithSuperAttributes_.java\".patchResource())\n\n        val generatedSubClassModel =\n            JavaFileObjects.forResource(\"ModelWithSuperAttributes\\$SubModelWithSuperAttributes_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model),\n            generatedFileObjects = listOf(generatedModel, generatedSubClassModel)\n        )\n    }\n\n    @Test\n    fun testModelWithType() {\n        assertGeneration(\n            \"ModelWithType.java\",\n            \"ModelWithType_.java\",\n            // The generics in the model don't seem to work with KSP/Kotlin. It isn't a real/good\n            // use case anyway, so don't care about supporting it.\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithoutHash() {\n        assertGeneration(\"ModelWithoutHash.java\", \"ModelWithoutHash_.java\")\n    }\n\n    @Test\n    fun testDoNotHashModel() {\n        assertGeneration(\"ModelDoNotHash.java\", \"ModelDoNotHash_.java\")\n    }\n\n    @Test\n    fun testModelWithFinalAttribute() {\n        assertGeneration(\"ModelWithFinalField.java\", \"ModelWithFinalField_.java\")\n    }\n\n    @Test\n    fun testModelWithStaticAttributeFails() {\n        assertGenerationError(\"ModelWithStaticField.java\", \"static\")\n    }\n\n    @Test\n    fun testModelWithPrivateClassFails() {\n        assertGenerationError(\n            \"ModelWithPrivateInnerClass.java\",\n            \"private classes\",\n            // KSP bug prevents us from testing this case https://github.com/google/ksp/issues/622\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithFinalClassFails() {\n        assertGenerationError(\"ModelWithFinalClass.java\", \"\")\n    }\n\n    @Test\n    fun testModelThatDoesNotExtendEpoxyModelFails() {\n        assertGenerationError(\"ModelWithoutEpoxyExtension.java\", \"must extend\")\n    }\n\n    @Test\n    fun testModelAsInnerClassFails() {\n        assertGenerationError(\"ModelAsInnerClass.java\", \"Nested model classes must be static\")\n    }\n\n    @Test\n    fun testModelWithIntDefAnnotation() {\n        assertGeneration(\n            \"ModelWithIntDef.java\",\n            \"ModelWithIntDef_.java\",\n            // Throws NPE in KSP due to https://github.com/google/ksp/issues/622\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithAnnotatedClass() {\n        assertGeneration(\"ModelWithAnnotatedClass.java\", \"ModelWithAnnotatedClass_.java\")\n    }\n\n    @Test\n    fun testModelWithAbstractClass() {\n        val model = JavaFileObjects\n            .forResource(\"ModelWithAbstractClass.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model)\n        )\n\n        // We don't generate subclasses if the model is abstract unless it has a class annotation.\n        val modelNotGenerated: Boolean = try {\n            JavaFileObjects.forResource(\"non-sense? Any wrong path will generate IAE\")\n            false\n        } catch (e: IllegalArgumentException) {\n            true\n        }\n\n        Assert.assertTrue(modelNotGenerated)\n    }\n\n    @Test\n    fun testModelWithAbstractClassAndAnnotation() {\n        assertGeneration(\n            \"ModelWithAbstractClassAndAnnotation.java\",\n            \"ModelWithAbstractClassAndAnnotation_.java\"\n        )\n    }\n\n    @Test\n    fun testKotlinModel_kapt() {\n        assertGeneration(\n            \"ModelProcessorTest/testKotlinModel/Model.kt\",\n            \"ModelProcessorTest/testKotlinModel/Model_.java\",\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun testKotlinModel_ksp() {\n        assertGeneration(\n            \"ModelProcessorTest/testKotlinModel/Model.kt\",\n            \"ModelProcessorTest/testKotlinModel/Model_.java\",\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun testModelWithAnnotatedClassAndSuperClass() {\n        val model = JavaFileObjects\n            .forResource(\"ModelWithAnnotatedClassAndSuperAttributes.java\".patchResource())\n\n        val generatedModel = JavaFileObjects\n            .forResource(\"ModelWithAnnotatedClassAndSuperAttributes_.java\".patchResource())\n\n        val generatedSubClassModel = JavaFileObjects.forResource(\n            (\n                \"ModelWithAnnotatedClassAndSuperAttributes\\$SubModel\" +\n                    \"WithAnnotatedClassAndSuperAttributes_.java\"\n                ).patchResource()\n        )\n        assertGeneration(\n            sources = listOf(model),\n            generatedFileObjects = listOf(generatedModel, generatedSubClassModel),\n            // Throws NPE in KSP due to https://github.com/google/ksp/issues/622\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithoutSetter() {\n        assertGeneration(\"ModelWithoutSetter.java\", \"ModelWithoutSetter_.java\")\n    }\n\n    @Test\n    fun testModelReturningClassType() {\n        assertGeneration(\"ModelReturningClassType.java\", \"ModelReturningClassType_.java\")\n    }\n\n    @Test\n    fun testModelReturningClassTypeWithVarargs() {\n        assertGeneration(\n            \"ModelReturningClassTypeWithVarargs.java\",\n            \"ModelReturningClassTypeWithVarargs_.java\"\n        )\n    }\n\n    @Test\n    fun testModelWithVarargsConstructors() {\n        assertGeneration(\n            \"ModelWithVarargsConstructors.java\",\n            \"ModelWithVarargsConstructors_.java\",\n            // The kotlin extension generation doesn't actually work with vararg constructors.\n            // it's a bug we're not trying to support, so just make sure this works with the originally\n            // intended legacy java.\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithHolderGeneratesNewHolderMethod() {\n        assertGeneration(\n            \"AbstractModelWithHolder.java\",\n            \"AbstractModelWithHolder_.java\",\n            // The nested static holder class results in KSP seeing it as an \"Error\" type during processing\n            // for some reason (seems like a bug?). There doesn't seem to be a way to defer the\n            // symbol the way we access it via a type param does not give the underlying KSAnnotated\n            // element. The separate test with kotlin sources works fine, so workaround is to write\n            // the holder classes in kotlin if needed.\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun testModelWithHolderGeneratesNewHolderMethod_kotlin() {\n        assertGeneration(\n            \"testModelWithHolderGeneratesNewHolderMethod/AbstractModelWithHolder.kt\",\n            \"testModelWithHolderGeneratesNewHolderMethod/AbstractModelWithHolder_.java\",\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun testGenerateDefaultLayoutMethod() {\n        assertGeneration(\"GenerateDefaultLayoutMethod.java\", \"GenerateDefaultLayoutMethod_.java\")\n    }\n\n    @Test\n    fun testGenerateDefaultLayoutMethodFailsIfLayoutNotSpecified() {\n        assertGenerationError(\n            \"GenerateDefaultLayoutMethodNoLayout.java\",\n            \"Model must specify a valid layout resource\"\n        )\n    }\n\n    @Test\n    fun testGeneratedDefaultMethodWithLayoutSpecifiedInParent() {\n        val model = JavaFileObjects\n            .forResource(\"GenerateDefaultLayoutMethodParentLayout.java\".patchResource())\n\n        val generatedNoLayoutModel = JavaFileObjects\n            .forResource(\"GenerateDefaultLayoutMethodParentLayout\\$NoLayout_.java\".patchResource())\n\n        val generatedWithLayoutModel =\n            JavaFileObjects.forResource(\"GenerateDefaultLayoutMethodParentLayout\\$WithLayout_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model),\n            generatedFileObjects = listOf(generatedNoLayoutModel, generatedWithLayoutModel)\n        )\n    }\n\n    @Test\n    fun testGeneratedDefaultMethodWithLayoutSpecifiedInNextParent() {\n        val model = JavaFileObjects\n            .forResource(\"GenerateDefaultLayoutMethodNextParentLayout.java\".patchResource())\n\n        val generatedNoLayoutModel = JavaFileObjects\n            .forResource(\"GenerateDefaultLayoutMethodNextParentLayout\\$NoLayout_.java\".patchResource())\n\n        val generatedStillNoLayoutModel = JavaFileObjects\n            .forResource(\"GenerateDefaultLayoutMethodNextParentLayout\\$StillNoLayout_.java\".patchResource())\n\n        val generatedWithLayoutModel =\n            JavaFileObjects.forResource(\"GenerateDefaultLayoutMethodNextParentLayout\\$WithLayout_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model),\n            generatedFileObjects = listOf(\n                generatedNoLayoutModel,\n                generatedStillNoLayoutModel,\n                generatedWithLayoutModel\n            )\n        )\n    }\n\n    @Test\n    fun testGeneratedDefaultMethodWithLayoutFailsIfNotSpecifiedInParent() {\n        assertGenerationError(\n            \"GenerateDefaultLayoutMethodParentStillNoLayout.java\",\n            \"Model must specify a valid layout resource\"\n        )\n    }\n\n    @Test\n    fun modelWithViewClickListener() {\n        assertGeneration(\"ModelWithViewClickListener.java\", \"ModelWithViewClickListener_.java\")\n    }\n\n    @Test\n    fun modelWithViewClickLongListener() {\n        val model = JavaFileObjects\n            .forResource(\"ModelWithViewLongClickListener.java\".patchResource())\n\n        val generatedNoLayoutModel = JavaFileObjects\n            .forResource(\"ModelWithViewLongClickListener_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model),\n            generatedFileObjects = listOf(generatedNoLayoutModel)\n        )\n    }\n\n    @Test\n    fun modelWithCheckedChangeListener() {\n        assertGeneration(\n            \"ModelWithCheckedChangeListener.java\",\n            \"ModelWithCheckedChangeListener_.java\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithoutGetterAndSetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithoutGetterAndSetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithoutSetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithoutSetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithoutGetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithoutGetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithIsPrefixGetter() {\n        checkFileCompiles(\"ModelWithPrivateFieldWithIsPrefixGetter.java\")\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithPrivateGetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithPrivateGetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithStaticGetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithStaticGetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithGetterWithParamsFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithGetterWithParams.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithPrivateSetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithPrivateSetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithStaticSetterFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithStaticSetter.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithPrivateAttributeWithGetterWithoutParamsFails() {\n        assertGenerationError(\n            \"ModelWithPrivateFieldWithSettterWithoutParams.java\",\n            \"private fields without proper getter and setter\"\n        )\n    }\n\n    @Test\n    fun testModelWithAllPrivateFieldTypes() {\n        assertGeneration(\n            \"ModelWithAllPrivateFieldTypes.java\",\n            \"ModelWithAllPrivateFieldTypes_.java\"\n        )\n    }\n\n    @Test\n    fun modelWithViewPrivateClickListener() {\n        assertGeneration(\n            \"ModelWithPrivateViewClickListener.java\",\n            \"ModelWithPrivateViewClickListener_.java\"\n        )\n    }\n\n    @Test\n    fun modelWithPrivateFieldWithSameAsFieldGetterAndSetterName() {\n        assertGeneration(\n            \"ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName.java\",\n            \"ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_.java\"\n        )\n    }\n\n    @Test\n    fun testDoNotUseInToStringModel() {\n        assertGeneration(\"ModelDoNotUseInToString.java\", \"ModelDoNotUseInToString_.java\")\n    }\n\n    @Test\n    fun modelWithAnnotation() {\n        assertGeneration(\"ModelWithAnnotation.java\", \"ModelWithAnnotation_.java\")\n    }\n\n    @Test\n    fun testModelBuilderInterface() {\n        assertGeneration(\"ModelWithAllFieldTypes.java\", \"ModelWithAllFieldTypesBuilder.java\")\n    }\n\n    @Test\n    fun generatedEpoxyModelGroup() {\n        assertGeneration(\n            \"EpoxyModelGroupWithAnnotations.java\",\n            \"EpoxyModelGroupWithAnnotations_.java\",\n        )\n    }\n\n    @Test\n    fun generatedEpoxyModelWithView() {\n        assertGeneration(\n            \"AbstractEpoxyModelWithView.java\",\n            \"AbstractEpoxyModelWithView_.java\"\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/ProcessorTestUtils.kt",
    "content": "package com.airbnb.epoxy\n\nimport com.airbnb.epoxy.processor.ControllerProcessor\nimport com.airbnb.epoxy.processor.ControllerProcessorProvider\nimport com.airbnb.epoxy.processor.DataBindingProcessor\nimport com.airbnb.epoxy.processor.DataBindingProcessorProvider\nimport com.airbnb.epoxy.processor.EpoxyProcessor\nimport com.airbnb.epoxy.processor.EpoxyProcessorProvider\nimport com.airbnb.epoxy.processor.ModelViewProcessor\nimport com.airbnb.epoxy.processor.ModelViewProcessorProvider\nimport com.airbnb.paris.processor.ParisProcessor\nimport com.airbnb.paris.processor.ParisProcessorProvider\nimport com.github.difflib.DiffUtils\nimport com.google.common.truth.Truth.assert_\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.google.testing.compile.JavaFileObjects\nimport com.google.testing.compile.JavaSourcesSubject\nimport com.google.testing.compile.JavaSourcesSubjectFactory.javaSources\nimport com.tschuchort.compiletesting.KotlinCompilation\nimport com.tschuchort.compiletesting.SourceFile\nimport com.tschuchort.compiletesting.configureKsp\nimport com.tschuchort.compiletesting.kspProcessorOptions\nimport com.tschuchort.compiletesting.kspSourcesDir\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport strikt.api.expect\nimport strikt.api.expectThat\nimport strikt.assertions.contains\nimport strikt.assertions.doesNotContain\nimport strikt.assertions.isEmpty\nimport strikt.assertions.isNotNull\nimport java.io.File\nimport javax.annotation.processing.Processor\nimport javax.tools.JavaFileObject\n\n@ExperimentalCompilerApi\ninternal object ProcessorTestUtils {\n    @JvmStatic\n    fun assertGenerationError(\n        inputFile: String,\n        errorMessage: String,\n        compilationMode: CompilationMode = CompilationMode.ALL\n    ) {\n        val model = JavaFileObjects\n            .forResource(inputFile.patchResource())\n\n        assertGenerationError(listOf(model), errorMessage, compilationMode)\n    }\n\n    fun assertGenerationError(\n        sources: List<JavaFileObject>,\n        errorMessage: String,\n        compilationMode: CompilationMode = CompilationMode.ALL\n    ) {\n        if (compilationMode.testJavaAP) {\n            googleCompileJava(sources)\n                .processedWith(processors())\n                .failsToCompile()\n                .withErrorContaining(errorMessage)\n        }\n\n        expectCompilationFailure(\n            errorMessage,\n            sourceFiles = toKotlinCompilationSourceFiles(sources),\n            compilationMode = compilationMode\n        )\n    }\n\n    @JvmStatic\n    fun checkFileCompiles(inputFile: String) {\n        val model = JavaFileObjects\n            .forResource(inputFile.patchResource())\n\n        googleCompileJava(listOf(model))\n            .processedWith(processors())\n            .compilesWithoutError()\n    }\n\n    @JvmStatic\n    @JvmOverloads\n    fun processors(useParis: Boolean = false): MutableList<Processor> {\n        return mutableListOf<Processor>().apply {\n            add(EpoxyProcessor())\n            add(ControllerProcessor())\n            add(DataBindingProcessor())\n            add(ModelViewProcessor())\n            if (useParis) add(ParisProcessor())\n        }\n    }\n\n    fun processorProviders(useParis: Boolean = false): List<SymbolProcessorProvider> {\n        return mutableListOf<SymbolProcessorProvider>().apply {\n            add(EpoxyProcessorProvider())\n            add(ControllerProcessorProvider())\n            add(DataBindingProcessorProvider())\n            add(ModelViewProcessorProvider())\n            if (useParis) add(ParisProcessorProvider())\n        }\n    }\n\n    @JvmStatic\n    fun options(\n        withNoValidation: Boolean = false,\n        withImplicitAdding: Boolean = false\n    ): List<String> {\n        return mutableListOf<String>().apply {\n            if (withNoValidation) add(\"validateEpoxyModelUsage\" setTo false)\n            if (withImplicitAdding) add(\"implicitlyAddAutoModels\" setTo true)\n        }\n    }\n\n    @JvmOverloads\n    @JvmStatic\n    fun assertGeneration(\n        inputFile: String,\n        generatedFile: String,\n        useParis: Boolean = false,\n        helperObjects: List<JavaFileObject> = emptyList(),\n        compilationMode: CompilationMode = CompilationMode.ALL,\n        ignoreCompilationError: Boolean = false\n    ) {\n        assertGeneration(\n            sourceFileNames = listOf(inputFile),\n            sourceObjects = helperObjects,\n            generatedFileNames = listOf(generatedFile),\n            useParis = useParis,\n            compilationMode = compilationMode,\n            ignoreCompilationError = ignoreCompilationError,\n        )\n    }\n\n    @JvmStatic\n    fun assertGeneration(\n        inputFiles: List<String>,\n        generatedFileNames: List<String>,\n        useParis: Boolean = false,\n        compilationMode: CompilationMode = CompilationMode.ALL,\n        ignoreCompilationError: Boolean = false\n    ) {\n        assertGeneration(\n            sourceFileNames = inputFiles,\n            generatedFileNames = generatedFileNames,\n            useParis = useParis,\n            compilationMode = compilationMode,\n            ignoreCompilationError = ignoreCompilationError,\n        )\n    }\n\n    @JvmName(\"assertGenerationWithFileObjects\")\n    fun assertGeneration(\n        sourceFileNames: List<String> = emptyList(),\n        sourceObjects: List<JavaFileObject> = emptyList(),\n        generatedFileNames: List<String> = emptyList(),\n        generatedFileObjects: List<JavaFileObject> = emptyList(),\n        useParis: Boolean = false,\n        compilationMode: CompilationMode = CompilationMode.ALL,\n        ignoreCompilationError: Boolean = false\n    ) {\n        assertGeneration(\n            sources = sourceObjects + sourceFileNames.toJavaFileObjects(),\n            generatedFileObjects = generatedFileObjects + generatedFileNames.toJavaFileObjects(),\n            useParis = useParis,\n            compilationMode = compilationMode,\n            ignoreCompilationError = ignoreCompilationError,\n        )\n    }\n\n    @JvmName(\"assertGenerationWithFileObjects\")\n    fun assertGeneration(\n        sources: List<JavaFileObject>,\n        generatedFileObjects: List<JavaFileObject> = emptyList(),\n        useParis: Boolean = false,\n        compilationMode: CompilationMode = CompilationMode.ALL,\n        /**\n         * As long as the generated files match properly then ignore any errors during compilation.\n         * This can be used to workaround kinks in kotlin compile testing library.\n         */\n        ignoreCompilationError: Boolean = false\n    ) {\n        if (compilationMode.testJavaAP) {\n\n            googleCompileJava(sources)\n                .processedWith(processors(useParis))\n                .compilesWithoutError().apply {\n                    if (generatedFileObjects.isNotEmpty()) {\n                        and()\n                            .generatesSources(\n                                generatedFileObjects[0],\n                                *generatedFileObjects.drop(1).toTypedArray()\n                            )\n                    }\n                }\n\n            googleCompileJava(sources)\n                // Also compile using these flags, since they run different code and could help\n                // catch concurrency issues, as well as indeterminate ways that the order of generated\n                // code may change due to concurrent processing. Generated code output must be stable\n                // to provide stable build cache keys\n                .withAnnotationProcessorOptions(\n                    \"logEpoxyTimings\" to true,\n                )\n                .processedWith(processors(useParis))\n                .compilesWithoutError().apply {\n                    if (generatedFileObjects.isNotEmpty()) {\n                        and()\n                            .generatesSources(\n                                generatedFileObjects[0],\n                                *generatedFileObjects.drop(1).toTypedArray()\n                            )\n                    }\n                }\n        }\n\n        // Convert from the java file objects that google compile testing uses to source files\n        // that kotlin compile testing can use.\n        val generatedFiles = generatedFileObjects.map { generatedFileObject ->\n            File(generatedFileObject.toUri()).also {\n                check(it.exists()) { \"Don't have a file for $generatedFileObject\" }\n            }\n        }\n\n        val sourcesForKotlinCompilation = toKotlinCompilationSourceFiles(sources)\n\n        if (compilationMode.testKapt) {\n            testCodeGeneration(\n                sourceFiles = sourcesForKotlinCompilation,\n                expectedOutput = generatedFiles,\n                useKsp = false,\n                useParis = useParis,\n                ignoreCompilationError = ignoreCompilationError,\n            )\n        }\n\n        if (compilationMode.testKSP) {\n\n            // KSP can't capture the original parameter names in java sources so it uses \"p0\"/\"p1\"/etc\n            // placeholders, which differs from kapt behavior. Due to this we can't directly compare them\n            // and instead maintain separate ksp expected sources.\n            val generatedKspFiles = generatedFiles.map { generatedFile ->\n                File(generatedFile.parent, \"/ksp/${generatedFile.name}\")\n                    .unpatchResource()\n                    .also {\n                        if (!it.exists()) {\n                            it.parentFile?.mkdirs()\n                            it.createNewFile()\n                        }\n                    }\n            }\n\n            testCodeGeneration(\n                sourceFiles = sourcesForKotlinCompilation,\n                expectedOutput = generatedKspFiles,\n                useKsp = true,\n                useParis = useParis,\n                ignoreCompilationError = ignoreCompilationError\n            )\n        }\n    }\n\n    private fun toKotlinCompilationSourceFiles(sources: List<JavaFileObject>): List<SourceFile> {\n        return sources.map { javaFileObject ->\n            SourceFile.new(\n                name = javaFileObject.name.substringAfterLast(\"/\"),\n                contents = javaFileObject.openInputStream().bufferedReader().readText()\n            )\n        }\n    }\n\n    /**\n     * Test that [sourceFiles] generate [expectedOutput].\n     * @param useKsp - If true ksp will be used as the annotation processing backend, if false, kapt will be used.\n     *\n     * You can set [UPDATE_TEST_SOURCES_ON_DIFF] to true to have the original sources file updated for the actual generated code.\n     */\n    fun testCodeGeneration(\n        sourceFiles: List<SourceFile>,\n        expectedOutput: List<File> = emptyList(),\n        unexpectedOutputFileName: List<String> = emptyList(),\n        useKsp: Boolean = true,\n        useParis: Boolean = false,\n        args: MutableMap<String, String> = mutableMapOf(),\n        ignoreCompilationError: Boolean = false\n    ) {\n        println(\"Using ksp: $useKsp\")\n        val compilation = getCompilation(useKsp, args, sourceFiles, useParis)\n        val result = compilation.compile()\n\n        val generatedSources = if (useKsp) {\n            compilation.kspSourcesDir.walk().filter { it.isFile }.toList()\n        } else {\n            result.sourcesGeneratedByAnnotationProcessor\n        }\n\n        if (result.exitCode != KotlinCompilation.ExitCode.OK) {\n            println(\"Generated:\")\n            generatedSources.forEach { println(it.readText()) }\n            if (!ignoreCompilationError) {\n                error(\"Compilation failed with ${result.exitCode}.\")\n            }\n        }\n\n        println(\"Generated files:\")\n        generatedSources.forEach { println(it.name) }\n\n        expect {\n            expectedOutput.forEach { expectedOutputFile ->\n                val actualOutputFileName = expectedOutputFile.name\n                // Since we may encode output files as txt resources, we need to remove the suffix when comparing\n                // generated filename to expected filename.\n                val expectedOutputFilename = actualOutputFileName.removeSuffix(\".txt\")\n                val generated = generatedSources.find { it.name == expectedOutputFilename }\n                that(generated) {\n                    isNotNull().and {\n                        val patch =\n                            DiffUtils.diff(generated!!.readLines(), expectedOutputFile.readLines())\n                        if (patch.deltas.isNotEmpty()) {\n                            println(\"Found differences for $expectedOutputFilename!\")\n                            println(\"Actual filename in filesystem is $actualOutputFileName\")\n                            println(\"Expected:\\n\")\n                            println(expectedOutputFile.readText())\n                            println(\"Generated:\\n\")\n                            println(generated.readText())\n\n                            if (UPDATE_TEST_SOURCES_ON_DIFF) {\n                                println(\"UPDATE_TEST_SOURCES_ON_DIFF is enabled; updating expected sources with actual sources.\")\n                                expectedOutputFile.unpatchResource().apply {\n                                    parentFile?.mkdirs()\n                                    writeText(generated.readText())\n                                }\n                            }\n                        }\n                        that(patch.deltas).isEmpty()\n                    }\n                }.describedAs(expectedOutputFilename)\n            }\n        }\n        val generatedFileNames = generatedSources.map { it.name }\n        if (unexpectedOutputFileName.isNotEmpty()) {\n            expectThat(generatedFileNames).doesNotContain(unexpectedOutputFileName)\n        }\n    }\n\n    /**\n     * Allows writing compilation test name with backticks that specifies a resource folder. If there folder is nested `/` should be\n     * encoded as ` `. Compilation is expceted to fail with [failureMessage].\n     */\n    fun expectCompilationFailure(\n        failureMessage: String,\n        sourceFiles: List<SourceFile>,\n        args: MutableMap<String, String> = mutableMapOf(),\n        compilationMode: CompilationMode = CompilationMode.ALL\n    ) {\n        fun testCodeGenerationFailure(useKsp: Boolean) {\n            val compilation = getCompilation(useKsp, args, sourceFiles)\n\n            val result = compilation.compile()\n\n            if (result.exitCode == KotlinCompilation.ExitCode.OK) {\n                error(\"Compilation succeed.\")\n            }\n            expectThat(result.messages).contains(failureMessage)\n        }\n\n        if (compilationMode.testKSP) {\n            testCodeGenerationFailure(useKsp = true)\n        }\n        if (compilationMode.testKapt) {\n            testCodeGenerationFailure(useKsp = false)\n        }\n    }\n\n    private fun getCompilation(\n        useKsp: Boolean,\n        args: MutableMap<String, String>,\n        sourceFiles: List<SourceFile>,\n        useParis: Boolean = false\n    ): KotlinCompilation {\n        return KotlinCompilation().apply {\n            if (useKsp) configureKsp {\n                symbolProcessorProviders += processorProviders(useParis)\n                kspProcessorOptions.putAll(args)\n            } else {\n                annotationProcessors = processors(useParis)\n                kaptArgs = args\n            }\n            sources = sourceFiles\n            inheritClassPath = true\n            messageOutputStream = System.out\n        }\n    }\n}\n\ninfix fun String.setTo(value: Any) = \"-A$this=$value\"\n\nfun JavaSourcesSubject.withAnnotationProcessorOptions(vararg option: Pair<String, Any>): JavaSourcesSubject {\n    return withCompilerOptions(option.map { it.first setTo it.second })\n}\n\nfun googleCompileJava(sources: List<JavaFileObject>): JavaSourcesSubject {\n    return assert_().about(javaSources())\n        .that(sources)\n        .withAnnotationProcessorOptions(\n            // java ap cannot generate kotlin sources\n            \"disableEpoxyKotlinExtensionGeneration\" to true,\n        )\n}\n\nfun List<String>.toJavaFileObjects() = map { JavaFileObjects.forResource(it.patchResource()) }\n\nfun javaFile(name: String) = JavaFileObjects.forResource(name.patchResource())\n\nenum class CompilationMode(\n    val testKapt: Boolean = false,\n    val testKSP: Boolean = false,\n    val testJavaAP: Boolean = false\n) {\n    KSP(testKSP = true),\n    JavaAP(testJavaAP = true),\n    KAPT(testKapt = true),\n    ALL(testKSP = true, testKapt = true, testJavaAP = true)\n}\n\n/**\n * Change to true to have tests auto update the expected sources files for easy updating of tests.\n */\nconst val UPDATE_TEST_SOURCES_ON_DIFF = true\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/ViewProcessorTest.kt",
    "content": "@file:OptIn(ExperimentalCompilerApi::class)\n\npackage com.airbnb.epoxy\n\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGeneration\nimport com.airbnb.epoxy.ProcessorTestUtils.assertGenerationError\nimport com.google.testing.compile.JavaFileObjects\nimport org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi\nimport org.junit.Test\nimport javax.tools.JavaFileObject\n\nclass ViewProcessorTest {\n\n    @Test\n    fun stringOverloads() {\n        assertGeneration(\"TestStringOverloadsView.java\", \"TestStringOverloadsViewModel_.java\")\n    }\n\n    @Test\n    fun stringOverloads_throwsIfNotCharSequence() {\n        assertGenerationError(\n            \"StringOverloads_throwsIfNotCharSequence.java\",\n            \"must be a CharSequence\"\n        )\n    }\n\n    @Test\n    fun nullStringOverloads() {\n        assertGeneration(\n            \"TestNullStringOverloadsView.java\",\n            \"TestNullStringOverloadsViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun manyTypes() {\n        assertGeneration(\"TestManyTypesView.java\", \"TestManyTypesViewModel_.java\")\n    }\n\n    @Test\n    fun manyTypes_kapt() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/testManyTypes/TestManyTypesView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/testManyTypes/TestManyTypesViewModel_.java\",\n                \"ViewProcessorTest/testManyTypes/TestManyTypesViewModelBuilder.java\",\n                \"ViewProcessorTest/testManyTypes/EpoxyModelViewProcessorKotlinExtensions.kt\"\n            ),\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun manyTypes_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/testManyTypes/TestManyTypesView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/testManyTypes/TestManyTypesViewModel_.java\",\n                \"ViewProcessorTest/testManyTypes/TestManyTypesViewModelBuilder.java\",\n                \"ViewProcessorTest/testManyTypes/EpoxyModelViewProcessorKotlinExtensions.kt\"\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun inheritingAttributesWorksCorrectly_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun inheritingAttributesWorksCorrectly_kapt() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun inheritingAttributesWorksCorrectlyJavaSources_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceView.kt\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/AirEpoxyModel.java\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceViewModel_.java\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun inheritingAttributesWorksCorrectlyJavaClassPath_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModel_.java\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun inheritingAttributesWorksCorrectlyJavaClassPath_kapt() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModel_.java\",\n                \"ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun wildcardHandling_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/wildcardHandling/SourceView.kt\",\n                \"ViewProcessorTest/wildcardHandling/AirEpoxyModel.java\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/wildcardHandling/SourceViewModel_.java\",\n                \"ViewProcessorTest/wildcardHandling/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun annotationsAreCopied_java() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/annotationsAreCopied_java/SourceView.java\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/annotationsAreCopied_java/SourceViewModel_.java\",\n                \"ViewProcessorTest/annotationsAreCopied_java/SourceViewModelBuilder.java\",\n            ),\n        )\n    }\n\n    @Test\n    fun annotationsAreCopied_ksp() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/annotationsAreCopied/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/annotationsAreCopied/SourceViewModel_.java\",\n                \"ViewProcessorTest/annotationsAreCopied/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun annotationsAreCopied_kapt() {\n        assertGeneration(\n            inputFiles = listOf(\n                \"ViewProcessorTest/annotationsAreCopied/SourceView.kt\",\n            ),\n            generatedFileNames = listOf(\n                \"ViewProcessorTest/annotationsAreCopied/SourceViewModel_.java\",\n                \"ViewProcessorTest/annotationsAreCopied/SourceViewModelBuilder.java\",\n            ),\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun prop_throwsIfPrivate() {\n        assertGenerationError(\"Prop_throwsIfPrivate.java\", \"private\")\n    }\n\n    @Test\n    fun prop_throwsIfStatic() {\n        assertGenerationError(\"Prop_throwsIfStatic.java\", \"static\")\n    }\n\n    @Test\n    fun prop_throwsIfNoParams() {\n        assertGenerationError(\"Prop_throwsIfNoParams.java\", \"must have exactly 1 parameter\")\n    }\n\n    @Test\n    fun prop_throwsIfMultipleParams() {\n        assertGenerationError(\"Prop_throwsIfMultipleParams.java\", \"must have exactly 1 parameter\")\n    }\n\n    @Test\n    fun groups() {\n        assertGeneration(\"PropGroupsView.java\", \"PropGroupsViewModel_.java\")\n    }\n\n    @Test\n    fun defaults() {\n        assertGeneration(\"PropDefaultsView.java\", \"PropDefaultsViewModel_.java\")\n    }\n\n    @Test\n    fun defaults_throwsForNonStaticValue() {\n        assertGenerationError(\"PropDefaultsView_throwsForNonStaticValue.java\", \"static\")\n    }\n\n    @Test\n    fun defaults_throwsForNonFinalValue() {\n        assertGenerationError(\"PropDefaultsView_throwsForNonFinalValue.java\", \"final\")\n    }\n\n    @Test\n    fun defaults_throwsForPrivateValue_kapt() {\n        assertGenerationError(\n            \"PropDefaultsView_throwsForPrivateValue.java\",\n            \"final\",\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun defaults_kspGeneratesCodeForPrivateValue() {\n        assertGeneration(\n            sourceFileNames = listOf(\"PropDefaultsView_throwsForPrivateValue.java\"),\n            compilationMode = CompilationMode.KSP,\n            // Previously, no code was generated for private fields and the test passed.\n            // Now code is generated that references private fields, causing compilation errors,\n            // but the code generation itself works correctly, so we ignore the compilation error.\n            ignoreCompilationError = true\n        )\n    }\n\n    @Test\n    fun defaults_throwsForWrongType() {\n        assertGenerationError(\"PropDefaultsView_throwsForWrongType.java\", \"must be a int\")\n    }\n\n    @Test\n    fun defaults_throwsForNotFound() {\n        assertGenerationError(\"PropDefaultsView_throwsForNotFound.java\", \"could not be found\")\n    }\n\n    @Test\n    fun onViewRecycled() {\n        assertGeneration(\"OnViewRecycledView.java\", \"OnViewRecycledViewModel_.java\")\n    }\n\n    @Test\n    fun onViewRecycled_throwsIfPrivate() {\n        assertGenerationError(\"OnViewRecycledView_throwsIfPrivate.java\", \"private\")\n    }\n\n    @Test\n    fun onViewRecycled_throwsIfStatic() {\n        assertGenerationError(\"OnViewRecycledView_throwsIfStatic.java\", \"static\")\n    }\n\n    @Test\n    fun onViewRecycled_throwsIfHasParams() {\n        assertGenerationError(\n            \"OnViewRecycledView_throwsIfHasParams.java\",\n            \"must have exactly 0 parameter\"\n        )\n    }\n\n    @Test\n    fun onVisibilityChanged() {\n        assertGeneration(\n            \"OnVisibilityChangedView.java\",\n            \"OnVisibilityChangedViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun onVisibilityChanged_throwsIfPrivate() {\n        assertGenerationError(\n            \"OnVisibilityChangedView_throwsIfPrivate.java\",\n            \"private\"\n        )\n    }\n\n    @Test\n    fun onVisibilityChanged_throwsIfStatic() {\n        assertGenerationError(\n            \"OnVisibilityChangedView_throwsIfStatic.java\",\n            \"static\"\n        )\n    }\n\n    @Test\n    fun onVisibilityChanged_throwsIfInvalidParams() {\n        assertGenerationError(\n            inputFile = \"OnVisibilityChangedView_throwsIfInvalidParams.java\",\n            errorMessage = \"Methods annotated with Class must have parameter types [float, float, int, int], found: [Boolean, Boolean, Int, Int] (method: onVisibilityChanged)\",\n            compilationMode = CompilationMode.KSP\n        )\n\n        assertGenerationError(\n            inputFile = \"OnVisibilityChangedView_throwsIfInvalidParams.java\",\n            errorMessage = \"must have parameter types [float, float, int, int], found: \" +\n                \"[boolean, boolean, int, int] (method: onVisibilityChanged)\",\n            compilationMode = CompilationMode.JavaAP\n        )\n    }\n\n    @Test\n    fun onVisibilityChanged_throwsIfNoParams() {\n        assertGenerationError(\n            \"OnVisibilityChangedView_throwsIfNoParams.java\",\n            \"must have exactly 4 parameter (method: onVisibilityChanged)\"\n        )\n    }\n\n    @Test\n    fun onVisibilityStateChanged() {\n        assertGeneration(\n            \"OnVisibilityStateChangedView.java\",\n            \"OnVisibilityStateChangedViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun onVisibilityStateChanged_throwsIfPrivate() {\n        assertGenerationError(\n            \"OnVisibilityStateChangedView_throwsIfPrivate.java\",\n            \"private\"\n        )\n    }\n\n    @Test\n    fun onVisibilityStateChanged_throwsIfStatic() {\n        assertGenerationError(\n            \"OnVisibilityStateChangedView_throwsIfStatic.java\",\n            \"static\"\n        )\n    }\n\n    @Test\n    fun onVisibilityStateChanged_throwsIfInvalidParams() {\n        assertGenerationError(\n            inputFile = \"OnVisibilityStateChangedView_throwsIfInvalidParams.java\",\n            errorMessage = \"must have parameter types [int], found: [boolean] (method: onVisibilityStateChanged)\",\n            compilationMode = CompilationMode.JavaAP\n        )\n\n        assertGenerationError(\n            inputFile = \"OnVisibilityStateChangedView_throwsIfInvalidParams.java\",\n            errorMessage = \"must have parameter types [int], found: [Boolean] (method: onVisibilityStateChanged)\",\n            compilationMode = CompilationMode.KSP\n        )\n    }\n\n    @Test\n    fun onVisibilityStateChanged_throwsIfNoParams() {\n        assertGenerationError(\n            \"OnVisibilityStateChangedView_throwsIfNoParams.java\",\n            \"must have exactly 1 parameter (method: onVisibilityStateChanged)\"\n        )\n    }\n\n    @Test\n    fun nullOnRecycle() {\n        assertGeneration(\"NullOnRecycleView.java\", \"NullOnRecycleViewModel_.java\")\n    }\n\n    @Test\n    fun nullOnRecycle_throwsIfNotNullable() {\n        assertGenerationError(\"NullOnRecycleView_throwsIfNotNullable.java\", \"@Nullable\")\n    }\n\n    @Test\n    fun doNotHash() {\n        assertGeneration(\"DoNotHashView.java\", \"DoNotHashViewModel_.java\")\n    }\n\n    @Test\n    fun objectWithoutEqualsThrows() {\n        assertGenerationError(\n            \"ObjectWithoutEqualsThrowsView.java\",\n            \"Attribute does not implement hashCode\"\n        )\n    }\n\n    @Test\n    fun ignoreRequireHashCode() {\n        assertGeneration(\"IgnoreRequireHashCodeView.java\", \"IgnoreRequireHashCodeViewModel_.java\")\n    }\n\n    @Test\n    fun savedState() {\n        assertGeneration(\"SavedStateView.java\", \"SavedStateViewModel_.java\")\n    }\n\n    @Test\n    fun gridSpanCount() {\n        assertGeneration(\"GridSpanCountView.java\", \"GridSpanCountViewModel_.java\")\n    }\n\n    @Test\n    fun baseModel() {\n        val model = JavaFileObjects\n            .forResource(\"BaseModelView.java\".patchResource())\n\n        val baseModel = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.TestBaseModel\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.widget.FrameLayout;\\n\" +\n                    \"\\n\" +\n                    \"import java.util.List;\\n\" +\n                    \"\\n\" +\n                    \"public abstract class TestBaseModel<T extends FrameLayout> \" +\n                    \"extends EpoxyModel<T> {\\n\" +\n                    \" public TestBaseModel(long id) { super(id); }\" +\n                    \"\\n\" +\n                    \"  @Override\\n\" +\n                    \"  public void bind(T view) {\\n\" +\n                    \"    super.bind(view);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"  @Override\\n\" +\n                    \"  public void bind(T view, List<Object> payloads) {\\n\" +\n                    \"    super.bind(view, payloads);\\n\" +\n                    \"  }\\n\" +\n                    \"}\\n\"\n            )\n\n        val generatedModel = JavaFileObjects.forResource(\"BaseModelViewModel_.java\".patchResource())\n        assertGeneration(\n            sources = listOf(baseModel, model),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun baseModelWithDiffBind() {\n        val baseModel = JavaFileObjects.forSourceLines(\n            \"com.airbnb.epoxy.TestBaseModel\",\n            \"package com.airbnb.epoxy;\\n\" +\n                \"\\n\" +\n                \"import android.widget.FrameLayout;\\n\" +\n                \"\\n\" +\n                \"public abstract class TestBaseModel<T extends FrameLayout> \" +\n                \"extends EpoxyModel<T> {\\n\" +\n                \"@Override\\n\" +\n                \"  public void bind(T view, EpoxyModel<?> previouslyBoundModel) {\\n\" +\n                \"    super.bind(view, previouslyBoundModel);\\n\" +\n                \"  }\" +\n                \"}\"\n        )\n\n        assertGeneration(\n            sourceFileNames = listOf(\"BaseModelView.java\"),\n            sourceObjects = listOf(baseModel),\n            generatedFileNames = listOf(\"baseModelWithDiffBind/BaseModelViewModel_.java\")\n        )\n    }\n\n    @Test\n    fun baseModelWithAttribute() {\n        val model = JavaFileObjects\n            .forResource(\"BaseModelView.java\".patchResource())\n\n        val baseModel = JavaFileObjects.forSourceLines(\n            \"com.airbnb.epoxy.TestBaseModel\",\n            \"package com.airbnb.epoxy;\\n\" +\n                \"\\n\" +\n                \"import android.widget.FrameLayout;\\n\" +\n                \"\\n\" +\n                \"public abstract class TestBaseModel<T extends FrameLayout> \" +\n                \"extends EpoxyModel<T> {\\n\" +\n                \"  @EpoxyAttribute String baseModelString;\\n\" +\n                \"}\\n\"\n        )\n\n        val generatedModel =\n            JavaFileObjects.forResource(\"baseModelWithAttribute/BaseModelViewModel_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(baseModel, model),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun throwsIfBaseModelNotEpoxyModel() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.BaseModelView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.widget.FrameLayout;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView(defaultLayout = 1, baseModelClass = TestBaseModel.class)\\n\" +\n                    \"public class BaseModelView extends FrameLayout {\\n\" +\n                    \"\\n\" +\n                    \"  public BaseModelView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"  @ModelProp\\n\" +\n                    \"  public void setClickListener(String title) {\\n\" +\n                    \"\\n\" +\n                    \"  }\\n\" +\n                    \"}\"\n            )\n\n        val baseModel = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.TestBaseModel\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"public abstract class TestBaseModel{\\n\" +\n                    \"}\\n\"\n            )\n\n        assertGenerationError(\n            sources = listOf(baseModel, model),\n            errorMessage = \"The base model provided to an ModelView must extend EpoxyModel\"\n        )\n    }\n\n    @Test\n    fun baseModelFromPackageConfig() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.BaseModelView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.widget.FrameLayout;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView(defaultLayout = 1)\\n\" +\n                    \"public class BaseModelView extends FrameLayout {\\n\" +\n                    \"\\n\" +\n                    \"  public BaseModelView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"  @ModelProp\\n\" +\n                    \"  public void setClickListener(String title) {\\n\" +\n                    \"\\n\" +\n                    \"  }\\n\" +\n                    \"}\"\n            )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    import com.airbnb.epoxy.TestBaseModel;\n                    \n                    @PackageModelViewConfig(rClass = R.class, defaultBaseModelClass = TestBaseModel.class)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val baseModel = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.TestBaseModel\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"public abstract class TestBaseModel<T extends View> \" +\n                    \"extends EpoxyModel<T> {\\n\" +\n                    \"}\\n\"\n            )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"baseModelFromPackageConfig/BaseModelViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(baseModel, model, configClass, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun baseModelFromPackageConfigIsOverriddenByViewSetting() {\n        // If a package default is set for the base model it can be overridden if the view sets its\n        // own base model\n\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.BaseModelView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView(defaultLayout = 1, baseModelClass = EpoxyModel.class)\\n\" +\n                    \"public class BaseModelView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public BaseModelView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"  @ModelProp\\n\" +\n                    \"  public void setClickListener(String title) {\\n\" +\n                    \"\\n\" +\n                    \"  }\\n\" +\n                    \"}\"\n            )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    import com.airbnb.epoxy.TestBaseModel;\n                    \n                    @PackageModelViewConfig(rClass = R.class, defaultBaseModelClass = TestBaseModel.class)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val baseModel = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.TestBaseModel\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"public abstract class TestBaseModel<T extends View> \" +\n                    \"extends EpoxyModel<T> {\\n\" +\n                    \"}\\n\"\n            )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"baseModelFromPackageConfigIsOverriddenByViewSetting/BaseModelViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(baseModel, model, configClass, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun throwsIfBaseModelNotEpoxyModelInPackageConfig() {\n        val model = JavaFileObjects\n            .forResource(\"BaseModelView.java\".patchResource())\n\n        val baseModel = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.TestBaseModel\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"public abstract class TestBaseModel{\\n\" +\n                    \"}\\n\"\n            )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    import com.airbnb.epoxy.TestBaseModel;\n                    \n                    @PackageModelViewConfig(rClass = R.class, defaultBaseModelClass = TestBaseModel.class)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        assertGenerationError(\n            sources = listOf(baseModel, model, configClass, R),\n            errorMessage = \"The base model provided to an ModelView must extend EpoxyModel\"\n        )\n    }\n\n    @Test\n    fun rLayoutInViewModelAnnotationWorks() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.RLayoutInViewModelAnnotationWorksView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView(defaultLayout = R.layout.res)\\n\" +\n                    \"public class RLayoutInViewModelAnnotationWorksView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public RLayoutInViewModelAnnotationWorksView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"}\"\n            )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"RLayoutInViewModelAnnotationWorksViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(model, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun packageLayoutPatternDefault() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.DefaultPackageLayoutPatternView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView\\n\" +\n                    \"public class DefaultPackageLayoutPatternView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public DefaultPackageLayoutPatternView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"}\"\n            )\n\n        val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int default_package_layout_pattern_view = 0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    \n                    @PackageModelViewConfig(rClass = R.class)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"DefaultPackageLayoutPatternViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(model, configClass, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun packageLayoutPatternDefaultWithR2() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.DefaultPackageLayoutPatternView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView\\n\" +\n                    \"public class DefaultPackageLayoutPatternView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public DefaultPackageLayoutPatternView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"}\"\n            )\n\n        val R2 = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R2\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R2 {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int default_package_layout_pattern_view = 0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int default_package_layout_pattern_view = 0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R2;\n                    \n                    @PackageModelViewConfig(rClass = R2.class)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"DefaultPackageLayoutPatternViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(model, configClass, R2, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun packageLayoutCustomPattern() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.CustomPackageLayoutPatternView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView\\n\" +\n                    \"public class CustomPackageLayoutPatternView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public CustomPackageLayoutPatternView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"}\"\n            )\n\n        val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int hello_custom_package_layout_pattern_view_me = \" +\n                \"0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    \n                    @PackageModelViewConfig(rClass = R.class, defaultLayoutPattern = \"hello_%s_me\")\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"CustomPackageLayoutPatternViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(model, configClass, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun layoutOverloads() {\n        val model = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.LayoutOverloadsView\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import android.content.Context;\\n\" +\n                    \"import android.view.View;\\n\" +\n                    \"\\n\" +\n                    \"@ModelView\\n\" +\n                    \"public class LayoutOverloadsView extends View {\\n\" +\n                    \"\\n\" +\n                    \"  public LayoutOverloadsView(Context context) {\\n\" +\n                    \"    super(context);\\n\" +\n                    \"  }\\n\" +\n                    \"\\n\" +\n                    \"}\"\n            )\n\n        val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int layout_overloads_view = 0x7f040008;\\n\" +\n                \"    public static final int layout_overloads_view_one = 0x7f040009;\\n\" +\n                \"    public static final int layout_overloads_view_two = 0x7f04000a;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    \n                    @PackageModelViewConfig(rClass = R.class, useLayoutOverloads = true)\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        val generatedModel = JavaFileObjects.forResource(\n            \"LayoutOverloadsViewModel_.java\".patchResource()\n        )\n\n        assertGeneration(\n            sources = listOf(model, configClass, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun generatedModelSuffix() {\n        val model = JavaFileObjects.forSourceLines(\n            \"com.airbnb.epoxy.GeneratedModelSuffixView\",\n            \"package com.airbnb.epoxy;\\n\" +\n                \"\\n\" +\n                \"import android.content.Context;\\n\" +\n                \"import android.view.View;\\n\" +\n                \"\\n\" +\n                \"@ModelView\\n\" +\n                \"public class GeneratedModelSuffixView extends View {\\n\" +\n                \"\\n\" +\n                \"  public GeneratedModelSuffixView(Context context) {\\n\" +\n                \"    super(context);\\n\" +\n                \"  }\\n\" +\n                \"\\n\" +\n                \"}\"\n        )\n\n        val R = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int generated_model_suffix_view = 0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n\n        val configClass = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.EpoxyModelViewConfig\",\n            \"\"\"\n                    package com.airbnb.epoxy;\n                    \n                    import com.airbnb.epoxy.PackageModelViewConfig;\n                    import com.airbnb.epoxy.R;\n                    \n                    @PackageModelViewConfig(rClass = R.class, generatedModelSuffix = \"Suffix_\")\n                    interface EpoxyModelViewConfig {}\n            \"\"\".trimIndent()\n        )\n\n        assertGeneration(\n            sourceObjects = listOf(model, configClass, R),\n            generatedFileNames = listOf(\"GeneratedModelSuffixViewSuffix_.java\")\n        )\n    }\n\n    @Test\n    fun afterBindProps() {\n        val model = JavaFileObjects\n            .forResource(\"TestAfterBindPropsView.java\".patchResource())\n\n        val superModel = JavaFileObjects\n            .forResource(\"TestAfterBindPropsSuperView.java\".patchResource())\n\n        val generatedModel =\n            JavaFileObjects.forResource(\"TestAfterBindPropsViewModel_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, superModel),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun textProp() {\n        assertGeneration(\"TestTextPropView.java\", \"TestTextPropViewModel_.java\")\n    }\n\n    @Test\n    fun textPropMustBeCharSequence() {\n        assertGenerationError(\"TestTextPropMustBeCharSequenceView.java\", \"must be a CharSequence\")\n    }\n\n    @Test\n    fun textPropDefault() {\n        val model = JavaFileObjects\n            .forResource(\"TextPropDefaultView.java\".patchResource())\n\n        val generatedModel =\n            JavaFileObjects.forResource(\"TextPropDefaultViewModel_.java\".patchResource())\n\n        assertGeneration(\n            sources = listOf(model, R),\n            generatedFileObjects = listOf(generatedModel)\n        )\n    }\n\n    @Test\n    fun textPropDefault_throwsForNonStringRes() {\n        val model = JavaFileObjects\n            .forResource(\"TextPropDefaultView_throwsForNonStringRes.java\".patchResource())\n\n        assertGenerationError(\n            listOf(model, R),\n            \"@TextProp value for defaultRes must be a String resource\"\n        )\n    }\n\n    @Test\n    fun callbackProp() {\n        assertGeneration(\"TestCallbackPropView.java\", \"TestCallbackPropViewModel_.java\")\n    }\n\n    @Test\n    fun callbackPropMustBeNullable() {\n        assertGenerationError(\"TestCallbackPropMustBeNullableView.java\", \"must be marked Nullable\")\n    }\n\n    @Test\n    fun testModelBuilderInterface() {\n        assertGeneration(\"TestManyTypesView.java\", \"TestManyTypesViewModelBuilder.java\")\n    }\n\n    @Test\n    fun testAutoLayout() {\n        assertGeneration(\"AutoLayoutModelView.java\", \"AutoLayoutModelViewModel_.java\")\n    }\n\n    @Test\n    fun testAutoLayoutMatchParent() {\n        assertGeneration(\n            \"AutoLayoutModelViewMatchParent.java\",\n            \"AutoLayoutModelViewMatchParentModel_.java\"\n        )\n    }\n\n    @Test\n    fun testAutoLayoutManualLayoutParams() {\n        assertGeneration(\n            \"AutoLayoutModelViewManualLayoutParams.java\",\n            \"AutoLayoutModelViewManualLayoutParamsModel_.java\"\n        )\n    }\n\n    @Test\n    fun testModelViewInheritsFromSuperClass() {\n        assertViewsHaveModelsGenerated(\n            \"ModelViewSuperClass.java\",\n            \"ModelViewExtendingSuperClass.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropModelProp() {\n        assertGeneration(\"TestFieldPropModelPropView.java\", \"TestFieldPropModelPropViewModel_.java\")\n    }\n\n    @Test\n    fun testFieldPropTextProp() {\n        assertGeneration(\"TestFieldPropTextPropView.java\", \"TestFieldPropTextPropViewModel_.java\")\n    }\n\n    @Test\n    fun testFieldPropCallbackProp() {\n        assertGeneration(\n            \"TestFieldPropCallbackPropView.java\",\n            \"TestFieldPropCallbackPropViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropDoNotHashOption() {\n        assertGeneration(\n            \"TestFieldPropDoNotHashOptionView.java\",\n            \"TestFieldPropDoNotHashOptionViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropGenerateStringOverloadsOption() {\n        assertGeneration(\n            \"TestFieldPropGenerateStringOverloadsOptionView.java\",\n            \"TestFieldPropGenerateStringOverloadsOptionViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropNullOnRecycleOption() {\n        assertGeneration(\n            \"TestFieldPropNullOnRecycleOptionView.java\",\n            \"TestFieldPropNullOnRecycleOptionViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropIgnoreRequireHashCodeOption() {\n        assertGeneration(\n            \"TestFieldPropIgnoreRequireHashCodeOptionView.java\",\n            \"TestFieldPropIgnoreRequireHashCodeOptionViewModel_.java\"\n        )\n    }\n\n    @Test\n    fun testFieldPropInheritFromParentView() {\n        assertGeneration(\n            listOf(\"TestFieldPropChildView.java\", \"TestFieldPropParentView.java\"),\n            listOf(\"TestFieldPropChildViewModel_.java\")\n        )\n    }\n\n    @Test\n    fun testFieldPropThrowsIfPrivate_kapt() {\n        assertGenerationError(\n            \"TestFieldPropThrowsIfPrivateView.java\",\n            \"private\",\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun testFieldPropGeneratesCodeForPrivate_ksp() {\n        assertGeneration(\n            sourceFileNames = listOf(\"PropDefaultsView_throwsForPrivateValue.java\"),\n            compilationMode = CompilationMode.KSP,\n            // Previously, no code was generated for private fields and the test passed.\n            // Now code is generated that references private fields, causing compilation errors,\n            // but the code generation itself works correctly, so we ignore the compilation error.\n            ignoreCompilationError = true\n        )\n    }\n\n    @Test\n    fun testFieldPropThrowsIfStatic() {\n        assertGenerationError(\"TestFieldPropThrowsIfStaticView.java\", \"static\")\n    }\n\n    @Test\n    fun testFieldPropStringOverloadsIfNotCharSequence() {\n        assertGenerationError(\n            \"TestFieldPropStringOverloadsIfNotCharSequenceView.java\",\n            \"must be a CharSequence\"\n        )\n    }\n\n    @Test\n    fun testFieldPropTextPropIfNotCharSequence() {\n        assertGenerationError(\"TestTextPropIfNotCharSequenceView.java\", \"must be a CharSequence\")\n    }\n\n    @Test\n    fun testStyleableView_kapt() {\n        val configClass: JavaFileObject = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.Config\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import com.airbnb.paris.annotations.ParisConfig;\\n\" +\n                    \"import com.airbnb.epoxy.R;\\n\" +\n\n                    \"@ParisConfig(rClass = R.class)\\n\" +\n                    \"class Config {}\"\n            )\n\n        assertGeneration(\n            inputFile = \"ModelViewWithParis.java\",\n            generatedFile = \"ModelViewWithParisModel_.java\",\n            useParis = true,\n            helperObjects = listOf(configClass, R),\n            compilationMode = CompilationMode.KAPT\n        )\n    }\n\n    @Test\n    fun testStyleableView_ksp() {\n        val configClass: JavaFileObject = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.Config\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import com.airbnb.paris.annotations.ParisConfig;\\n\" +\n                    \"import com.airbnb.epoxy.R;\\n\" +\n\n                    \"@ParisConfig(rClass = R.class)\\n\" +\n                    \"class Config {}\"\n            )\n\n        assertGeneration(\n            inputFile = \"ModelViewWithParis.java\",\n            generatedFile = \"ModelViewWithParisModel_.java\",\n            useParis = true,\n            helperObjects = listOf(configClass, R),\n            compilationMode = CompilationMode.KSP,\n            // the generated paris references are reported as errors even though they are properly generated\n            // after processing.\n            ignoreCompilationError = true\n        )\n    }\n\n    @Test\n    fun testStyleableViewKotlinSources_ksp() {\n        val configClass: JavaFileObject = JavaFileObjects\n            .forSourceLines(\n                \"com.airbnb.epoxy.Config\",\n                \"package com.airbnb.epoxy;\\n\" +\n                    \"\\n\" +\n                    \"import com.airbnb.paris.annotations.ParisConfig;\\n\" +\n                    \"import com.airbnb.epoxy.R;\\n\" +\n\n                    \"@ParisConfig(rClass = R.class)\\n\" +\n                    \"class Config {}\"\n            )\n\n        assertGeneration(\n            inputFile = \"ViewProcessorTest/testStyleableViewKotlinSources/ModelViewWithParis.kt\",\n            generatedFile = \"ViewProcessorTest/testStyleableViewKotlinSources/ModelViewWithParisModel_.java\",\n            useParis = true,\n            helperObjects = listOf(configClass, R),\n            compilationMode = CompilationMode.KSP,\n        )\n    }\n\n    private fun assertViewsHaveModelsGenerated(vararg viewFiles: String) {\n        assertGeneration(viewFiles.toList(), viewFiles.map { it.replace(\".\", \"Model_.\") })\n    }\n\n    companion object {\n\n        private val R: JavaFileObject = JavaFileObjects.forSourceString(\n            \"com.airbnb.epoxy.R\",\n            \"\" +\n                \"package com.airbnb.epoxy;\\n\" +\n                \"public final class R {\\n\" +\n                \"  public static final class layout {\\n\" +\n                \"    public static final int res = 0x7f040008;\\n\" +\n                \"  }\\n\" +\n                \"  public static final class string {\\n\" +\n                \"    public static final int string_resource_value = 0x7f040009;\\n\" +\n                \"  }\\n\" +\n                \"}\"\n        )\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/java/com/airbnb/epoxy/testpackage/DifferentPackageTest.java",
    "content": "package com.airbnb.epoxy.testpackage;\n\nimport org.junit.Test;\nimport com.airbnb.integrationtest.processortest.differentpackage.Model_;\n\n/**\n * A test to check that a model subclass in a different package from its super class does not\n * include package private fields from its super class on its generated model.\n * <p>\n * This also tests that model superclasses in different modules have their attributes included in\n * the generated class too.\n */\npublic class DifferentPackageTest {\n\n  @Test\n  public void differentPackageUsage() {\n    new Model_()\n        .subclassValue(1)\n        // Attributes from super class in same module, different package.\n        .publicValue(1)\n        .protectedValue(1)\n        // Inherited attributes from a subclass in a different module\n        .processorTest2ValueProtected(3)\n        .processorTest2ValuePublic(3);\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AbstractEpoxyModelWithView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.airbnb.epoxy.EpoxyModelClass;\nimport com.airbnb.epoxy.EpoxyModelWithView;\n\nimport androidx.annotation.NonNull;\n\n@EpoxyModelClass\npublic abstract class AbstractEpoxyModelWithView extends EpoxyModelWithView<View> {\n  @Override\n  public View buildView(@NonNull ViewGroup parent) {\n    return new View(parent.getContext());\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AbstractEpoxyModelWithView_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AbstractEpoxyModelWithView_ extends AbstractEpoxyModelWithView implements GeneratedModel<View>, AbstractEpoxyModelWithViewBuilder {\n  private OnModelBoundListener<AbstractEpoxyModelWithView_, View> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AbstractEpoxyModelWithView_, View> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AbstractEpoxyModelWithView_, View> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AbstractEpoxyModelWithView_, View> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public AbstractEpoxyModelWithView_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final View object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final View object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractEpoxyModelWithView_ onBind(\n      OnModelBoundListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(View object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractEpoxyModelWithView_ onUnbind(\n      OnModelUnboundListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final View object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractEpoxyModelWithView_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final View object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractEpoxyModelWithView_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AbstractEpoxyModelWithView_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AbstractEpoxyModelWithView_ that = (AbstractEpoxyModelWithView_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AbstractEpoxyModelWithView_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AbstractModelWithHolder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.NonNull;\n\n@EpoxyModelClass\npublic abstract class AbstractModelWithHolder\n    extends EpoxyModelWithHolder<AbstractModelWithHolder.Holder> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  static class Holder extends EpoxyHolder {\n\n    protected void bindView(@NonNull View itemView) {\n\n    }\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AbstractModelWithHolder_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewParent;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AbstractModelWithHolder_ extends AbstractModelWithHolder implements GeneratedModel<AbstractModelWithHolder.Holder>, AbstractModelWithHolderBuilder {\n  private OnModelBoundListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public AbstractModelWithHolder_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final AbstractModelWithHolder.Holder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final AbstractModelWithHolder.Holder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onBind(\n      OnModelBoundListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AbstractModelWithHolder.Holder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onUnbind(\n      OnModelUnboundListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final AbstractModelWithHolder.Holder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AbstractModelWithHolder.Holder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AbstractModelWithHolder_, AbstractModelWithHolder.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public AbstractModelWithHolder_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected AbstractModelWithHolder.Holder createNewHolder(ViewParent parent) {\n    return new AbstractModelWithHolder.Holder();\n  }\n\n  @Override\n  public AbstractModelWithHolder_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AbstractModelWithHolder_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AbstractModelWithHolder_ that = (AbstractModelWithHolder_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AbstractModelWithHolder_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\npublic class AutoLayoutModelView extends View {\n\n  public AutoLayoutModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  void setValue(int value) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelViewManualLayoutParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup.LayoutParams;\n\nimport com.airbnb.epoxy.ModelView.Size;\n\n@ModelView(autoLayout = Size.MANUAL)\npublic class AutoLayoutModelViewManualLayoutParams extends View {\n\n  public AutoLayoutModelViewManualLayoutParams(Context context) {\n    super(context);\n    setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));\n  }\n\n  @ModelProp\n  void setValue(int value) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelViewManualLayoutParamsModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.NullPointerException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewManualLayoutParamsModel_ extends EpoxyModel<AutoLayoutModelViewManualLayoutParams> implements GeneratedModel<AutoLayoutModelViewManualLayoutParams>, AutoLayoutModelViewManualLayoutParamsModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParams buildView(ViewGroup parent) {\n    AutoLayoutModelViewManualLayoutParams v = new AutoLayoutModelViewManualLayoutParams(parent.getContext());\n    if (v.getLayoutParams() == null) {\n      throw new NullPointerException(\"Layout params is required to be set for Size.MANUAL\");\n    }\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final AutoLayoutModelViewManualLayoutParams object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewManualLayoutParams object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewManualLayoutParams object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewManualLayoutParamsModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewManualLayoutParamsModel_ that = (AutoLayoutModelViewManualLayoutParamsModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelViewManualLayoutParams object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelViewManualLayoutParams object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final AutoLayoutModelViewManualLayoutParams object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelViewManualLayoutParams object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelViewManualLayoutParams#setValue(int)\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewManualLayoutParamsModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewManualLayoutParamsModel_ that = (AutoLayoutModelViewManualLayoutParamsModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewManualLayoutParamsModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelViewMatchParent.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelView.Size;\n\n@ModelView(autoLayout = Size.MATCH_WIDTH_MATCH_HEIGHT)\npublic class AutoLayoutModelViewMatchParent extends View {\n\n  public AutoLayoutModelViewMatchParent(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  void setValue(int value) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelViewMatchParentModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewMatchParentModel_ extends EpoxyModel<AutoLayoutModelViewMatchParent> implements GeneratedModel<AutoLayoutModelViewMatchParent>, AutoLayoutModelViewMatchParentModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParent buildView(ViewGroup parent) {\n    AutoLayoutModelViewMatchParent v = new AutoLayoutModelViewMatchParent(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final AutoLayoutModelViewMatchParent object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewMatchParent object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewMatchParent object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewMatchParentModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewMatchParentModel_ that = (AutoLayoutModelViewMatchParentModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelViewMatchParent object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewMatchParentModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelViewMatchParent object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewMatchParentModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final AutoLayoutModelViewMatchParent object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewMatchParentModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelViewMatchParent object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewMatchParentModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelViewMatchParent#setValue(int)\n   */\n  public AutoLayoutModelViewMatchParentModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewMatchParentModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewMatchParentModel_ that = (AutoLayoutModelViewMatchParentModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewMatchParentModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoLayoutModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewModel_ extends EpoxyModel<AutoLayoutModelView> implements GeneratedModel<AutoLayoutModelView>, AutoLayoutModelViewModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelView buildView(ViewGroup parent) {\n    AutoLayoutModelView v = new AutoLayoutModelView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final AutoLayoutModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelView object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewModel_ that = (AutoLayoutModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final AutoLayoutModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelView#setValue(int)\n   */\n  public AutoLayoutModelViewModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewModel_ that = (AutoLayoutModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoModelNotInAutoAdapter.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\n\npublic class AutoModelNotInAutoAdapter {\n\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute_;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/AutoModelNotOnModelField.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class AutoModelNotOnModelField extends EpoxyController {\n\n  @AutoModel String value;\n\n  @Override\n  protected void buildModels() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/BaseModelView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\n@ModelView(defaultLayout = 1, baseModelClass = TestBaseModel.class)\npublic class BaseModelView extends FrameLayout {\n\n  public BaseModelView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setClickListener(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_(long id) {\n    super(id);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/BasicModelWithAttribute.java",
    "content": "package com.airbnb.epoxy;\n\npublic class BasicModelWithAttribute extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/BasicModelWithAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BasicModelWithAttribute_ extends BasicModelWithAttribute implements GeneratedModel<Object>, BasicModelWithAttributeBuilder {\n  private OnModelBoundListener<BasicModelWithAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BasicModelWithAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BasicModelWithAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BasicModelWithAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public BasicModelWithAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithAttribute_ onBind(\n      OnModelBoundListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithAttribute_ onUnbind(\n      OnModelUnboundListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public BasicModelWithAttribute_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BasicModelWithAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BasicModelWithAttribute_ that = (BasicModelWithAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BasicModelWithAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerProcessorTest/controllerWithAutoModel/BasicModelWithAttribute.kt",
    "content": "package com.airbnb.epoxy\n\nopen class BasicModelWithAttribute : EpoxyModel<Any?>() {\n    @EpoxyAttribute\n    var value = 0\n\n    override fun getDefaultLayout(): Int {\n        return 0\n    }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerProcessorTest/controllerWithAutoModel/ControllerWithAutoModel.kt",
    "content": "package com.airbnb.epoxy.adapter\n\nimport android.view.View\nimport com.airbnb.epoxy.AutoModel\nimport com.airbnb.epoxy.BasicModelWithAttribute_\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model\n\nclass ControllerWithAutoModel : EpoxyController() {\n    @AutoModel\n    lateinit var modelWithAttribute1: BasicModelWithAttribute_\n\n    @AutoModel\n    lateinit var modelWithAttribute2: BasicModelWithAttribute_\n\n    @AutoModel\n    lateinit var modelFromClassPath: ProcessorTest2Model<View>\n\n    protected override fun buildModels() {}\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerProcessorTest/controllerWithAutoModel/ControllerWithAutoModel_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModel_EpoxyHelper extends ControllerHelper<ControllerWithAutoModel> {\n  private final ControllerWithAutoModel controller;\n\n  private EpoxyModel modelWithAttribute2;\n\n  private EpoxyModel modelWithAttribute1;\n\n  public ControllerWithAutoModel_EpoxyHelper(ControllerWithAutoModel controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-1);\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-2);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -1);\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute2 = controller.modelWithAttribute2;\n    modelWithAttribute1 = controller.modelWithAttribute1;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerProcessorTest/controllerWithAutoModel/ksp/ControllerWithAutoModel_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport android.view.View;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModel_EpoxyHelper extends ControllerHelper<ControllerWithAutoModel> {\n  private final ControllerWithAutoModel controller;\n\n  private EpoxyModel modelFromClassPath;\n\n  private EpoxyModel modelWithAttribute2;\n\n  private EpoxyModel modelWithAttribute1;\n\n  public ControllerWithAutoModel_EpoxyHelper(ControllerWithAutoModel controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelFromClassPath = new ProcessorTest2Model<View>();\n    controller.modelFromClassPath.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-3);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelFromClassPath, controller.modelFromClassPath, \"modelFromClassPath\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -3);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelFromClassPath = controller.modelFromClassPath;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n    modelWithAttribute1 = controller.modelWithAttribute1;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModel.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithAutoModel extends EpoxyController {\n\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute1;\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute2;\n\n  @Override\n  protected void buildModels() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelAndImplicitAdding.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithAutoModelAndImplicitAdding extends EpoxyController {\n\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute1;\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute2;\n\n  @Override\n  protected void buildModels() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelAndImplicitAdding_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelAndImplicitAdding_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelAndImplicitAdding> {\n  private final ControllerWithAutoModelAndImplicitAdding controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModelAndImplicitAdding_EpoxyHelper(\n      ControllerWithAutoModelAndImplicitAdding controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    setControllerToStageTo(controller.modelWithAttribute1, controller);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    setControllerToStageTo(controller.modelWithAttribute2, controller);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass> {\n  private final ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute3;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper(\n      ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute3 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute3.id(-2);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-3);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute3, controller.modelWithAttribute3, \"modelWithAttribute3\", -2);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -3);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute3 = controller.modelWithAttribute3;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelWithSuperClass.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithAutoModelWithSuperClass extends EpoxyController {\n\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute1;\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute2;\n\n  @Override\n  protected void buildModels() {\n\n  }\n\n  public static class SubControllerWithAutoModelWithSuperClass extends ControllerWithAutoModelWithSuperClass {\n\n    @AutoModel BasicModelWithAttribute_ modelWithAttribute3;\n\n    @Override\n    protected void buildModels() {\n\n    }\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelWithSuperClass_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelWithSuperClass_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelWithSuperClass> {\n  private final ControllerWithAutoModelWithSuperClass controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModelWithSuperClass_EpoxyHelper(\n      ControllerWithAutoModelWithSuperClass controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelWithoutValidation.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.AutoModel;\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.EpoxyController;\n\npublic class ControllerWithAutoModelWithoutValidation extends EpoxyController {\n\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute1;\n  @AutoModel BasicModelWithAttribute_ modelWithAttribute2;\n\n  @Override\n  protected void buildModels() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModelWithoutValidation_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport java.lang.Override;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelWithoutValidation_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelWithoutValidation> {\n  private final ControllerWithAutoModelWithoutValidation controller;\n\n  public ControllerWithAutoModelWithoutValidation_EpoxyHelper(\n      ControllerWithAutoModelWithoutValidation controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ControllerWithAutoModel_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModel_EpoxyHelper extends ControllerHelper<ControllerWithAutoModel> {\n  private final ControllerWithAutoModel controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModel_EpoxyHelper(ControllerWithAutoModel controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/CustomPackageLayoutPatternViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class CustomPackageLayoutPatternViewModel_ extends EpoxyModel<CustomPackageLayoutPatternView> implements GeneratedModel<CustomPackageLayoutPatternView>, CustomPackageLayoutPatternViewModelBuilder {\n  private OnModelBoundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final CustomPackageLayoutPatternView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final CustomPackageLayoutPatternView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final CustomPackageLayoutPatternView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof CustomPackageLayoutPatternViewModel_)) {\n      bind(object);\n      return;\n    }\n    CustomPackageLayoutPatternViewModel_ that = (CustomPackageLayoutPatternViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final CustomPackageLayoutPatternView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CustomPackageLayoutPatternViewModel_ onBind(\n      OnModelBoundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(CustomPackageLayoutPatternView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CustomPackageLayoutPatternViewModel_ onUnbind(\n      OnModelUnboundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final CustomPackageLayoutPatternView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CustomPackageLayoutPatternViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final CustomPackageLayoutPatternView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CustomPackageLayoutPatternViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.hello_custom_package_layout_pattern_view_me;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof CustomPackageLayoutPatternViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    CustomPackageLayoutPatternViewModel_ that = (CustomPackageLayoutPatternViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"CustomPackageLayoutPatternViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DataBindingConfig.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyDataBindingLayouts({R.layout.model_with_data_binding})\ninterface EpoxyDataBindingConfig {}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DataBindingModelWithAllFieldTypes.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\n@EpoxyModelClass\npublic abstract class DataBindingModelWithAllFieldTypes extends DataBindingEpoxyModel {\n  @EpoxyAttribute int valueInt;\n  @EpoxyAttribute Integer valueInteger;\n  @EpoxyAttribute short valueShort;\n  @EpoxyAttribute Short valueShortWrapper;\n  @EpoxyAttribute char valueChar;\n  @EpoxyAttribute Character valueCharacter;\n  @EpoxyAttribute byte valuebByte;\n  @EpoxyAttribute Byte valueByteWrapper;\n  @EpoxyAttribute long valueLong;\n  @EpoxyAttribute Long valueLongWrapper;\n  @EpoxyAttribute double valueDouble;\n  @EpoxyAttribute Double valueDoubleWrapper;\n  @EpoxyAttribute float valueFloat;\n  @EpoxyAttribute Float valueFloatWrapper;\n  @EpoxyAttribute boolean valueBoolean;\n  @EpoxyAttribute Boolean valueBooleanWrapper;\n  @EpoxyAttribute int[] valueIntArray;\n  @EpoxyAttribute Object[] valueObjectArray;\n  @EpoxyAttribute String valueString;\n  @EpoxyAttribute Object valueObject;\n  @EpoxyAttribute List<String> valueList;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DataBindingModelWithAllFieldTypesNoValidation.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\n@EpoxyModelClass\npublic abstract class DataBindingModelWithAllFieldTypesNoValidation extends DataBindingEpoxyModel {\n  @EpoxyAttribute int valueInt;\n  @EpoxyAttribute Integer valueInteger;\n  @EpoxyAttribute short valueShort;\n  @EpoxyAttribute Short valueShortWrapper;\n  @EpoxyAttribute char valueChar;\n  @EpoxyAttribute Character valueCharacter;\n  @EpoxyAttribute byte valuebByte;\n  @EpoxyAttribute Byte valueByteWrapper;\n  @EpoxyAttribute long valueLong;\n  @EpoxyAttribute Long valueLongWrapper;\n  @EpoxyAttribute double valueDouble;\n  @EpoxyAttribute Double valueDoubleWrapper;\n  @EpoxyAttribute float valueFloat;\n  @EpoxyAttribute Float valueFloatWrapper;\n  @EpoxyAttribute boolean valueBoolean;\n  @EpoxyAttribute Boolean valueBooleanWrapper;\n  @EpoxyAttribute int[] valueIntArray;\n  @EpoxyAttribute Object[] valueObjectArray;\n  @EpoxyAttribute String valueString;\n  @EpoxyAttribute Object valueObject;\n  @EpoxyAttribute List<String> valueList;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DataBindingModelWithAllFieldTypesNoValidation_.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.databinding.ViewDataBinding;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DataBindingModelWithAllFieldTypesNoValidation_ extends DataBindingModelWithAllFieldTypesNoValidation implements GeneratedModel<DataBindingEpoxyModel.DataBindingHolder>, DataBindingModelWithAllFieldTypesNoValidationBuilder {\n  private OnModelBoundListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public DataBindingModelWithAllFieldTypesNoValidation_() {\n    super();\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DataBindingEpoxyModel.DataBindingHolder object, final int position) {\n  }\n\n  @Override\n  public void handlePostBind(final DataBindingEpoxyModel.DataBindingHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypesNoValidation_ onBind(\n      OnModelBoundListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DataBindingEpoxyModel.DataBindingHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypesNoValidation_ onUnbind(\n      OnModelUnboundListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypesNoValidation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypesNoValidation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypesNoValidation_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.valueInteger = valueInteger;\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return valueInteger;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueShort(short valueShort) {\n    onMutation();\n    super.valueShort = valueShort;\n    return this;\n  }\n\n  public short valueShort() {\n    return valueShort;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.valueShortWrapper = valueShortWrapper;\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueChar(char valueChar) {\n    onMutation();\n    super.valueChar = valueChar;\n    return this;\n  }\n\n  public char valueChar() {\n    return valueChar;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.valueCharacter = valueCharacter;\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return valueCharacter;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.valuebByte = valuebByte;\n    return this;\n  }\n\n  public byte valuebByte() {\n    return valuebByte;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.valueByteWrapper = valueByteWrapper;\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueLong(long valueLong) {\n    onMutation();\n    super.valueLong = valueLong;\n    return this;\n  }\n\n  public long valueLong() {\n    return valueLong;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.valueLongWrapper = valueLongWrapper;\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueDouble(double valueDouble) {\n    onMutation();\n    super.valueDouble = valueDouble;\n    return this;\n  }\n\n  public double valueDouble() {\n    return valueDouble;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueDoubleWrapper(\n      Double valueDoubleWrapper) {\n    onMutation();\n    super.valueDoubleWrapper = valueDoubleWrapper;\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueFloat(float valueFloat) {\n    onMutation();\n    super.valueFloat = valueFloat;\n    return this;\n  }\n\n  public float valueFloat() {\n    return valueFloat;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.valueFloatWrapper = valueFloatWrapper;\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.valueBoolean = valueBoolean;\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return valueBoolean;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueBooleanWrapper(\n      Boolean valueBooleanWrapper) {\n    onMutation();\n    super.valueBooleanWrapper = valueBooleanWrapper;\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.valueIntArray = valueIntArray;\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return valueIntArray;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueObjectArray(\n      Object[] valueObjectArray) {\n    onMutation();\n    super.valueObjectArray = valueObjectArray;\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueString(String valueString) {\n    onMutation();\n    super.valueString = valueString;\n    return this;\n  }\n\n  public String valueString() {\n    return valueString;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueObject(Object valueObject) {\n    onMutation();\n    super.valueObject = valueObject;\n    return this;\n  }\n\n  public Object valueObject() {\n    return valueObject;\n  }\n\n  public DataBindingModelWithAllFieldTypesNoValidation_ valueList(List<String> valueList) {\n    onMutation();\n    super.valueList = valueList;\n    return this;\n  }\n\n  public List<String> valueList() {\n    return valueList;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding) {\n    binding.setVariable(BR.valueInt, valueInt);\n    binding.setVariable(BR.valueInteger, valueInteger);\n    binding.setVariable(BR.valueShort, valueShort);\n    binding.setVariable(BR.valueShortWrapper, valueShortWrapper);\n    binding.setVariable(BR.valueChar, valueChar);\n    binding.setVariable(BR.valueCharacter, valueCharacter);\n    binding.setVariable(BR.valuebByte, valuebByte);\n    binding.setVariable(BR.valueByteWrapper, valueByteWrapper);\n    binding.setVariable(BR.valueLong, valueLong);\n    binding.setVariable(BR.valueLongWrapper, valueLongWrapper);\n    binding.setVariable(BR.valueDouble, valueDouble);\n    binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper);\n    binding.setVariable(BR.valueFloat, valueFloat);\n    binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper);\n    binding.setVariable(BR.valueBoolean, valueBoolean);\n    binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper);\n    binding.setVariable(BR.valueIntArray, valueIntArray);\n    binding.setVariable(BR.valueObjectArray, valueObjectArray);\n    binding.setVariable(BR.valueString, valueString);\n    binding.setVariable(BR.valueObject, valueObject);\n    binding.setVariable(BR.valueList, valueList);\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DataBindingModelWithAllFieldTypesNoValidation_)) {\n      setDataBindingVariables(binding);\n      return;\n    }\n    DataBindingModelWithAllFieldTypesNoValidation_ that = (DataBindingModelWithAllFieldTypesNoValidation_) previousModel;\n    if ((valueInt != that.valueInt)) {\n      binding.setVariable(BR.valueInt, valueInt);\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      binding.setVariable(BR.valueInteger, valueInteger);\n    }\n    if ((valueShort != that.valueShort)) {\n      binding.setVariable(BR.valueShort, valueShort);\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      binding.setVariable(BR.valueShortWrapper, valueShortWrapper);\n    }\n    if ((valueChar != that.valueChar)) {\n      binding.setVariable(BR.valueChar, valueChar);\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      binding.setVariable(BR.valueCharacter, valueCharacter);\n    }\n    if ((valuebByte != that.valuebByte)) {\n      binding.setVariable(BR.valuebByte, valuebByte);\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      binding.setVariable(BR.valueByteWrapper, valueByteWrapper);\n    }\n    if ((valueLong != that.valueLong)) {\n      binding.setVariable(BR.valueLong, valueLong);\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      binding.setVariable(BR.valueLongWrapper, valueLongWrapper);\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      binding.setVariable(BR.valueDouble, valueDouble);\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper);\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      binding.setVariable(BR.valueFloat, valueFloat);\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper);\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      binding.setVariable(BR.valueBoolean, valueBoolean);\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper);\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      binding.setVariable(BR.valueIntArray, valueIntArray);\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      binding.setVariable(BR.valueObjectArray, valueObjectArray);\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      binding.setVariable(BR.valueString, valueString);\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      binding.setVariable(BR.valueObject, valueObject);\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      binding.setVariable(BR.valueList, valueList);\n    }\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypesNoValidation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.valueInteger = null;\n    super.valueShort = (short) 0;\n    super.valueShortWrapper = null;\n    super.valueChar = (char) 0;\n    super.valueCharacter = null;\n    super.valuebByte = (byte) 0;\n    super.valueByteWrapper = null;\n    super.valueLong = 0L;\n    super.valueLongWrapper = null;\n    super.valueDouble = 0.0d;\n    super.valueDoubleWrapper = null;\n    super.valueFloat = 0.0f;\n    super.valueFloatWrapper = null;\n    super.valueBoolean = false;\n    super.valueBooleanWrapper = null;\n    super.valueIntArray = null;\n    super.valueObjectArray = null;\n    super.valueString = null;\n    super.valueObject = null;\n    super.valueList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DataBindingModelWithAllFieldTypesNoValidation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DataBindingModelWithAllFieldTypesNoValidation_ that = (DataBindingModelWithAllFieldTypesNoValidation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      return false;\n    }\n    if ((valueShort != that.valueShort)) {\n      return false;\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      return false;\n    }\n    if ((valueChar != that.valueChar)) {\n      return false;\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      return false;\n    }\n    if ((valuebByte != that.valuebByte)) {\n      return false;\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      return false;\n    }\n    if ((valueLong != that.valueLong)) {\n      return false;\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      return false;\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      return false;\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      return false;\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      return false;\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      return false;\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      return false;\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      return false;\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      return false;\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      return false;\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      return false;\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      return false;\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + (valueInteger != null ? valueInteger.hashCode() : 0);\n    _result = 31 * _result + valueShort;\n    _result = 31 * _result + (valueShortWrapper != null ? valueShortWrapper.hashCode() : 0);\n    _result = 31 * _result + valueChar;\n    _result = 31 * _result + (valueCharacter != null ? valueCharacter.hashCode() : 0);\n    _result = 31 * _result + valuebByte;\n    _result = 31 * _result + (valueByteWrapper != null ? valueByteWrapper.hashCode() : 0);\n    _result = 31 * _result + (int) (valueLong ^ (valueLong >>> 32));\n    _result = 31 * _result + (valueLongWrapper != null ? valueLongWrapper.hashCode() : 0);\n    temp = Double.doubleToLongBits(valueDouble);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (valueDoubleWrapper != null ? valueDoubleWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueFloat != +0.0f ? Float.floatToIntBits(valueFloat) : 0);\n    _result = 31 * _result + (valueFloatWrapper != null ? valueFloatWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueBoolean ? 1 : 0);\n    _result = 31 * _result + (valueBooleanWrapper != null ? valueBooleanWrapper.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(valueIntArray);\n    _result = 31 * _result + Arrays.hashCode(valueObjectArray);\n    _result = 31 * _result + (valueString != null ? valueString.hashCode() : 0);\n    _result = 31 * _result + (valueObject != null ? valueObject.hashCode() : 0);\n    _result = 31 * _result + (valueList != null ? valueList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DataBindingModelWithAllFieldTypesNoValidation_{\" +\n        \"valueInt=\" + valueInt +\n        \", valueInteger=\" + valueInteger +\n        \", valueShort=\" + valueShort +\n        \", valueShortWrapper=\" + valueShortWrapper +\n        \", valueChar=\" + valueChar +\n        \", valueCharacter=\" + valueCharacter +\n        \", valuebByte=\" + valuebByte +\n        \", valueByteWrapper=\" + valueByteWrapper +\n        \", valueLong=\" + valueLong +\n        \", valueLongWrapper=\" + valueLongWrapper +\n        \", valueDouble=\" + valueDouble +\n        \", valueDoubleWrapper=\" + valueDoubleWrapper +\n        \", valueFloat=\" + valueFloat +\n        \", valueFloatWrapper=\" + valueFloatWrapper +\n        \", valueBoolean=\" + valueBoolean +\n        \", valueBooleanWrapper=\" + valueBooleanWrapper +\n        \", valueIntArray=\" + valueIntArray +\n        \", valueObjectArray=\" + valueObjectArray +\n        \", valueString=\" + valueString +\n        \", valueObject=\" + valueObject +\n        \", valueList=\" + valueList +\n        \"}\" + super.toString();\n  }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DataBindingModelWithAllFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.databinding.ViewDataBinding;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DataBindingModelWithAllFieldTypes_ extends DataBindingModelWithAllFieldTypes implements GeneratedModel<DataBindingEpoxyModel.DataBindingHolder>, DataBindingModelWithAllFieldTypesBuilder {\n  private OnModelBoundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public DataBindingModelWithAllFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DataBindingEpoxyModel.DataBindingHolder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final DataBindingEpoxyModel.DataBindingHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypes_ onBind(\n      OnModelBoundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DataBindingEpoxyModel.DataBindingHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypes_ onUnbind(\n      OnModelUnboundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.valueInteger = valueInteger;\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return valueInteger;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.valueShort = valueShort;\n    return this;\n  }\n\n  public short valueShort() {\n    return valueShort;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.valueShortWrapper = valueShortWrapper;\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.valueChar = valueChar;\n    return this;\n  }\n\n  public char valueChar() {\n    return valueChar;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.valueCharacter = valueCharacter;\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return valueCharacter;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.valuebByte = valuebByte;\n    return this;\n  }\n\n  public byte valuebByte() {\n    return valuebByte;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.valueByteWrapper = valueByteWrapper;\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.valueLong = valueLong;\n    return this;\n  }\n\n  public long valueLong() {\n    return valueLong;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.valueLongWrapper = valueLongWrapper;\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.valueDouble = valueDouble;\n    return this;\n  }\n\n  public double valueDouble() {\n    return valueDouble;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.valueDoubleWrapper = valueDoubleWrapper;\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.valueFloat = valueFloat;\n    return this;\n  }\n\n  public float valueFloat() {\n    return valueFloat;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.valueFloatWrapper = valueFloatWrapper;\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.valueBoolean = valueBoolean;\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return valueBoolean;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.valueBooleanWrapper = valueBooleanWrapper;\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.valueIntArray = valueIntArray;\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return valueIntArray;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.valueObjectArray = valueObjectArray;\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.valueString = valueString;\n    return this;\n  }\n\n  public String valueString() {\n    return valueString;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.valueObject = valueObject;\n    return this;\n  }\n\n  public Object valueObject() {\n    return valueObject;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.valueList = valueList;\n    return this;\n  }\n\n  public List<String> valueList() {\n    return valueList;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding) {\n    if (!binding.setVariable(BR.valueInt, valueInt)) {\n      throw new IllegalStateException(\"The attribute valueInt was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueInteger, valueInteger)) {\n      throw new IllegalStateException(\"The attribute valueInteger was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueShort, valueShort)) {\n      throw new IllegalStateException(\"The attribute valueShort was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueShortWrapper, valueShortWrapper)) {\n      throw new IllegalStateException(\"The attribute valueShortWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueChar, valueChar)) {\n      throw new IllegalStateException(\"The attribute valueChar was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueCharacter, valueCharacter)) {\n      throw new IllegalStateException(\"The attribute valueCharacter was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valuebByte, valuebByte)) {\n      throw new IllegalStateException(\"The attribute valuebByte was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueByteWrapper, valueByteWrapper)) {\n      throw new IllegalStateException(\"The attribute valueByteWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueLong, valueLong)) {\n      throw new IllegalStateException(\"The attribute valueLong was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueLongWrapper, valueLongWrapper)) {\n      throw new IllegalStateException(\"The attribute valueLongWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueDouble, valueDouble)) {\n      throw new IllegalStateException(\"The attribute valueDouble was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper)) {\n      throw new IllegalStateException(\"The attribute valueDoubleWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueFloat, valueFloat)) {\n      throw new IllegalStateException(\"The attribute valueFloat was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper)) {\n      throw new IllegalStateException(\"The attribute valueFloatWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueBoolean, valueBoolean)) {\n      throw new IllegalStateException(\"The attribute valueBoolean was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper)) {\n      throw new IllegalStateException(\"The attribute valueBooleanWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueIntArray, valueIntArray)) {\n      throw new IllegalStateException(\"The attribute valueIntArray was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueObjectArray, valueObjectArray)) {\n      throw new IllegalStateException(\"The attribute valueObjectArray was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueString, valueString)) {\n      throw new IllegalStateException(\"The attribute valueString was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueObject, valueObject)) {\n      throw new IllegalStateException(\"The attribute valueObject was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueList, valueList)) {\n      throw new IllegalStateException(\"The attribute valueList was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DataBindingModelWithAllFieldTypes_)) {\n      setDataBindingVariables(binding);\n      return;\n    }\n    DataBindingModelWithAllFieldTypes_ that = (DataBindingModelWithAllFieldTypes_) previousModel;\n    if ((valueInt != that.valueInt)) {\n      binding.setVariable(BR.valueInt, valueInt);\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      binding.setVariable(BR.valueInteger, valueInteger);\n    }\n    if ((valueShort != that.valueShort)) {\n      binding.setVariable(BR.valueShort, valueShort);\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      binding.setVariable(BR.valueShortWrapper, valueShortWrapper);\n    }\n    if ((valueChar != that.valueChar)) {\n      binding.setVariable(BR.valueChar, valueChar);\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      binding.setVariable(BR.valueCharacter, valueCharacter);\n    }\n    if ((valuebByte != that.valuebByte)) {\n      binding.setVariable(BR.valuebByte, valuebByte);\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      binding.setVariable(BR.valueByteWrapper, valueByteWrapper);\n    }\n    if ((valueLong != that.valueLong)) {\n      binding.setVariable(BR.valueLong, valueLong);\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      binding.setVariable(BR.valueLongWrapper, valueLongWrapper);\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      binding.setVariable(BR.valueDouble, valueDouble);\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper);\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      binding.setVariable(BR.valueFloat, valueFloat);\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper);\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      binding.setVariable(BR.valueBoolean, valueBoolean);\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper);\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      binding.setVariable(BR.valueIntArray, valueIntArray);\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      binding.setVariable(BR.valueObjectArray, valueObjectArray);\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      binding.setVariable(BR.valueString, valueString);\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      binding.setVariable(BR.valueObject, valueObject);\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      binding.setVariable(BR.valueList, valueList);\n    }\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.valueInteger = null;\n    super.valueShort = (short) 0;\n    super.valueShortWrapper = null;\n    super.valueChar = (char) 0;\n    super.valueCharacter = null;\n    super.valuebByte = (byte) 0;\n    super.valueByteWrapper = null;\n    super.valueLong = 0L;\n    super.valueLongWrapper = null;\n    super.valueDouble = 0.0d;\n    super.valueDoubleWrapper = null;\n    super.valueFloat = 0.0f;\n    super.valueFloatWrapper = null;\n    super.valueBoolean = false;\n    super.valueBooleanWrapper = null;\n    super.valueIntArray = null;\n    super.valueObjectArray = null;\n    super.valueString = null;\n    super.valueObject = null;\n    super.valueList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DataBindingModelWithAllFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DataBindingModelWithAllFieldTypes_ that = (DataBindingModelWithAllFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      return false;\n    }\n    if ((valueShort != that.valueShort)) {\n      return false;\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      return false;\n    }\n    if ((valueChar != that.valueChar)) {\n      return false;\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      return false;\n    }\n    if ((valuebByte != that.valuebByte)) {\n      return false;\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      return false;\n    }\n    if ((valueLong != that.valueLong)) {\n      return false;\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      return false;\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      return false;\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      return false;\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      return false;\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      return false;\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      return false;\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      return false;\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      return false;\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      return false;\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      return false;\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      return false;\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + (valueInteger != null ? valueInteger.hashCode() : 0);\n    _result = 31 * _result + valueShort;\n    _result = 31 * _result + (valueShortWrapper != null ? valueShortWrapper.hashCode() : 0);\n    _result = 31 * _result + valueChar;\n    _result = 31 * _result + (valueCharacter != null ? valueCharacter.hashCode() : 0);\n    _result = 31 * _result + valuebByte;\n    _result = 31 * _result + (valueByteWrapper != null ? valueByteWrapper.hashCode() : 0);\n    _result = 31 * _result + (int) (valueLong ^ (valueLong >>> 32));\n    _result = 31 * _result + (valueLongWrapper != null ? valueLongWrapper.hashCode() : 0);\n    temp = Double.doubleToLongBits(valueDouble);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (valueDoubleWrapper != null ? valueDoubleWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueFloat != +0.0f ? Float.floatToIntBits(valueFloat) : 0);\n    _result = 31 * _result + (valueFloatWrapper != null ? valueFloatWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueBoolean ? 1 : 0);\n    _result = 31 * _result + (valueBooleanWrapper != null ? valueBooleanWrapper.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(valueIntArray);\n    _result = 31 * _result + Arrays.hashCode(valueObjectArray);\n    _result = 31 * _result + (valueString != null ? valueString.hashCode() : 0);\n    _result = 31 * _result + (valueObject != null ? valueObject.hashCode() : 0);\n    _result = 31 * _result + (valueList != null ? valueList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DataBindingModelWithAllFieldTypes_{\" +\n        \"valueInt=\" + valueInt +\n        \", valueInteger=\" + valueInteger +\n        \", valueShort=\" + valueShort +\n        \", valueShortWrapper=\" + valueShortWrapper +\n        \", valueChar=\" + valueChar +\n        \", valueCharacter=\" + valueCharacter +\n        \", valuebByte=\" + valuebByte +\n        \", valueByteWrapper=\" + valueByteWrapper +\n        \", valueLong=\" + valueLong +\n        \", valueLongWrapper=\" + valueLongWrapper +\n        \", valueDouble=\" + valueDouble +\n        \", valueDoubleWrapper=\" + valueDoubleWrapper +\n        \", valueFloat=\" + valueFloat +\n        \", valueFloatWrapper=\" + valueFloatWrapper +\n        \", valueBoolean=\" + valueBoolean +\n        \", valueBooleanWrapper=\" + valueBooleanWrapper +\n        \", valueIntArray=\" + valueIntArray +\n        \", valueObjectArray=\" + valueObjectArray +\n        \", valueString=\" + valueString +\n        \", valueObject=\" + valueObject +\n        \", valueList=\" + valueList +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DefaultPackageLayoutPatternViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DefaultPackageLayoutPatternViewModel_ extends EpoxyModel<DefaultPackageLayoutPatternView> implements GeneratedModel<DefaultPackageLayoutPatternView>, DefaultPackageLayoutPatternViewModelBuilder {\n  private OnModelBoundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DefaultPackageLayoutPatternView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final DefaultPackageLayoutPatternView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final DefaultPackageLayoutPatternView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DefaultPackageLayoutPatternViewModel_)) {\n      bind(object);\n      return;\n    }\n    DefaultPackageLayoutPatternViewModel_ that = (DefaultPackageLayoutPatternViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final DefaultPackageLayoutPatternView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DefaultPackageLayoutPatternViewModel_ onBind(\n      OnModelBoundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DefaultPackageLayoutPatternView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DefaultPackageLayoutPatternViewModel_ onUnbind(\n      OnModelUnboundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DefaultPackageLayoutPatternView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DefaultPackageLayoutPatternViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DefaultPackageLayoutPatternView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DefaultPackageLayoutPatternViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.default_package_layout_pattern_view;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DefaultPackageLayoutPatternViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DefaultPackageLayoutPatternViewModel_ that = (DefaultPackageLayoutPatternViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DefaultPackageLayoutPatternViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DoNotHashView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class DoNotHashView extends View {\n\n  public DoNotHashView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = Option.DoNotHash)\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @ModelProp(options = Option.DoNotHash)\n  public void setClickListener(View.OnClickListener title) {\n\n  }\n\n  @ModelProp\n  public void normalProp(CharSequence title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/DoNotHashViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DoNotHashViewModel_ extends EpoxyModel<DoNotHashView> implements GeneratedModel<DoNotHashView>, DoNotHashViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(3);\n\n  private OnModelBoundListener<DoNotHashViewModel_, DoNotHashView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DoNotHashViewModel_, DoNotHashView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DoNotHashViewModel_, DoNotHashView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DoNotHashViewModel_, DoNotHashView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence normalProp_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for normalProp\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final DoNotHashView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final DoNotHashView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setTitle(title_CharSequence);\n    object.normalProp(normalProp_CharSequence);\n  }\n\n  @Override\n  public void bind(final DoNotHashView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DoNotHashViewModel_)) {\n      bind(object);\n      return;\n    }\n    DoNotHashViewModel_ that = (DoNotHashViewModel_) previousModel;\n    super.bind(object);\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if (((title_CharSequence == null) != (that.title_CharSequence == null))) {\n      object.setTitle(title_CharSequence);\n    }\n\n    if ((normalProp_CharSequence != null ? !normalProp_CharSequence.equals(that.normalProp_CharSequence) : that.normalProp_CharSequence != null)) {\n      object.normalProp(normalProp_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final DoNotHashView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DoNotHashViewModel_ onBind(\n      OnModelBoundListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DoNotHashView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DoNotHashViewModel_ onUnbind(\n      OnModelUnboundListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final DoNotHashView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DoNotHashViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DoNotHashView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DoNotHashViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#setTitle(CharSequence)\n   */\n  public DoNotHashViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public DoNotHashViewModel_ clickListener(\n      @NonNull final OnModelClickListener<DoNotHashViewModel_, DoNotHashView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#setClickListener(View.OnClickListener)\n   */\n  public DoNotHashViewModel_ clickListener(@NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#normalProp(CharSequence)\n   */\n  public DoNotHashViewModel_ normalProp(@NonNull CharSequence normalProp) {\n    if (normalProp == null) {\n      throw new IllegalArgumentException(\"normalProp cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.normalProp_CharSequence = normalProp;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence normalProp() {\n    return normalProp_CharSequence;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public DoNotHashViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    this.clickListener_OnClickListener = null;\n    this.normalProp_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DoNotHashViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DoNotHashViewModel_ that = (DoNotHashViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((title_CharSequence == null) != (that.title_CharSequence == null))) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((normalProp_CharSequence != null ? !normalProp_CharSequence.equals(that.normalProp_CharSequence) : that.normalProp_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (normalProp_CharSequence != null ? normalProp_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DoNotHashViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", normalProp_CharSequence=\" + normalProp_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/EpoxyModelGroupWithAnnotations.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.Collection;\n\n@EpoxyModelClass\npublic class EpoxyModelGroupWithAnnotations extends EpoxyModelGroup {\n\n  public EpoxyModelGroupWithAnnotations(int layoutRes, Collection<? extends EpoxyModel<?>> models) {\n    super(layoutRes, models);\n  }\n\n  @EpoxyAttribute int value;\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/EpoxyModelGroupWithAnnotations_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.Collection;\n\n/**\n * Generated file. Do not modify!\n */\npublic class EpoxyModelGroupWithAnnotations_ extends EpoxyModelGroupWithAnnotations implements GeneratedModel<ModelGroupHolder>, EpoxyModelGroupWithAnnotationsBuilder {\n  private OnModelBoundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public EpoxyModelGroupWithAnnotations_(int layoutRes,\n      Collection<? extends EpoxyModel<?>> models) {\n    super(layoutRes, models);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelGroupHolder object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final ModelGroupHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public EpoxyModelGroupWithAnnotations_ onBind(\n      OnModelBoundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelGroupHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public EpoxyModelGroupWithAnnotations_ onUnbind(\n      OnModelUnboundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelGroupHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public EpoxyModelGroupWithAnnotations_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelGroupHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public EpoxyModelGroupWithAnnotations_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public EpoxyModelGroupWithAnnotations_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ shouldSaveViewState(boolean shouldSaveViewState) {\n    super.shouldSaveViewState(shouldSaveViewState);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof EpoxyModelGroupWithAnnotations_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    EpoxyModelGroupWithAnnotations_ that = (EpoxyModelGroupWithAnnotations_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"EpoxyModelGroupWithAnnotations_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethod.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass(layout = 1)\npublic abstract class GenerateDefaultLayoutMethod extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodNextParentLayout$NoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.NoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_NoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$NoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$NoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$NoLayout_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.StillNoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_StillNoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ layout(\n      @LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodNextParentLayout$WithLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.WithLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_WithLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$WithLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$WithLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$WithLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodNextParentLayout.java",
    "content": "package com.airbnb.epoxy;\n\npublic class GenerateDefaultLayoutMethodNextParentLayout {\n\n  @EpoxyModelClass\n  public static abstract class NoLayout extends WithLayout {\n    @EpoxyAttribute int value;\n  }\n\n  @EpoxyModelClass\n  public static abstract class StillNoLayout extends WithLayout {\n\n  }\n\n  @EpoxyModelClass(layout = 1)\n  public static abstract class WithLayout extends EpoxyModel<Object> {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodNoLayout.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass\npublic abstract class GenerateDefaultLayoutMethodNoLayout extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodParentLayout$NoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodParentLayout$NoLayout_ extends GenerateDefaultLayoutMethodParentLayout.NoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodParentLayout_NoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodParentLayout$NoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodParentLayout$NoLayout_ that = (GenerateDefaultLayoutMethodParentLayout$NoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodParentLayout$NoLayout_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodParentLayout$WithLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodParentLayout$WithLayout_ extends GenerateDefaultLayoutMethodParentLayout.WithLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodParentLayout_WithLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodParentLayout$WithLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodParentLayout$WithLayout_ that = (GenerateDefaultLayoutMethodParentLayout$WithLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodParentLayout$WithLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodParentLayout.java",
    "content": "package com.airbnb.epoxy;\n\npublic class GenerateDefaultLayoutMethodParentLayout {\n\n  @EpoxyModelClass\n  public static abstract class NoLayout extends WithLayout {\n    @EpoxyAttribute int value;\n  }\n\n  @EpoxyModelClass(layout = 1)\n  public static abstract class WithLayout extends EpoxyModel<Object> {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethodParentStillNoLayout.java",
    "content": "package com.airbnb.epoxy;\n\npublic class GenerateDefaultLayoutMethodParentStillNoLayout {\n\n  @EpoxyModelClass\n  public static abstract class NoLayout extends StillNoLayout {\n    @EpoxyAttribute int value;\n  }\n\n  @EpoxyModelClass\n  public static abstract class StillNoLayout extends EpoxyModel<Object> {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GenerateDefaultLayoutMethod_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethod_ extends GenerateDefaultLayoutMethod implements GeneratedModel<Object>, GenerateDefaultLayoutMethodBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethod_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethod_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethod_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethod_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethod_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethod_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethod_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethod_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethod_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethod_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethod_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethod_ that = (GenerateDefaultLayoutMethod_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethod_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GeneratedModelSuffixViewSuffix_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GeneratedModelSuffixViewSuffix_ extends EpoxyModel<GeneratedModelSuffixView> implements GeneratedModel<GeneratedModelSuffixView>, GeneratedModelSuffixViewSuffixBuilder {\n  private OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final GeneratedModelSuffixView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GeneratedModelSuffixView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final GeneratedModelSuffixView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof GeneratedModelSuffixViewSuffix_)) {\n      bind(object);\n      return;\n    }\n    GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final GeneratedModelSuffixView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GeneratedModelSuffixViewSuffix_ onBind(\n      OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GeneratedModelSuffixView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GeneratedModelSuffixViewSuffix_ onUnbind(\n      OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final GeneratedModelSuffixView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GeneratedModelSuffixViewSuffix_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final GeneratedModelSuffixView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GeneratedModelSuffixViewSuffix_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.generated_model_suffix_view;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GeneratedModelSuffixViewSuffix_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GeneratedModelSuffixViewSuffix_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GridSpanCountView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1, fullSpan = false)\npublic class GridSpanCountView extends View {\n\n  public GridSpanCountView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setClickListener(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/GridSpanCountViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GridSpanCountViewModel_ extends EpoxyModel<GridSpanCountView> implements GeneratedModel<GridSpanCountView>, GridSpanCountViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<GridSpanCountViewModel_, GridSpanCountView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GridSpanCountViewModel_, GridSpanCountView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GridSpanCountViewModel_, GridSpanCountView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GridSpanCountViewModel_, GridSpanCountView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final GridSpanCountView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GridSpanCountView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final GridSpanCountView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof GridSpanCountViewModel_)) {\n      bind(object);\n      return;\n    }\n    GridSpanCountViewModel_ that = (GridSpanCountViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GridSpanCountView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GridSpanCountViewModel_ onBind(\n      OnModelBoundListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GridSpanCountView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GridSpanCountViewModel_ onUnbind(\n      OnModelUnboundListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final GridSpanCountView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GridSpanCountViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final GridSpanCountView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GridSpanCountViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GridSpanCountView#setClickListener(String)\n   */\n  public GridSpanCountViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GridSpanCountViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GridSpanCountViewModel_ that = (GridSpanCountViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GridSpanCountViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/IgnoreRequireHashCodeView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class IgnoreRequireHashCodeView extends View {\n\n  public IgnoreRequireHashCodeView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = Option.IgnoreRequireHashCode)\n  public void setClickListener(View.OnClickListener title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/IgnoreRequireHashCodeViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class IgnoreRequireHashCodeViewModel_ extends EpoxyModel<IgnoreRequireHashCodeView> implements GeneratedModel<IgnoreRequireHashCodeView>, IgnoreRequireHashCodeViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final IgnoreRequireHashCodeView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final IgnoreRequireHashCodeView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final IgnoreRequireHashCodeView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof IgnoreRequireHashCodeViewModel_)) {\n      bind(object);\n      return;\n    }\n    IgnoreRequireHashCodeViewModel_ that = (IgnoreRequireHashCodeViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_OnClickListener != null ? !clickListener_OnClickListener.equals(that.clickListener_OnClickListener) : that.clickListener_OnClickListener != null)) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final IgnoreRequireHashCodeView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public IgnoreRequireHashCodeViewModel_ onBind(\n      OnModelBoundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(IgnoreRequireHashCodeView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public IgnoreRequireHashCodeViewModel_ onUnbind(\n      OnModelUnboundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final IgnoreRequireHashCodeView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public IgnoreRequireHashCodeViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final IgnoreRequireHashCodeView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public IgnoreRequireHashCodeViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public IgnoreRequireHashCodeViewModel_ clickListener(\n      @NonNull final OnModelClickListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see IgnoreRequireHashCodeView#setClickListener(View.OnClickListener)\n   */\n  public IgnoreRequireHashCodeViewModel_ clickListener(\n      @NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof IgnoreRequireHashCodeViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    IgnoreRequireHashCodeViewModel_ that = (IgnoreRequireHashCodeViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_OnClickListener != null ? !clickListener_OnClickListener.equals(that.clickListener_OnClickListener) : that.clickListener_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? clickListener_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"IgnoreRequireHashCodeViewModel_{\" +\n        \"clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/LayoutOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class LayoutOverloadsViewModel_ extends EpoxyModel<LayoutOverloadsView> implements GeneratedModel<LayoutOverloadsView>, LayoutOverloadsViewModelBuilder {\n  private OnModelBoundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final LayoutOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final LayoutOverloadsView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final LayoutOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof LayoutOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    LayoutOverloadsViewModel_ that = (LayoutOverloadsViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final LayoutOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public LayoutOverloadsViewModel_ onBind(\n      OnModelBoundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(LayoutOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public LayoutOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final LayoutOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public LayoutOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final LayoutOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public LayoutOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.layout_overloads_view;\n  }\n\n  public LayoutOverloadsViewModel_ withOneLayout() {\n    layout(R.layout.layout_overloads_view_one);\n    return this;\n  }\n\n  public LayoutOverloadsViewModel_ withTwoLayout() {\n    layout(R.layout.layout_overloads_view_two);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof LayoutOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    LayoutOverloadsViewModel_ that = (LayoutOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"LayoutOverloadsViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelAsInnerClass.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelAsInnerClass {\n\n  class InnerClass extends EpoxyModel<Object> {\n    @EpoxyAttribute int valueInt;\n\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelConfigRequireHashCodeAllowsMarkedAttributes.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelConfigRequireHashCodeAllowsMarkedAttributes extends EpoxyModel<Object> {\n\n  public static class ClassWithoutHashCode {\n\n  }\n\n  @EpoxyAttribute(Option.IgnoreRequireHashCode) ClassWithoutHashCode classWithoutHashCode;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelConfigRequireHashCodeCharSequencePasses.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelConfigRequireHashCodeCharSequencePasses extends EpoxyModel<Object> {\n\n  @EpoxyAttribute CharSequence charSequence;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelConfigRequireHashCodeInterfaceWithHashCodePasses.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelConfigRequireHashCodeInterfaceWithHashCodePasses extends EpoxyModel<Object> {\n\n  interface MyInterface {\n    int hashCode();\n  }\n\n  @EpoxyAttribute MyInterface myInterfaceImplementation;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelConfigSubPackageOverridesParent.java",
    "content": "package com.airbnb.epoxy.configtest.sub;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelConfigSubPackageOverridesParent extends EpoxyModel<Object> {\n\n  public static class ClassWithoutHashCode {\n\n  }\n\n  @EpoxyAttribute ClassWithoutHashCode classWithoutHashCode;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelDoNotHash.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\npublic class ModelDoNotHash extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n  @EpoxyAttribute({Option.DoNotHash}) int value2;\n  @EpoxyAttribute({Option.DoNotHash}) String value3;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelDoNotHash_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelDoNotHash_ extends ModelDoNotHash implements GeneratedModel<Object>, ModelDoNotHashBuilder {\n  private OnModelBoundListener<ModelDoNotHash_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelDoNotHash_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelDoNotHash_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelDoNotHash_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelDoNotHash_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotHash_ onBind(OnModelBoundListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotHash_ onUnbind(OnModelUnboundListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotHash_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotHash_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelDoNotHash_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelDoNotHash_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelDoNotHash_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelDoNotHash_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelDoNotHash_ that = (ModelDoNotHash_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if (((value3 == null) != (that.value3 == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + (value3 != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelDoNotHash_{\" +\n        \"value=\" + value +\n        \", value2=\" + value2 +\n        \", value3=\" + value3 +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelDoNotUseInToString.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\npublic class ModelDoNotUseInToString extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n  @EpoxyAttribute({Option.DoNotUseInToString}) int value2;\n  @EpoxyAttribute({Option.DoNotUseInToString}) String value3;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelDoNotUseInToString_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelDoNotUseInToString_ extends ModelDoNotUseInToString implements GeneratedModel<Object>, ModelDoNotUseInToStringBuilder {\n  private OnModelBoundListener<ModelDoNotUseInToString_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelDoNotUseInToString_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelDoNotUseInToString_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelDoNotUseInToString_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelDoNotUseInToString_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotUseInToString_ onBind(\n      OnModelBoundListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotUseInToString_ onUnbind(\n      OnModelUnboundListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotUseInToString_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotUseInToString_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelDoNotUseInToString_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelDoNotUseInToString_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelDoNotUseInToString_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelDoNotUseInToString_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelDoNotUseInToString_ that = (ModelDoNotUseInToString_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if ((value2 != that.value2)) {\n      return false;\n    }\n    if ((value3 != null ? !value3.equals(that.value3) : that.value3 != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + value2;\n    _result = 31 * _result + (value3 != null ? value3.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelDoNotUseInToString_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelForRProcessingTest.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass(layout = R.layout.res)\npublic abstract class ModelForRProcessingTest extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelForRProcessingTest_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelForRProcessingTest_ extends ModelForRProcessingTest implements GeneratedModel<Object>, ModelForRProcessingTestBuilder {\n  private OnModelBoundListener<ModelForRProcessingTest_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelForRProcessingTest_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelForRProcessingTest_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelForRProcessingTest_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelForRProcessingTest_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForRProcessingTest_ onBind(\n      OnModelBoundListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForRProcessingTest_ onUnbind(\n      OnModelUnboundListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForRProcessingTest_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForRProcessingTest_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelForRProcessingTest_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.res;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelForRProcessingTest_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelForRProcessingTest_ that = (ModelForRProcessingTest_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelForRProcessingTest_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelForTestingDuplicateRValues.java",
    "content": "package com.airbnb.epoxy;\n\nimport com.airbnb.epoxy.othermodule.R;\n\n@EpoxyModelClass(layout = R.layout.res_in_other_module)\npublic abstract class ModelForTestingDuplicateRValues extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelForTestingDuplicateRValues_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.epoxy.othermodule.R;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelForTestingDuplicateRValues_ extends ModelForTestingDuplicateRValues implements GeneratedModel<Object>, ModelForTestingDuplicateRValuesBuilder {\n  private OnModelBoundListener<ModelForTestingDuplicateRValues_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelForTestingDuplicateRValues_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelForTestingDuplicateRValues_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelForTestingDuplicateRValues_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelForTestingDuplicateRValues_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForTestingDuplicateRValues_ onBind(\n      OnModelBoundListener<ModelForTestingDuplicateRValues_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForTestingDuplicateRValues_ onUnbind(\n      OnModelUnboundListener<ModelForTestingDuplicateRValues_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForTestingDuplicateRValues_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelForTestingDuplicateRValues_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForTestingDuplicateRValues_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelForTestingDuplicateRValues_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelForTestingDuplicateRValues_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.res_in_other_module;\n  }\n\n  @Override\n  public ModelForTestingDuplicateRValues_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelForTestingDuplicateRValues_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelForTestingDuplicateRValues_ that = (ModelForTestingDuplicateRValues_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelForTestingDuplicateRValues_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelNoValidation.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelNoValidation extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelNoValidation_.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelNoValidation_ extends ModelNoValidation implements GeneratedModel<Object>, ModelNoValidationBuilder {\n  private OnModelBoundListener<ModelNoValidation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelNoValidation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelNoValidation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelNoValidation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelNoValidation_() {\n    super();\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelNoValidation_ onBind(OnModelBoundListener<ModelNoValidation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelNoValidation_ onUnbind(OnModelUnboundListener<ModelNoValidation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelNoValidation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelNoValidation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelNoValidation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelNoValidation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelNoValidation_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelNoValidation_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelNoValidation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelNoValidation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelNoValidation_ that = (ModelNoValidation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelNoValidation_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelPackageWithNoConfigInheritsNearestParentConfig.java",
    "content": "package com.airbnb.epoxy.configtest.sub.sub;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelPackageWithNoConfigInheritsNearestParentConfig extends EpoxyModel<Object> {\n\n  public static class ClassWithoutHashCode {\n\n  }\n\n  @EpoxyAttribute ClassWithoutHashCode classWithoutHashCode;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelProcessorTest/testKotlinModel/Model.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\nimport androidx.annotation.DrawableRes\n\n@EpoxyModelClass\nabstract class Model : EpoxyModelWithHolder<Model.Holder>() {\n    @EpoxyAttribute @DrawableRes\n    var imageRes: Int = 0\n\n    @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)\n    var clickListener: View.OnClickListener? = null\n\n    override fun getDefaultLayout(): Int = 0\n\n    override fun bind(holder: Holder) {\n    }\n\n    override fun unbind(holder: Holder) {\n    }\n\n    class Holder : EpoxyHolder() {\n        override fun bindView(itemView: View) {\n\n        }\n    }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelProcessorTest/testKotlinModel/Model_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class Model_ extends Model implements GeneratedModel<Model.Holder>, ModelBuilder {\n  private OnModelBoundListener<Model_, Model.Holder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<Model_, Model.Holder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<Model_, Model.Holder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<Model_, Model.Holder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public Model_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Model.Holder object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Model.Holder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public Model_ onBind(OnModelBoundListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Model.Holder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public Model_ onUnbind(OnModelUnboundListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Model.Holder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public Model_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Model.Holder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public Model_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public Model_ imageRes(@DrawableRes int imageRes) {\n    onMutation();\n    super.setImageRes(imageRes);\n    return this;\n  }\n\n  @DrawableRes\n  public int imageRes() {\n    return super.getImageRes();\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public Model_ clickListener(final OnModelClickListener<Model_, Model.Holder> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.setClickListener(null);\n    }\n    else {\n      super.setClickListener(new WrappedEpoxyModelClickListener<>(clickListener));\n    }\n    return this;\n  }\n\n  public Model_ clickListener(View.OnClickListener clickListener) {\n    onMutation();\n    super.setClickListener(clickListener);\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return super.getClickListener();\n  }\n\n  @Override\n  public Model_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public Model_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public Model_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public Model_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public Model_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public Model_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public Model_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected Model.Holder createNewHolder(ViewParent parent) {\n    return new Model.Holder();\n  }\n\n  @Override\n  public Model_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setImageRes(0);\n    super.setClickListener(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof Model_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    Model_ that = (Model_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getImageRes() != that.getImageRes())) {\n      return false;\n    }\n    if (((getClickListener() == null) != (that.getClickListener() == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + getImageRes();\n    _result = 31 * _result + (getClickListener() != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"Model_{\" +\n        \"imageRes=\" + getImageRes() +\n        \", clickListener=\" + getClickListener() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelProcessorTest/testKotlinModel/ksp/Model_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewParent;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class Model_ extends Model implements GeneratedModel<Model.Holder>, ModelBuilder {\n  private OnModelBoundListener<Model_, Model.Holder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<Model_, Model.Holder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<Model_, Model.Holder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<Model_, Model.Holder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public Model_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Model.Holder object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Model.Holder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public Model_ onBind(OnModelBoundListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Model.Holder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public Model_ onUnbind(OnModelUnboundListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Model.Holder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public Model_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Model.Holder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public Model_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<Model_, Model.Holder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public Model_ imageRes(@DrawableRes int imageRes) {\n    onMutation();\n    super.setImageRes(imageRes);\n    return this;\n  }\n\n  @DrawableRes\n  public int imageRes() {\n    return super.getImageRes();\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public Model_ clickListener(\n      @Nullable final OnModelClickListener<Model_, Model.Holder> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.setClickListener(null);\n    }\n    else {\n      super.setClickListener(new WrappedEpoxyModelClickListener<>(clickListener));\n    }\n    return this;\n  }\n\n  public Model_ clickListener(@Nullable View.OnClickListener clickListener) {\n    onMutation();\n    super.setClickListener(clickListener);\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener clickListener() {\n    return super.getClickListener();\n  }\n\n  @Override\n  public Model_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public Model_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public Model_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public Model_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public Model_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected Model.Holder createNewHolder(ViewParent parent) {\n    return new Model.Holder();\n  }\n\n  @Override\n  public Model_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setImageRes(0);\n    super.setClickListener(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof Model_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    Model_ that = (Model_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getImageRes() != that.getImageRes())) {\n      return false;\n    }\n    if (((getClickListener() == null) != (that.getClickListener() == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + getImageRes();\n    _result = 31 * _result + (getClickListener() != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"Model_{\" +\n        \"imageRes=\" + getImageRes() +\n        \", clickListener=\" + getClickListener() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresEqualsFailsBasicObject.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelRequiresEqualsFailsBasicObject extends EpoxyModel<Object> {\n\n  public static class ClassWithHashCodeAndNotEquals {\n\n    @Override\n    public int hashCode() {\n      return super.hashCode();\n    }\n  }\n\n  @EpoxyAttribute ClassWithHashCodeAndNotEquals classWithoutHashCode;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeArrayFails.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelRequiresHashCodeArrayFails extends EpoxyModel<Object> {\n  @EpoxyAttribute Object[] clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeArraySucceeds.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelRequiresHashCodeArraySucceeds extends EpoxyModel<Object> {\n  @EpoxyAttribute String[] clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeAutoValueClassPasses.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.google.auto.value.AutoValue;\n\npublic class ModelRequiresHashCodeAutoValueClassPasses extends EpoxyModel<Object> {\n\n  @AutoValue\n  public static abstract class AutoValueClass {\n\n  }\n\n  @EpoxyAttribute AutoValueClass autoValueClass;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeEnumPasses.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelRequiresHashCodeEnumPasses extends EpoxyModel<Object> {\n\n  public enum MyEnum {\n    Value\n  }\n\n  @EpoxyAttribute MyEnum enumValue;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeFailsBasicObject.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ModelRequiresHashCodeFailsBasicObject extends EpoxyModel<Object> {\n\n  public static class ClassWithoutHashCode {\n\n    @Override\n    public boolean equals(Object obj) {\n      return super.equals(obj);\n    }\n  }\n\n  @EpoxyAttribute ClassWithoutHashCode classWithoutHashCode;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeIterableFails.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport java.util.List;\n\npublic class ModelRequiresHashCodeIterableFails extends EpoxyModel<Object> {\n  @EpoxyAttribute List<Object> clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelRequiresHashCodeIterableSucceeds.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport java.util.List;\n\npublic class ModelRequiresHashCodeIterableSucceeds extends EpoxyModel<Object> {\n  @EpoxyAttribute List<String> clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelReturningClassType.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\npublic class ModelReturningClassType extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public ModelReturningClassType classType(int classType) {\n    return this;\n  }\n\n  public ModelReturningClassType classType(int param1, int param2) {\n    return this;\n  }\n\n  public ModelReturningClassType list(List<String> list) {\n    return this;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelReturningClassTypeWithVarargs.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelReturningClassTypeWithVarargs extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public ModelReturningClassTypeWithVarargs classType(String... varargs) {\n    return this;\n  }\n\n  public ModelReturningClassTypeWithVarargs classType(String first, String... varargs) {\n    return this;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelReturningClassTypeWithVarargs_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelReturningClassTypeWithVarargs_ extends ModelReturningClassTypeWithVarargs implements GeneratedModel<Object>, ModelReturningClassTypeWithVarargsBuilder {\n  private OnModelBoundListener<ModelReturningClassTypeWithVarargs_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelReturningClassTypeWithVarargs_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelReturningClassTypeWithVarargs_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelReturningClassTypeWithVarargs_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelReturningClassTypeWithVarargs_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassTypeWithVarargs_ onBind(\n      OnModelBoundListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassTypeWithVarargs_ onUnbind(\n      OnModelUnboundListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassTypeWithVarargs_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassTypeWithVarargs_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelReturningClassTypeWithVarargs_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ classType(String... varargs) {\n    super.classType(varargs);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ classType(String first, String... varargs) {\n    super.classType(first, varargs);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelReturningClassTypeWithVarargs_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelReturningClassTypeWithVarargs_ that = (ModelReturningClassTypeWithVarargs_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelReturningClassTypeWithVarargs_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelReturningClassType_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelReturningClassType_ extends ModelReturningClassType implements GeneratedModel<Object>, ModelReturningClassTypeBuilder {\n  private OnModelBoundListener<ModelReturningClassType_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelReturningClassType_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelReturningClassType_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelReturningClassType_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelReturningClassType_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassType_ onBind(\n      OnModelBoundListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassType_ onUnbind(\n      OnModelUnboundListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassType_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassType_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelReturningClassType_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelReturningClassType_ classType(int classType) {\n    super.classType(classType);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ classType(int param1, int param2) {\n    super.classType(param1, param2);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ list(List<String> list) {\n    super.list(list);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelReturningClassType_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelReturningClassType_ that = (ModelReturningClassType_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelReturningClassType_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewExtendingSuperClass.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelView.Size;\n\n@ModelView(autoLayout = Size.MATCH_WIDTH_MATCH_HEIGHT)\npublic class ModelViewExtendingSuperClass extends View {\n\n  public ModelViewExtendingSuperClass(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  void subClassValue(int value) {\n\n  }\n\n  @ModelProp\n  void superClassValue(int value) {\n    // same as super class, expect no duplicate\n  }\n\n  @OnViewRecycled\n  void onClear() {\n\n  }\n\n  @OnViewRecycled\n  void onSubClassCleared() {\n\n  }\n\n  @AfterPropsSet\n  void afterProps() {\n\n  }\n\n  @AfterPropsSet\n  void onSubclassAfterPropsSet() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewExtendingSuperClassModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewExtendingSuperClassModel_ extends EpoxyModel<ModelViewExtendingSuperClass> implements GeneratedModel<ModelViewExtendingSuperClass>, ModelViewExtendingSuperClassModelBuilder {\n  private OnModelBoundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int subClassValue_Int = 0;\n\n  private int superClassValue_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClass buildView(ViewGroup parent) {\n    ModelViewExtendingSuperClass v = new ModelViewExtendingSuperClass(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewExtendingSuperClass object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelViewExtendingSuperClass object) {\n    super.bind(object);\n    object.subClassValue(subClassValue_Int);\n    object.superClassValue(superClassValue_Int);\n  }\n\n  @Override\n  public void bind(final ModelViewExtendingSuperClass object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewExtendingSuperClassModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewExtendingSuperClassModel_ that = (ModelViewExtendingSuperClassModel_) previousModel;\n    super.bind(object);\n\n    if ((subClassValue_Int != that.subClassValue_Int)) {\n      object.subClassValue(subClassValue_Int);\n    }\n\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      object.superClassValue(superClassValue_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewExtendingSuperClass object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterProps();\n    object.onSubclassAfterPropsSet();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewExtendingSuperClassModel_ onBind(\n      OnModelBoundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewExtendingSuperClass object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onClear();\n    object.onSubClassCleared();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewExtendingSuperClassModel_ onUnbind(\n      OnModelUnboundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final ModelViewExtendingSuperClass object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewExtendingSuperClassModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewExtendingSuperClass object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewExtendingSuperClassModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewExtendingSuperClass#subClassValue(int)\n   */\n  public ModelViewExtendingSuperClassModel_ subClassValue(int subClassValue) {\n    onMutation();\n    this.subClassValue_Int = subClassValue;\n    return this;\n  }\n\n  public int subClassValue() {\n    return subClassValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewExtendingSuperClass#superClassValue(int)\n   */\n  public ModelViewExtendingSuperClassModel_ superClassValue(int superClassValue) {\n    onMutation();\n    this.superClassValue_Int = superClassValue;\n    return this;\n  }\n\n  public int superClassValue() {\n    return superClassValue_Int;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.subClassValue_Int = 0;\n    this.superClassValue_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewExtendingSuperClassModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewExtendingSuperClassModel_ that = (ModelViewExtendingSuperClassModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((subClassValue_Int != that.subClassValue_Int)) {\n      return false;\n    }\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + subClassValue_Int;\n    _result = 31 * _result + superClassValue_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewExtendingSuperClassModel_{\" +\n        \"subClassValue_Int=\" + subClassValue_Int +\n        \", superClassValue_Int=\" + superClassValue_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewSuperClass.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelView.Size;\n\n@ModelView(autoLayout = Size.MATCH_WIDTH_MATCH_HEIGHT)\npublic class ModelViewSuperClass extends View {\n\n  public ModelViewSuperClass(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  void superClassValue(int value) {\n\n  }\n\n  @OnViewRecycled\n  void onClear() {\n\n  }\n\n  @AfterPropsSet\n  void afterProps() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewSuperClassModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewSuperClassModel_ extends EpoxyModel<ModelViewSuperClass> implements GeneratedModel<ModelViewSuperClass>, ModelViewSuperClassModelBuilder {\n  private OnModelBoundListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int superClassValue_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewSuperClass buildView(ViewGroup parent) {\n    ModelViewSuperClass v = new ModelViewSuperClass(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewSuperClass object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelViewSuperClass object) {\n    super.bind(object);\n    object.superClassValue(superClassValue_Int);\n  }\n\n  @Override\n  public void bind(final ModelViewSuperClass object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewSuperClassModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewSuperClassModel_ that = (ModelViewSuperClassModel_) previousModel;\n    super.bind(object);\n\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      object.superClassValue(superClassValue_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewSuperClass object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterProps();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewSuperClassModel_ onBind(\n      OnModelBoundListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewSuperClass object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onClear();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewSuperClassModel_ onUnbind(\n      OnModelUnboundListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewSuperClass object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewSuperClassModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewSuperClass object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewSuperClassModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewSuperClass#superClassValue(int)\n   */\n  public ModelViewSuperClassModel_ superClassValue(int superClassValue) {\n    onMutation();\n    this.superClassValue_Int = superClassValue;\n    return this;\n  }\n\n  public int superClassValue() {\n    return superClassValue_Int;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.superClassValue_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewSuperClassModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewSuperClassModel_ that = (ModelViewSuperClassModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superClassValue_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewSuperClassModel_{\" +\n        \"superClassValue_Int=\" + superClassValue_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewWithParis.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\nimport com.airbnb.paris.annotations.Style;\nimport com.airbnb.paris.annotations.Styleable;\n\n@Styleable\n@ModelView\npublic class ModelViewWithParis extends View {\n  @ModelProp int value;\n\n  public ModelViewWithParis(Context context) {\n    super(context);\n  }\n\n  @Style(isDefault = true)\n  static void headerStyle(ModelViewWithParisStyleApplier.StyleBuilder builder) {\n\n  }\n\n  @Style\n  static void otherStyle(ModelViewWithParisStyleApplier.StyleBuilder builder) {\n\n  }\n\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelViewWithParisModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.AsyncTask;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.paris.StyleApplierUtils;\nimport com.airbnb.paris.styles.Style;\nimport com.airbnb.viewmodeladapter.R;\nimport java.lang.AssertionError;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Runnable;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewWithParisModel_ extends EpoxyModel<ModelViewWithParis> implements GeneratedModel<ModelViewWithParis>, ModelViewWithParisModelBuilder {\n  private static final Style DEFAULT_PARIS_STYLE = new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n\n  private static WeakReference<Style> parisStyleReference_header;\n\n  private static WeakReference<Style> parisStyleReference_other;\n\n  private static WeakReference<Style> parisStyleReference_default;\n\n  private OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  private Style style = DEFAULT_PARIS_STYLE;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewWithParis buildView(ViewGroup parent) {\n    ModelViewWithParis v = new ModelViewWithParis(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewWithParis object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {\n        public void run() {\n          try {\n            StyleApplierUtils.Companion.assertSameAttributes(new ModelViewWithParisStyleApplier(object), style, DEFAULT_PARIS_STYLE);\n          }\n          catch(AssertionError e) {\n            throw new IllegalStateException(\"ModelViewWithParisModel_ model at position \" + position + \" has an invalid style:\\n\\n\" + e.getMessage());\n          }\n        }\n      } );\n    }\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object) {\n\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n    object.value = value_Int;\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewWithParisModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) previousModel;\n\n    if (!Objects.equals(style, that.style)) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.value = value_Int;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewWithParis object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onBind(\n      OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewWithParis object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onUnbind(\n      OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewWithParis object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewWithParis object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ style(Style style) {\n    onMutation();\n    this.style = style;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ styleBuilder(\n      StyleBuilderCallback<ModelViewWithParisStyleApplier.StyleBuilder> builderCallback) {\n    ModelViewWithParisStyleApplier.StyleBuilder builder = new ModelViewWithParisStyleApplier.StyleBuilder();\n    builderCallback.buildStyle(builder.addDefault());\n    return style(builder.build());\n  }\n\n  /**\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withHeaderStyle() {\n    Style style = parisStyleReference_header != null ? parisStyleReference_header.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addHeader().build();\n      parisStyleReference_header = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *  @see ModelViewWithParis#otherStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withOtherStyle() {\n    Style style = parisStyleReference_other != null ? parisStyleReference_other.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addOther().build();\n      parisStyleReference_other = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withDefaultStyle() {\n    Style style = parisStyleReference_default != null ? parisStyleReference_default.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n      parisStyleReference_default = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewWithParis#value\n   */\n  public ModelViewWithParisModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    this.style = DEFAULT_PARIS_STYLE;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewWithParisModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    if ((style != null ? !style.equals(that.style) : that.style != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    _result = 31 * _result + (style != null ? style.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewWithParisModel_{\" +\n        \"value_Int=\" + value_Int +\n        \", style=\" + style +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAbstractClass.java",
    "content": "package com.airbnb.epoxy;\n\npublic abstract class ModelWithAbstractClass extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAbstractClassAndAnnotation.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass\npublic abstract class ModelWithAbstractClassAndAnnotation extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAbstractClassAndAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAbstractClassAndAnnotation_ extends ModelWithAbstractClassAndAnnotation implements GeneratedModel<Object>, ModelWithAbstractClassAndAnnotationBuilder {\n  private OnModelBoundListener<ModelWithAbstractClassAndAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAbstractClassAndAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAbstractClassAndAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAbstractClassAndAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAbstractClassAndAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAbstractClassAndAnnotation_ onBind(\n      OnModelBoundListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAbstractClassAndAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAbstractClassAndAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAbstractClassAndAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAbstractClassAndAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAbstractClassAndAnnotation_ that = (ModelWithAbstractClassAndAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAbstractClassAndAnnotation_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAllFieldTypes.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\npublic class ModelWithAllFieldTypes extends EpoxyModel<Object> {\n  @EpoxyAttribute int valueInt;\n  @EpoxyAttribute Integer valueInteger;\n  @EpoxyAttribute short valueShort;\n  @EpoxyAttribute Short valueShortWrapper;\n  @EpoxyAttribute char valueChar;\n  @EpoxyAttribute Character valueCharacter;\n  @EpoxyAttribute byte valuebByte;\n  @EpoxyAttribute Byte valueByteWrapper;\n  @EpoxyAttribute long valueLong;\n  @EpoxyAttribute Long valueLongWrapper;\n  @EpoxyAttribute double valueDouble;\n  @EpoxyAttribute Double valueDoubleWrapper;\n  @EpoxyAttribute float valueFloat;\n  @EpoxyAttribute Float valueFloatWrapper;\n  @EpoxyAttribute boolean valueBoolean;\n  @EpoxyAttribute Boolean valueBooleanWrapper;\n  @EpoxyAttribute int[] valueIntArray;\n  @EpoxyAttribute Object[] valueObjectArray;\n  @EpoxyAttribute String valueString;\n  @EpoxyAttribute Object valueObject;\n  @EpoxyAttribute List<String> valueList;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAllFieldTypesBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.List;\n\n@EpoxyBuildScope\npublic interface ModelWithAllFieldTypesBuilder {\n  ModelWithAllFieldTypesBuilder onBind(\n      OnModelBoundListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onUnbind(\n      OnModelUnboundListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder valueInt(int valueInt);\n\n  ModelWithAllFieldTypesBuilder valueInteger(Integer valueInteger);\n\n  ModelWithAllFieldTypesBuilder valueShort(short valueShort);\n\n  ModelWithAllFieldTypesBuilder valueShortWrapper(Short valueShortWrapper);\n\n  ModelWithAllFieldTypesBuilder valueChar(char valueChar);\n\n  ModelWithAllFieldTypesBuilder valueCharacter(Character valueCharacter);\n\n  ModelWithAllFieldTypesBuilder valuebByte(byte valuebByte);\n\n  ModelWithAllFieldTypesBuilder valueByteWrapper(Byte valueByteWrapper);\n\n  ModelWithAllFieldTypesBuilder valueLong(long valueLong);\n\n  ModelWithAllFieldTypesBuilder valueLongWrapper(Long valueLongWrapper);\n\n  ModelWithAllFieldTypesBuilder valueDouble(double valueDouble);\n\n  ModelWithAllFieldTypesBuilder valueDoubleWrapper(Double valueDoubleWrapper);\n\n  ModelWithAllFieldTypesBuilder valueFloat(float valueFloat);\n\n  ModelWithAllFieldTypesBuilder valueFloatWrapper(Float valueFloatWrapper);\n\n  ModelWithAllFieldTypesBuilder valueBoolean(boolean valueBoolean);\n\n  ModelWithAllFieldTypesBuilder valueBooleanWrapper(Boolean valueBooleanWrapper);\n\n  ModelWithAllFieldTypesBuilder valueIntArray(int[] valueIntArray);\n\n  ModelWithAllFieldTypesBuilder valueObjectArray(Object[] valueObjectArray);\n\n  ModelWithAllFieldTypesBuilder valueString(String valueString);\n\n  ModelWithAllFieldTypesBuilder valueObject(Object valueObject);\n\n  ModelWithAllFieldTypesBuilder valueList(List<String> valueList);\n\n  ModelWithAllFieldTypesBuilder id(long id);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable Number... ids);\n\n  ModelWithAllFieldTypesBuilder id(long id1, long id2);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence key);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence key, long id);\n\n  ModelWithAllFieldTypesBuilder layout(@LayoutRes int layoutRes);\n\n  ModelWithAllFieldTypesBuilder spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAllFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAllFieldTypes_ extends ModelWithAllFieldTypes implements GeneratedModel<Object>, ModelWithAllFieldTypesBuilder {\n  private OnModelBoundListener<ModelWithAllFieldTypes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAllFieldTypes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAllFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllFieldTypes_ onBind(\n      OnModelBoundListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllFieldTypes_ onUnbind(\n      OnModelUnboundListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAllFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public ModelWithAllFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.valueInteger = valueInteger;\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return valueInteger;\n  }\n\n  public ModelWithAllFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.valueShort = valueShort;\n    return this;\n  }\n\n  public short valueShort() {\n    return valueShort;\n  }\n\n  public ModelWithAllFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.valueShortWrapper = valueShortWrapper;\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.valueChar = valueChar;\n    return this;\n  }\n\n  public char valueChar() {\n    return valueChar;\n  }\n\n  public ModelWithAllFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.valueCharacter = valueCharacter;\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return valueCharacter;\n  }\n\n  public ModelWithAllFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.valuebByte = valuebByte;\n    return this;\n  }\n\n  public byte valuebByte() {\n    return valuebByte;\n  }\n\n  public ModelWithAllFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.valueByteWrapper = valueByteWrapper;\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.valueLong = valueLong;\n    return this;\n  }\n\n  public long valueLong() {\n    return valueLong;\n  }\n\n  public ModelWithAllFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.valueLongWrapper = valueLongWrapper;\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.valueDouble = valueDouble;\n    return this;\n  }\n\n  public double valueDouble() {\n    return valueDouble;\n  }\n\n  public ModelWithAllFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.valueDoubleWrapper = valueDoubleWrapper;\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.valueFloat = valueFloat;\n    return this;\n  }\n\n  public float valueFloat() {\n    return valueFloat;\n  }\n\n  public ModelWithAllFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.valueFloatWrapper = valueFloatWrapper;\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.valueBoolean = valueBoolean;\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return valueBoolean;\n  }\n\n  public ModelWithAllFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.valueBooleanWrapper = valueBooleanWrapper;\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.valueIntArray = valueIntArray;\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return valueIntArray;\n  }\n\n  public ModelWithAllFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.valueObjectArray = valueObjectArray;\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public ModelWithAllFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.valueString = valueString;\n    return this;\n  }\n\n  public String valueString() {\n    return valueString;\n  }\n\n  public ModelWithAllFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.valueObject = valueObject;\n    return this;\n  }\n\n  public Object valueObject() {\n    return valueObject;\n  }\n\n  public ModelWithAllFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.valueList = valueList;\n    return this;\n  }\n\n  public List<String> valueList() {\n    return valueList;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.valueInteger = null;\n    super.valueShort = (short) 0;\n    super.valueShortWrapper = null;\n    super.valueChar = (char) 0;\n    super.valueCharacter = null;\n    super.valuebByte = (byte) 0;\n    super.valueByteWrapper = null;\n    super.valueLong = 0L;\n    super.valueLongWrapper = null;\n    super.valueDouble = 0.0d;\n    super.valueDoubleWrapper = null;\n    super.valueFloat = 0.0f;\n    super.valueFloatWrapper = null;\n    super.valueBoolean = false;\n    super.valueBooleanWrapper = null;\n    super.valueIntArray = null;\n    super.valueObjectArray = null;\n    super.valueString = null;\n    super.valueObject = null;\n    super.valueList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAllFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAllFieldTypes_ that = (ModelWithAllFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      return false;\n    }\n    if ((valueShort != that.valueShort)) {\n      return false;\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      return false;\n    }\n    if ((valueChar != that.valueChar)) {\n      return false;\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      return false;\n    }\n    if ((valuebByte != that.valuebByte)) {\n      return false;\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      return false;\n    }\n    if ((valueLong != that.valueLong)) {\n      return false;\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      return false;\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      return false;\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      return false;\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      return false;\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      return false;\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      return false;\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      return false;\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      return false;\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      return false;\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      return false;\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      return false;\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + (valueInteger != null ? valueInteger.hashCode() : 0);\n    _result = 31 * _result + valueShort;\n    _result = 31 * _result + (valueShortWrapper != null ? valueShortWrapper.hashCode() : 0);\n    _result = 31 * _result + valueChar;\n    _result = 31 * _result + (valueCharacter != null ? valueCharacter.hashCode() : 0);\n    _result = 31 * _result + valuebByte;\n    _result = 31 * _result + (valueByteWrapper != null ? valueByteWrapper.hashCode() : 0);\n    _result = 31 * _result + (int) (valueLong ^ (valueLong >>> 32));\n    _result = 31 * _result + (valueLongWrapper != null ? valueLongWrapper.hashCode() : 0);\n    temp = Double.doubleToLongBits(valueDouble);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (valueDoubleWrapper != null ? valueDoubleWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueFloat != +0.0f ? Float.floatToIntBits(valueFloat) : 0);\n    _result = 31 * _result + (valueFloatWrapper != null ? valueFloatWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueBoolean ? 1 : 0);\n    _result = 31 * _result + (valueBooleanWrapper != null ? valueBooleanWrapper.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(valueIntArray);\n    _result = 31 * _result + Arrays.hashCode(valueObjectArray);\n    _result = 31 * _result + (valueString != null ? valueString.hashCode() : 0);\n    _result = 31 * _result + (valueObject != null ? valueObject.hashCode() : 0);\n    _result = 31 * _result + (valueList != null ? valueList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAllFieldTypes_{\" +\n        \"valueInt=\" + valueInt +\n        \", valueInteger=\" + valueInteger +\n        \", valueShort=\" + valueShort +\n        \", valueShortWrapper=\" + valueShortWrapper +\n        \", valueChar=\" + valueChar +\n        \", valueCharacter=\" + valueCharacter +\n        \", valuebByte=\" + valuebByte +\n        \", valueByteWrapper=\" + valueByteWrapper +\n        \", valueLong=\" + valueLong +\n        \", valueLongWrapper=\" + valueLongWrapper +\n        \", valueDouble=\" + valueDouble +\n        \", valueDoubleWrapper=\" + valueDoubleWrapper +\n        \", valueFloat=\" + valueFloat +\n        \", valueFloatWrapper=\" + valueFloatWrapper +\n        \", valueBoolean=\" + valueBoolean +\n        \", valueBooleanWrapper=\" + valueBooleanWrapper +\n        \", valueIntArray=\" + valueIntArray +\n        \", valueObjectArray=\" + valueObjectArray +\n        \", valueString=\" + valueString +\n        \", valueObject=\" + valueObject +\n        \", valueList=\" + valueList +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAllPrivateFieldTypes.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.util.List;\n\npublic class ModelWithAllPrivateFieldTypes extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n  @EpoxyAttribute private Integer valueInteger;\n  @EpoxyAttribute private short valueShort;\n  @EpoxyAttribute private Short valueShortWrapper;\n  @EpoxyAttribute private char valueChar;\n  @EpoxyAttribute private Character valueCharacter;\n  @EpoxyAttribute private byte valuebByte;\n  @EpoxyAttribute private Byte valueByteWrapper;\n  @EpoxyAttribute private long valueLong;\n  @EpoxyAttribute private Long valueLongWrapper;\n  @EpoxyAttribute private double valueDouble;\n  @EpoxyAttribute private Double valueDoubleWrapper;\n  @EpoxyAttribute private float valueFloat;\n  @EpoxyAttribute private Float valueFloatWrapper;\n  @EpoxyAttribute private boolean valueBoolean;\n  @EpoxyAttribute private Boolean valueBooleanWrapper;\n  @EpoxyAttribute private int[] valueIntArray;\n  @EpoxyAttribute private Object[] valueObjectArray;\n  @EpoxyAttribute private String valueString;\n  @EpoxyAttribute private Object valueObject;\n  @EpoxyAttribute private List<String> valueList;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt() {\n    return valueInt;\n  }\n\n  public void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n\n  public Integer getValueInteger() {\n    return valueInteger;\n  }\n\n  public void setValueInteger(Integer valueInteger) {\n    this.valueInteger = valueInteger;\n  }\n\n  public short getValueShort() {\n    return valueShort;\n  }\n\n  public void setValueShort(short valueShort) {\n    this.valueShort = valueShort;\n  }\n\n  public Short getValueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public void setValueShortWrapper(Short valueShortWrapper) {\n    this.valueShortWrapper = valueShortWrapper;\n  }\n\n  public char getValueChar() {\n    return valueChar;\n  }\n\n  public void setValueChar(char valueChar) {\n    this.valueChar = valueChar;\n  }\n\n  public Character getValueCharacter() {\n    return valueCharacter;\n  }\n\n  public void setValueCharacter(Character valueCharacter) {\n    this.valueCharacter = valueCharacter;\n  }\n\n  public byte getValuebByte() {\n    return valuebByte;\n  }\n\n  public void setValuebByte(byte valuebByte) {\n    this.valuebByte = valuebByte;\n  }\n\n  public Byte getValueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public void setValueByteWrapper(Byte valueByteWrapper) {\n    this.valueByteWrapper = valueByteWrapper;\n  }\n\n  public long getValueLong() {\n    return valueLong;\n  }\n\n  public void setValueLong(long valueLong) {\n    this.valueLong = valueLong;\n  }\n\n  public Long getValueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public void setValueLongWrapper(Long valueLongWrapper) {\n    this.valueLongWrapper = valueLongWrapper;\n  }\n\n  public double getValueDouble() {\n    return valueDouble;\n  }\n\n  public void setValueDouble(double valueDouble) {\n    this.valueDouble = valueDouble;\n  }\n\n  public Double getValueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public void setValueDoubleWrapper(Double valueDoubleWrapper) {\n    this.valueDoubleWrapper = valueDoubleWrapper;\n  }\n\n  public float getValueFloat() {\n    return valueFloat;\n  }\n\n  public void setValueFloat(float valueFloat) {\n    this.valueFloat = valueFloat;\n  }\n\n  public Float getValueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public void setValueFloatWrapper(Float valueFloatWrapper) {\n    this.valueFloatWrapper = valueFloatWrapper;\n  }\n\n  public boolean isValueBoolean() {\n    return valueBoolean;\n  }\n\n  public void setValueBoolean(boolean valueBoolean) {\n    this.valueBoolean = valueBoolean;\n  }\n\n  public Boolean getValueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public void setValueBooleanWrapper(Boolean valueBooleanWrapper) {\n    this.valueBooleanWrapper = valueBooleanWrapper;\n  }\n\n  public int[] getValueIntArray() {\n    return valueIntArray;\n  }\n\n  public void setValueIntArray(int[] valueIntArray) {\n    this.valueIntArray = valueIntArray;\n  }\n\n  public Object[] getValueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public void setValueObjectArray(Object[] valueObjectArray) {\n    this.valueObjectArray = valueObjectArray;\n  }\n\n  public String getValueString() {\n    return valueString;\n  }\n\n  public void setValueString(String valueString) {\n    this.valueString = valueString;\n  }\n\n  public Object getValueObject() {\n    return valueObject;\n  }\n\n  public void setValueObject(Object valueObject) {\n    this.valueObject = valueObject;\n  }\n\n  public List<String> getValueList() {\n    return valueList;\n  }\n\n  public void setValueList(List<String> valueList) {\n    this.valueList = valueList;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAllPrivateFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAllPrivateFieldTypes_ extends ModelWithAllPrivateFieldTypes implements GeneratedModel<Object>, ModelWithAllPrivateFieldTypesBuilder {\n  private OnModelBoundListener<ModelWithAllPrivateFieldTypes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAllPrivateFieldTypes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAllPrivateFieldTypes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAllPrivateFieldTypes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAllPrivateFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllPrivateFieldTypes_ onBind(\n      OnModelBoundListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllPrivateFieldTypes_ onUnbind(\n      OnModelUnboundListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllPrivateFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllPrivateFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.setValueInt(valueInt);\n    return this;\n  }\n\n  public int valueInt() {\n    return super.getValueInt();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.setValueInteger(valueInteger);\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return super.getValueInteger();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.setValueShort(valueShort);\n    return this;\n  }\n\n  public short valueShort() {\n    return super.getValueShort();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.setValueShortWrapper(valueShortWrapper);\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return super.getValueShortWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.setValueChar(valueChar);\n    return this;\n  }\n\n  public char valueChar() {\n    return super.getValueChar();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.setValueCharacter(valueCharacter);\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return super.getValueCharacter();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.setValuebByte(valuebByte);\n    return this;\n  }\n\n  public byte valuebByte() {\n    return super.getValuebByte();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.setValueByteWrapper(valueByteWrapper);\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return super.getValueByteWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.setValueLong(valueLong);\n    return this;\n  }\n\n  public long valueLong() {\n    return super.getValueLong();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.setValueLongWrapper(valueLongWrapper);\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return super.getValueLongWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.setValueDouble(valueDouble);\n    return this;\n  }\n\n  public double valueDouble() {\n    return super.getValueDouble();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.setValueDoubleWrapper(valueDoubleWrapper);\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return super.getValueDoubleWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.setValueFloat(valueFloat);\n    return this;\n  }\n\n  public float valueFloat() {\n    return super.getValueFloat();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.setValueFloatWrapper(valueFloatWrapper);\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return super.getValueFloatWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.setValueBoolean(valueBoolean);\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return super.isValueBoolean();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.setValueBooleanWrapper(valueBooleanWrapper);\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return super.getValueBooleanWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.setValueIntArray(valueIntArray);\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return super.getValueIntArray();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.setValueObjectArray(valueObjectArray);\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return super.getValueObjectArray();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.setValueString(valueString);\n    return this;\n  }\n\n  public String valueString() {\n    return super.getValueString();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.setValueObject(valueObject);\n    return this;\n  }\n\n  public Object valueObject() {\n    return super.getValueObject();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.setValueList(valueList);\n    return this;\n  }\n\n  public List<String> valueList() {\n    return super.getValueList();\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ getValueObject() {\n    super.getValueObject();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setValueInt(0);\n    super.setValueInteger(null);\n    super.setValueShort((short) 0);\n    super.setValueShortWrapper(null);\n    super.setValueChar((char) 0);\n    super.setValueCharacter(null);\n    super.setValuebByte((byte) 0);\n    super.setValueByteWrapper(null);\n    super.setValueLong(0L);\n    super.setValueLongWrapper(null);\n    super.setValueDouble(0.0d);\n    super.setValueDoubleWrapper(null);\n    super.setValueFloat(0.0f);\n    super.setValueFloatWrapper(null);\n    super.setValueBoolean(false);\n    super.setValueBooleanWrapper(null);\n    super.setValueIntArray(null);\n    super.setValueObjectArray(null);\n    super.setValueString(null);\n    super.setValueObject(null);\n    super.setValueList(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAllPrivateFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAllPrivateFieldTypes_ that = (ModelWithAllPrivateFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getValueInt() != that.getValueInt())) {\n      return false;\n    }\n    if ((getValueInteger() != null ? !getValueInteger().equals(that.getValueInteger()) : that.getValueInteger() != null)) {\n      return false;\n    }\n    if ((getValueShort() != that.getValueShort())) {\n      return false;\n    }\n    if ((getValueShortWrapper() != null ? !getValueShortWrapper().equals(that.getValueShortWrapper()) : that.getValueShortWrapper() != null)) {\n      return false;\n    }\n    if ((getValueChar() != that.getValueChar())) {\n      return false;\n    }\n    if ((getValueCharacter() != null ? !getValueCharacter().equals(that.getValueCharacter()) : that.getValueCharacter() != null)) {\n      return false;\n    }\n    if ((getValuebByte() != that.getValuebByte())) {\n      return false;\n    }\n    if ((getValueByteWrapper() != null ? !getValueByteWrapper().equals(that.getValueByteWrapper()) : that.getValueByteWrapper() != null)) {\n      return false;\n    }\n    if ((getValueLong() != that.getValueLong())) {\n      return false;\n    }\n    if ((getValueLongWrapper() != null ? !getValueLongWrapper().equals(that.getValueLongWrapper()) : that.getValueLongWrapper() != null)) {\n      return false;\n    }\n    if ((Double.compare(that.getValueDouble(), getValueDouble()) != 0)) {\n      return false;\n    }\n    if ((getValueDoubleWrapper() != null ? !getValueDoubleWrapper().equals(that.getValueDoubleWrapper()) : that.getValueDoubleWrapper() != null)) {\n      return false;\n    }\n    if ((Float.compare(that.getValueFloat(), getValueFloat()) != 0)) {\n      return false;\n    }\n    if ((getValueFloatWrapper() != null ? !getValueFloatWrapper().equals(that.getValueFloatWrapper()) : that.getValueFloatWrapper() != null)) {\n      return false;\n    }\n    if ((isValueBoolean() != that.isValueBoolean())) {\n      return false;\n    }\n    if ((getValueBooleanWrapper() != null ? !getValueBooleanWrapper().equals(that.getValueBooleanWrapper()) : that.getValueBooleanWrapper() != null)) {\n      return false;\n    }\n    if (!Arrays.equals(getValueIntArray(), that.getValueIntArray())) {\n      return false;\n    }\n    if (!Arrays.equals(getValueObjectArray(), that.getValueObjectArray())) {\n      return false;\n    }\n    if ((getValueString() != null ? !getValueString().equals(that.getValueString()) : that.getValueString() != null)) {\n      return false;\n    }\n    if ((getValueObject() != null ? !getValueObject().equals(that.getValueObject()) : that.getValueObject() != null)) {\n      return false;\n    }\n    if ((getValueList() != null ? !getValueList().equals(that.getValueList()) : that.getValueList() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + getValueInt();\n    _result = 31 * _result + (getValueInteger() != null ? getValueInteger().hashCode() : 0);\n    _result = 31 * _result + getValueShort();\n    _result = 31 * _result + (getValueShortWrapper() != null ? getValueShortWrapper().hashCode() : 0);\n    _result = 31 * _result + getValueChar();\n    _result = 31 * _result + (getValueCharacter() != null ? getValueCharacter().hashCode() : 0);\n    _result = 31 * _result + getValuebByte();\n    _result = 31 * _result + (getValueByteWrapper() != null ? getValueByteWrapper().hashCode() : 0);\n    _result = 31 * _result + (int) (getValueLong() ^ (getValueLong() >>> 32));\n    _result = 31 * _result + (getValueLongWrapper() != null ? getValueLongWrapper().hashCode() : 0);\n    temp = Double.doubleToLongBits(getValueDouble());\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (getValueDoubleWrapper() != null ? getValueDoubleWrapper().hashCode() : 0);\n    _result = 31 * _result + (getValueFloat() != +0.0f ? Float.floatToIntBits(getValueFloat()) : 0);\n    _result = 31 * _result + (getValueFloatWrapper() != null ? getValueFloatWrapper().hashCode() : 0);\n    _result = 31 * _result + (isValueBoolean() ? 1 : 0);\n    _result = 31 * _result + (getValueBooleanWrapper() != null ? getValueBooleanWrapper().hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(getValueIntArray());\n    _result = 31 * _result + Arrays.hashCode(getValueObjectArray());\n    _result = 31 * _result + (getValueString() != null ? getValueString().hashCode() : 0);\n    _result = 31 * _result + (getValueObject() != null ? getValueObject().hashCode() : 0);\n    _result = 31 * _result + (getValueList() != null ? getValueList().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAllPrivateFieldTypes_{\" +\n        \"valueInt=\" + getValueInt() +\n        \", valueInteger=\" + getValueInteger() +\n        \", valueShort=\" + getValueShort() +\n        \", valueShortWrapper=\" + getValueShortWrapper() +\n        \", valueChar=\" + getValueChar() +\n        \", valueCharacter=\" + getValueCharacter() +\n        \", valuebByte=\" + getValuebByte() +\n        \", valueByteWrapper=\" + getValueByteWrapper() +\n        \", valueLong=\" + getValueLong() +\n        \", valueLongWrapper=\" + getValueLongWrapper() +\n        \", valueDouble=\" + getValueDouble() +\n        \", valueDoubleWrapper=\" + getValueDoubleWrapper() +\n        \", valueFloat=\" + getValueFloat() +\n        \", valueFloatWrapper=\" + getValueFloatWrapper() +\n        \", valueBoolean=\" + isValueBoolean() +\n        \", valueBooleanWrapper=\" + getValueBooleanWrapper() +\n        \", valueIntArray=\" + getValueIntArray() +\n        \", valueObjectArray=\" + getValueObjectArray() +\n        \", valueString=\" + getValueString() +\n        \", valueObject=\" + getValueObject() +\n        \", valueList=\" + getValueList() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotatedClass.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass\npublic class ModelWithAnnotatedClass extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ extends ModelWithAnnotatedClassAndSuperAttributes.SubModelWithAnnotatedClassAndSuperAttributes implements GeneratedModel<Object>, ModelWithAnnotatedClassAndSuperAttributes_SubModelWithAnnotatedClassAndSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ superValue(\n      int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      @Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      @Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      @Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ id(\n      @Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ layout(\n      @LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ show(\n      ) {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ show(\n      boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ hide(\n      ) {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ reset(\n      ) {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_ that = (ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotatedClassAndSuperAttributes$SubModelWithAnnotatedClassAndSuperAttributes_{\" +\n        \"superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotatedClassAndSuperAttributes.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithAnnotatedClassAndSuperAttributes extends EpoxyModel<Object> {\n\n  @EpoxyAttribute int superValue;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  @EpoxyModelClass\n  public static class SubModelWithAnnotatedClassAndSuperAttributes\n      extends ModelWithAnnotatedClassAndSuperAttributes {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotatedClassAndSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAnnotatedClassAndSuperAttributes_ extends ModelWithAnnotatedClassAndSuperAttributes implements GeneratedModel<Object>, ModelWithAnnotatedClassAndSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotatedClassAndSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClassAndSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotatedClassAndSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAnnotatedClassAndSuperAttributes_ superValue(int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClassAndSuperAttributes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotatedClassAndSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotatedClassAndSuperAttributes_ that = (ModelWithAnnotatedClassAndSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotatedClassAndSuperAttributes_{\" +\n        \"superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotatedClass_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAnnotatedClass_ extends ModelWithAnnotatedClass implements GeneratedModel<Object>, ModelWithAnnotatedClassBuilder {\n  private OnModelBoundListener<ModelWithAnnotatedClass_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotatedClass_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotatedClass_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotatedClass_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotatedClass_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClass_ onBind(\n      OnModelBoundListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClass_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClass_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClass_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotatedClass_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotatedClass_ that = (ModelWithAnnotatedClass_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotatedClass_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotation.java",
    "content": "package com.airbnb.epoxy;\n\n@EpoxyModelClass\n@Deprecated\npublic class ModelWithAnnotation extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Deprecated;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\n@Deprecated\npublic class ModelWithAnnotation_ extends ModelWithAnnotation implements GeneratedModel<Object>, ModelWithAnnotationBuilder {\n  private OnModelBoundListener<ModelWithAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotation_ onBind(OnModelBoundListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotation_ that = (ModelWithAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotation_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithCheckedChangeListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.widget.CompoundButton;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport static com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash;\n\npublic class ModelWithCheckedChangeListener extends EpoxyModel<Object> {\n  @EpoxyAttribute(DoNotHash) CompoundButton.OnCheckedChangeListener checkedListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithCheckedChangeListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.widget.CompoundButton;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithCheckedChangeListener_ extends ModelWithCheckedChangeListener implements GeneratedModel<Object>, ModelWithCheckedChangeListenerBuilder {\n  private OnModelBoundListener<ModelWithCheckedChangeListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithCheckedChangeListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithCheckedChangeListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithCheckedChangeListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithCheckedChangeListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithCheckedChangeListener_ onBind(\n      OnModelBoundListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithCheckedChangeListener_ onUnbind(\n      OnModelUnboundListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithCheckedChangeListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithCheckedChangeListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a checked change listener that will provide the parent view, model, value, and adapter position of the checked view. This will clear the normal CompoundButton.OnCheckedChangeListener if one has been set\n   */\n  public ModelWithCheckedChangeListener_ checkedListener(\n      final OnModelCheckedChangeListener<ModelWithCheckedChangeListener_, Object> checkedListener) {\n    onMutation();\n    if (checkedListener == null) {\n      super.checkedListener = null;\n    }\n    else {\n      super.checkedListener = new WrappedEpoxyModelCheckedChangeListener(checkedListener);\n    }\n    return this;\n  }\n\n  public ModelWithCheckedChangeListener_ checkedListener(\n      CompoundButton.OnCheckedChangeListener checkedListener) {\n    onMutation();\n    super.checkedListener = checkedListener;\n    return this;\n  }\n\n  public CompoundButton.OnCheckedChangeListener checkedListener() {\n    return checkedListener;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.checkedListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithCheckedChangeListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithCheckedChangeListener_ that = (ModelWithCheckedChangeListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((checkedListener == null) != (that.checkedListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (checkedListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithCheckedChangeListener_{\" +\n        \"checkedListener=\" + checkedListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithConstructors.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithConstructors extends EpoxyModel<Object> {\n  @EpoxyAttribute int valueInt;\n\n  public ModelWithConstructors(long id, int valueInt) {\n    super(id);\n    this.valueInt = valueInt;\n  }\n\n  public ModelWithConstructors(int valueInt) {\n    this.valueInt = valueInt;\n  }\n\n  public ModelWithConstructors() {\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithConstructors_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithConstructors_ extends ModelWithConstructors implements GeneratedModel<Object>, ModelWithConstructorsBuilder {\n  private OnModelBoundListener<ModelWithConstructors_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithConstructors_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithConstructors_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithConstructors_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithConstructors_(long id, int valueInt) {\n    super(id, valueInt);\n  }\n\n  public ModelWithConstructors_(int valueInt) {\n    super(valueInt);\n  }\n\n  public ModelWithConstructors_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithConstructors_ onBind(\n      OnModelBoundListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithConstructors_ onUnbind(\n      OnModelUnboundListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithConstructors_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithConstructors_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithConstructors_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithConstructors_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithConstructors_ that = (ModelWithConstructors_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + valueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithConstructors_{\" +\n        \"valueInt=\" + valueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithDataBindingBinding.java",
    "content": "package com.airbnb.epoxy.databinding;\nimport com.airbnb.epoxy.R;\nimport com.airbnb.epoxy.BR;\nimport android.view.View;\npublic class ModelWithDataBindingBinding extends androidx.databinding.ViewDataBinding  {\n\n  private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;\n  private static final android.util.SparseIntArray sViewsWithIds;\n  static {\n    sIncludes = null;\n    sViewsWithIds = null;\n  }\n  // views\n  public final android.widget.Button button;\n  // variables\n  private java.lang.String mStringValue;\n  // values\n  // listeners\n  // Inverse Binding Event Handlers\n\n  public ModelWithDataBindingBinding(androidx.databinding.DataBindingComponent bindingComponent, View root) {\n    super(bindingComponent, root, 0);\n    final Object[] bindings = mapBindings(bindingComponent, root, 1, sIncludes, sViewsWithIds);\n    this.button = (android.widget.Button) bindings[0];\n    this.button.setTag(null);\n    setRootTag(root);\n    // listeners\n    invalidateAll();\n  }\n\n  @Override\n  public void invalidateAll() {\n    synchronized(this) {\n      mDirtyFlags = 0x2L;\n    }\n    requestRebind();\n  }\n\n  @Override\n  public boolean hasPendingBindings() {\n    synchronized(this) {\n      if (mDirtyFlags != 0) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  public boolean setVariable(int variableId, Object variable) {\n    switch(variableId) {\n      case BR.stringValue :\n        setStringValue((java.lang.String) variable);\n        return true;\n    }\n    return false;\n  }\n\n  public void setStringValue(java.lang.String StringValue) {\n    this.mStringValue = StringValue;\n    synchronized(this) {\n      mDirtyFlags |= 0x1L;\n    }\n    notifyPropertyChanged(BR.stringValue);\n    super.requestRebind();\n  }\n  public java.lang.String getStringValue() {\n    return mStringValue;\n  }\n\n  @Override\n  protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {\n    switch (localFieldId) {\n    }\n    return false;\n  }\n\n  @Override\n  protected void executeBindings() {\n    long dirtyFlags = 0;\n    synchronized(this) {\n      dirtyFlags = mDirtyFlags;\n      mDirtyFlags = 0;\n    }\n    java.lang.String stringValue = mStringValue;\n\n    if ((dirtyFlags & 0x3L) != 0) {\n    }\n    // batch finished\n    if ((dirtyFlags & 0x3L) != 0) {\n      // api target 1\n\n      androidx.databinding.adapters.TextViewBindingAdapter.setText(this.button, stringValue);\n    }\n  }\n  // Listener Stub Implementations\n  // callback impls\n  // dirty flag\n  private  long mDirtyFlags = 0xffffffffffffffffL;\n\n  public static ModelWithDataBindingBinding inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {\n    return inflate(inflater, root, attachToRoot, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  public static ModelWithDataBindingBinding inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, androidx.databinding.DataBindingComponent bindingComponent) {\n    return androidx.databinding.DataBindingUtil.<ModelWithDataBindingBinding>inflate(inflater, com.airbnb.epoxy.R.layout.model_with_data_binding, root, attachToRoot, bindingComponent);\n  }\n  public static ModelWithDataBindingBinding inflate(android.view.LayoutInflater inflater) {\n    return inflate(inflater, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  public static ModelWithDataBindingBinding inflate(android.view.LayoutInflater inflater, androidx.databinding.DataBindingComponent bindingComponent) {\n    return bind(inflater.inflate(com.airbnb.epoxy.R.layout.model_with_data_binding, null, false), bindingComponent);\n  }\n  public static ModelWithDataBindingBinding bind(android.view.View view) {\n    return bind(view, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  public static ModelWithDataBindingBinding bind(android.view.View view, androidx.databinding.DataBindingComponent bindingComponent) {\n    if (!\"layout/model_with_data_binding_0\".equals(view.getTag())) {\n      throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());\n    }\n    return new ModelWithDataBindingBinding(bindingComponent, view);\n  }\n    /* flag mapping\n        flag 0 (0x1L): stringValue\n        flag 1 (0x2L): null\n    flag mapping end*/\n  //end\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithDataBindingBindingModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.databinding.ViewDataBinding;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithDataBindingBindingModel_ extends DataBindingEpoxyModel implements GeneratedModel<DataBindingEpoxyModel.DataBindingHolder>, ModelWithDataBindingBindingModelBuilder {\n  private OnModelBoundListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private String stringValue;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DataBindingEpoxyModel.DataBindingHolder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final DataBindingEpoxyModel.DataBindingHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithDataBindingBindingModel_ onBind(\n      OnModelBoundListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DataBindingEpoxyModel.DataBindingHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithDataBindingBindingModel_ onUnbind(\n      OnModelUnboundListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithDataBindingBindingModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithDataBindingBindingModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithDataBindingBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithDataBindingBindingModel_ stringValue(String stringValue) {\n    onMutation();\n    this.stringValue = stringValue;\n    return this;\n  }\n\n  public String stringValue() {\n    return stringValue;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(@Nullable Number... arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(@Nullable CharSequence arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(@Nullable CharSequence arg0,\n      @Nullable CharSequence... arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ id(@Nullable CharSequence arg0, long arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ layout(@LayoutRes int arg0) {\n    super.layout(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback arg0) {\n    super.spanSizeOverride(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.model_with_data_binding;\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding) {\n    if (!binding.setVariable(BR.stringValue, stringValue)) {\n      throw new IllegalStateException(\"The attribute stringValue was defined in your data binding model (com.airbnb.epoxy.DataBindingEpoxyModel) but a data variable of that name was not found in the layout.\");\n    }\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelWithDataBindingBindingModel_)) {\n      setDataBindingVariables(binding);\n      return;\n    }\n    ModelWithDataBindingBindingModel_ that = (ModelWithDataBindingBindingModel_) previousModel;\n    if ((stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null)) {\n      binding.setVariable(BR.stringValue, stringValue);\n    }\n  }\n\n  @Override\n  public ModelWithDataBindingBindingModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.stringValue = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithDataBindingBindingModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithDataBindingBindingModel_ that = (ModelWithDataBindingBindingModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringValue != null ? stringValue.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithDataBindingBindingModel_{\" +\n        \"stringValue=\" + stringValue +\n        \"}\" + super.toString();\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithDataBindingWithoutDonothashBinding.java",
    "content": "package com.airbnb.epoxy.databinding;\nimport android.view.View;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport com.airbnb.epoxy.R;\nimport com.airbnb.epoxy.BR;\n@SuppressWarnings(\"unchecked\")\npublic class ModelWithDataBindingWithoutDonothashBinding extends androidx.databinding.ViewDataBinding  {\n\n  @Nullable\n  private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;\n  @Nullable\n  private static final android.util.SparseIntArray sViewsWithIds;\n  static {\n    sIncludes = null;\n    sViewsWithIds = null;\n  }\n  // views\n  @NonNull\n  public final android.widget.Button button;\n  // variables\n  @Nullable\n  private java.lang.String mStringValue;\n  @Nullable\n  private android.view.View.OnClickListener mClickListener;\n  // values\n  // listeners\n  // Inverse Binding Event Handlers\n\n  public ModelWithDataBindingWithoutDonothashBinding(@NonNull androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {\n    super(bindingComponent, root, 0);\n    final Object[] bindings = mapBindings(bindingComponent, root, 1, sIncludes, sViewsWithIds);\n    this.button = (android.widget.Button) bindings[0];\n    this.button.setTag(null);\n    setRootTag(root);\n    // listeners\n    invalidateAll();\n  }\n\n  @Override\n  public void invalidateAll() {\n    synchronized(this) {\n      mDirtyFlags = 0x4L;\n    }\n    requestRebind();\n  }\n\n  @Override\n  public boolean hasPendingBindings() {\n    synchronized(this) {\n      if (mDirtyFlags != 0) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Override\n  public boolean setVariable(int variableId, @Nullable Object variable)  {\n    boolean variableSet = true;\n    if (BR.stringValue == variableId) {\n      setStringValue((java.lang.String) variable);\n    }\n    else if (BR.clickListener == variableId) {\n      setClickListener((android.view.View.OnClickListener) variable);\n    }\n    else {\n      variableSet = false;\n    }\n    return variableSet;\n  }\n\n  public void setStringValue(@Nullable java.lang.String StringValue) {\n    this.mStringValue = StringValue;\n    synchronized(this) {\n      mDirtyFlags |= 0x1L;\n    }\n    notifyPropertyChanged(BR.stringValue);\n    super.requestRebind();\n  }\n  @Nullable\n  public java.lang.String getStringValue() {\n    return mStringValue;\n  }\n  public void setClickListener(@Nullable android.view.View.OnClickListener ClickListener) {\n    this.mClickListener = ClickListener;\n    synchronized(this) {\n      mDirtyFlags |= 0x2L;\n    }\n    notifyPropertyChanged(BR.clickListener);\n    super.requestRebind();\n  }\n  @Nullable\n  public android.view.View.OnClickListener getClickListener() {\n    return mClickListener;\n  }\n\n  @Override\n  protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {\n    switch (localFieldId) {\n    }\n    return false;\n  }\n\n  @Override\n  protected void executeBindings() {\n    long dirtyFlags = 0;\n    synchronized(this) {\n      dirtyFlags = mDirtyFlags;\n      mDirtyFlags = 0;\n    }\n    java.lang.String stringValue = mStringValue;\n    android.view.View.OnClickListener clickListener = mClickListener;\n\n    if ((dirtyFlags & 0x5L) != 0) {\n    }\n    if ((dirtyFlags & 0x6L) != 0) {\n    }\n    // batch finished\n    if ((dirtyFlags & 0x6L) != 0) {\n      // api target 1\n\n      this.button.setOnClickListener(clickListener);\n    }\n    if ((dirtyFlags & 0x5L) != 0) {\n      // api target 1\n\n      androidx.databinding.adapters.TextViewBindingAdapter.setText(this.button, stringValue);\n    }\n  }\n  // Listener Stub Implementations\n  // callback impls\n  // dirty flag\n  private  long mDirtyFlags = 0xffffffffffffffffL;\n\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable android.view.ViewGroup root, boolean attachToRoot) {\n    return inflate(inflater, root, attachToRoot, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable android.view.ViewGroup root, boolean attachToRoot, @Nullable androidx.databinding.DataBindingComponent bindingComponent) {\n    return androidx.databinding.DataBindingUtil.<ModelWithDataBindingWithoutDonothashBinding>inflate(inflater, com.airbnb.epoxy.R.layout.model_with_data_binding_without_donothash, root, attachToRoot, bindingComponent);\n  }\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding inflate(@NonNull android.view.LayoutInflater inflater) {\n    return inflate(inflater, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable androidx.databinding.DataBindingComponent bindingComponent) {\n    return bind(inflater.inflate(com.airbnb.epoxy.R.layout.model_with_data_binding_without_donothash, null, false), bindingComponent);\n  }\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding bind(@NonNull android.view.View view) {\n    return bind(view, androidx.databinding.DataBindingUtil.getDefaultComponent());\n  }\n  @NonNull\n  public static ModelWithDataBindingWithoutDonothashBinding bind(@NonNull android.view.View view, @Nullable androidx.databinding.DataBindingComponent bindingComponent) {\n    if (!\"layout/model_with_data_binding_without_donothash_0\".equals(view.getTag())) {\n      throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());\n    }\n    return new ModelWithDataBindingWithoutDonothashBinding(bindingComponent, view);\n  }\n    /* flag mapping\n        flag 0 (0x1L): stringValue\n        flag 1 (0x2L): clickListener\n        flag 2 (0x3L): null\n    flag mapping end*/\n  //end\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithDataBindingWithoutDonothashBindingModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.databinding.ViewDataBinding;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify! */\npublic class ModelWithDataBindingWithoutDonothashBindingModel_ extends DataBindingEpoxyModel implements GeneratedModel<DataBindingEpoxyModel.DataBindingHolder>, ModelWithDataBindingWithoutDonothashBindingModelBuilder {\n  private OnModelBoundListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private String stringValue;\n\n  private View.OnClickListener clickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DataBindingEpoxyModel.DataBindingHolder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final DataBindingEpoxyModel.DataBindingHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public ModelWithDataBindingWithoutDonothashBindingModel_ onBind(\n      OnModelBoundListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DataBindingEpoxyModel.DataBindingHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()} */\n  public ModelWithDataBindingWithoutDonothashBindingModel_ onUnbind(\n      OnModelUnboundListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithDataBindingWithoutDonothashBindingModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithDataBindingWithoutDonothashBindingModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithDataBindingWithoutDonothashBindingModel_ stringValue(String stringValue) {\n    onMutation();\n    this.stringValue = stringValue;\n    return this;\n  }\n\n  public String stringValue() {\n    return stringValue;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set */\n  public ModelWithDataBindingWithoutDonothashBindingModel_ clickListener(\n      final OnModelClickListener<ModelWithDataBindingWithoutDonothashBindingModel_, DataBindingEpoxyModel.DataBindingHolder> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener = null;\n    }\n    else {\n      this.clickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  public ModelWithDataBindingWithoutDonothashBindingModel_ clickListener(\n      View.OnClickListener clickListener) {\n    onMutation();\n    this.clickListener = clickListener;\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return clickListener;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(@Nullable Number... arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(@Nullable CharSequence arg0) {\n    super.id(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(@Nullable CharSequence arg0,\n      @Nullable CharSequence... arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ id(@Nullable CharSequence arg0,\n      long arg1) {\n    super.id(arg0, arg1);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ layout(@LayoutRes int arg0) {\n    super.layout(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback arg0) {\n    super.spanSizeOverride(arg0);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.model_with_data_binding_without_donothash;\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding) {\n    if (!binding.setVariable(BR.stringValue, stringValue)) {\n      throw new IllegalStateException(\"The attribute stringValue was defined in your data binding model (com.airbnb.epoxy.DataBindingEpoxyModel) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.clickListener, clickListener)) {\n      throw new IllegalStateException(\"The attribute clickListener was defined in your data binding model (com.airbnb.epoxy.DataBindingEpoxyModel) but a data variable of that name was not found in the layout.\");\n    }\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelWithDataBindingWithoutDonothashBindingModel_)) {\n      setDataBindingVariables(binding);\n      return;\n    }\n    ModelWithDataBindingWithoutDonothashBindingModel_ that = (ModelWithDataBindingWithoutDonothashBindingModel_) previousModel;\n    if ((stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null)) {\n      binding.setVariable(BR.stringValue, stringValue);\n    }\n    if ((clickListener != null ? !clickListener.equals(that.clickListener) : that.clickListener != null)) {\n      binding.setVariable(BR.clickListener, clickListener);\n    }\n  }\n\n  @Override\n  public ModelWithDataBindingWithoutDonothashBindingModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.stringValue = null;\n    this.clickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithDataBindingWithoutDonothashBindingModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithDataBindingWithoutDonothashBindingModel_ that = (ModelWithDataBindingWithoutDonothashBindingModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null)) {\n      return false;\n    }\n    if ((clickListener != null ? !clickListener.equals(that.clickListener) : that.clickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringValue != null ? stringValue.hashCode() : 0);\n    _result = 31 * _result + (clickListener != null ? clickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithDataBindingWithoutDonothashBindingModel_{\" +\n        \"stringValue=\" + stringValue +\n        \", clickListener=\" + clickListener +\n        \"}\" + super.toString();\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithFieldAnnotation.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\n\npublic class ModelWithFieldAnnotation extends EpoxyModel<Object> {\n  @EpoxyAttribute @Nullable String title;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithFieldAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithFieldAnnotation_ extends ModelWithFieldAnnotation implements GeneratedModel<Object>, ModelWithFieldAnnotationBuilder {\n  private OnModelBoundListener<ModelWithFieldAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithFieldAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithFieldAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithFieldAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithFieldAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFieldAnnotation_ onBind(\n      OnModelBoundListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFieldAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFieldAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFieldAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithFieldAnnotation_ title(@Nullable String title) {\n    onMutation();\n    super.title = title;\n    return this;\n  }\n\n  @Nullable\n  public String title() {\n    return title;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.title = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithFieldAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithFieldAnnotation_ that = (ModelWithFieldAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title != null ? !title.equals(that.title) : that.title != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title != null ? title.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithFieldAnnotation_{\" +\n        \"title=\" + title +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithFinalClass.java",
    "content": "package com.airbnb.epoxy;\n\npublic final class ModelWithFinalClass extends EpoxyModel<Object> {\n  @EpoxyAttribute int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithFinalField.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithFinalField extends EpoxyModel<Object> {\n  @EpoxyAttribute final int finalValueInt;\n  @EpoxyAttribute int nonFinalValueInt;\n\n  public ModelWithFinalField(long id, int valueInt) {\n    super(id);\n    this.finalValueInt = valueInt;\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithFinalField_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithFinalField_ extends ModelWithFinalField implements GeneratedModel<Object>, ModelWithFinalFieldBuilder {\n  private OnModelBoundListener<ModelWithFinalField_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithFinalField_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithFinalField_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithFinalField_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithFinalField_(long id, int valueInt) {\n    super(id, valueInt);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFinalField_ onBind(OnModelBoundListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFinalField_ onUnbind(\n      OnModelUnboundListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFinalField_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFinalField_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int finalValueInt() {\n    return finalValueInt;\n  }\n\n  public ModelWithFinalField_ nonFinalValueInt(int nonFinalValueInt) {\n    onMutation();\n    super.nonFinalValueInt = nonFinalValueInt;\n    return this;\n  }\n\n  public int nonFinalValueInt() {\n    return nonFinalValueInt;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.nonFinalValueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithFinalField_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithFinalField_ that = (ModelWithFinalField_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((finalValueInt != that.finalValueInt)) {\n      return false;\n    }\n    if ((nonFinalValueInt != that.nonFinalValueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + finalValueInt;\n    _result = 31 * _result + nonFinalValueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithFinalField_{\" +\n        \"finalValueInt=\" + finalValueInt +\n        \", nonFinalValueInt=\" + nonFinalValueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithIntDef.java",
    "content": "package com.airbnb.epoxy.models;\n\nimport androidx.annotation.IntDef;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport java.lang.annotation.Retention;\n\nimport static java.lang.annotation.RetentionPolicy.SOURCE;\n\npublic class ModelWithIntDef extends EpoxyModel<Object> {\n\n  @Retention(SOURCE)\n  @IntDef({TYPE_1})\n  public @interface MyType {}\n\n  public static final int TYPE_1 = 1;\n\n  @EpoxyAttribute @MyType int type;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithIntDef_.java",
    "content": "package com.airbnb.epoxy.models;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.epoxy.EpoxyController;\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyViewHolder;\nimport com.airbnb.epoxy.GeneratedModel;\nimport com.airbnb.epoxy.OnModelBoundListener;\nimport com.airbnb.epoxy.OnModelUnboundListener;\nimport com.airbnb.epoxy.OnModelVisibilityChangedListener;\nimport com.airbnb.epoxy.OnModelVisibilityStateChangedListener;\nimport com.airbnb.epoxy.models.ModelWithIntDef.MyType;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithIntDef_ extends ModelWithIntDef implements GeneratedModel<Object>, ModelWithIntDefBuilder {\n  private OnModelBoundListener<ModelWithIntDef_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithIntDef_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithIntDef_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithIntDef_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithIntDef_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithIntDef_ onBind(OnModelBoundListener<ModelWithIntDef_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithIntDef_ onUnbind(OnModelUnboundListener<ModelWithIntDef_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithIntDef_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithIntDef_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithIntDef_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithIntDef_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithIntDef_ type(@MyType int type) {\n    onMutation();\n    super.type = type;\n    return this;\n  }\n\n  @MyType\n  public int type() {\n    return type;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithIntDef_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.type = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithIntDef_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithIntDef_ that = (ModelWithIntDef_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((type != that.type)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + type;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithIntDef_{\" +\n        \"type=\" + type +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithGetterWithParams.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithGetterWithParams extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt(int param) {\n    return valueInt;\n  }\n\n  public void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithIsPrefixGetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithIsPrefixGetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private boolean valueBoolean;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public boolean isValueBoolean() {\n    return valueBoolean;\n  }\n\n  public void setValueBoolean(boolean valueBoolean) {\n    this.valueBoolean = valueBoolean;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithPrivateGetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithPrivateGetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  private int getValueInt() {\n    return valueInt;\n  }\n\n  public void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithPrivateSetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithPrivateSetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt() {\n    return valueInt;\n  }\n\n  private void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName extends EpoxyModel<Object> {\n  @EpoxyAttribute private boolean isValue;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public boolean isValue() {\n    return isValue;\n  }\n\n  public void setValue(boolean isValue) {\n    this.isValue = isValue;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ extends ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName implements GeneratedModel<Object>, ModelWithPrivateFieldWithSameAsFieldGetterAndSetterNameBuilder {\n  private OnModelBoundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onBind(\n      OnModelBoundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onUnbind(\n      OnModelUnboundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ isValue(boolean isValue) {\n    onMutation();\n    super.setValue(isValue);\n    return this;\n  }\n\n  public boolean isValue() {\n    return super.isValue();\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setValue(false);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ that = (ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((isValue() != that.isValue())) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (isValue() ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_{\" +\n        \"isValue=\" + isValue() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithSettterWithoutParams.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithSettterWithoutParams extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt() {\n    return valueInt;\n  }\n\n  public void setValueInt() {\n    this.valueInt = 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithStaticGetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithStaticGetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public static int getValueInt() {\n    return 0;\n  }\n\n  public void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithStaticSetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithStaticSetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt() {\n    return valueInt;\n  }\n\n  public static void setValueInt(int valueInt) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithoutGetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithoutGetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public void setValueInt(int valueInt) {\n    this.valueInt = valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithoutGetterAndSetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithoutGetterAndSetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateFieldWithoutSetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateFieldWithoutSetter extends EpoxyModel<Object> {\n  @EpoxyAttribute private int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public int getValueInt() {\n    return valueInt;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateInnerClass.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithPrivateInnerClass extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  private static class Test extends EpoxyModel<Object> {\n    @EpoxyAttribute int value;\n\n    @Override\n    protected int getDefaultLayout() {\n      return 0;\n    }\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateViewClickListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.View.OnClickListener;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport static com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash;\n\npublic class ModelWithPrivateViewClickListener extends EpoxyModel<Object> {\n  @EpoxyAttribute(DoNotHash) private View.OnClickListener clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public OnClickListener getClickListener() {\n    return clickListener;\n  }\n\n  public void setClickListener(OnClickListener clickListener) {\n    this.clickListener = clickListener;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithPrivateViewClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithPrivateViewClickListener_ extends ModelWithPrivateViewClickListener implements GeneratedModel<Object>, ModelWithPrivateViewClickListenerBuilder {\n  private OnModelBoundListener<ModelWithPrivateViewClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithPrivateViewClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithPrivateViewClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithPrivateViewClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithPrivateViewClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateViewClickListener_ onBind(\n      OnModelBoundListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateViewClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateViewClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateViewClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithPrivateViewClickListener_ clickListener(\n      final OnModelClickListener<ModelWithPrivateViewClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.setClickListener(null);\n    }\n    else {\n      super.setClickListener(new WrappedEpoxyModelClickListener<>(clickListener));\n    }\n    return this;\n  }\n\n  public ModelWithPrivateViewClickListener_ clickListener(View.OnClickListener clickListener) {\n    onMutation();\n    super.setClickListener(clickListener);\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return super.getClickListener();\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setClickListener(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithPrivateViewClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithPrivateViewClickListener_ that = (ModelWithPrivateViewClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((getClickListener() == null) != (that.getClickListener() == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (getClickListener() != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithPrivateViewClickListener_{\" +\n        \"clickListener=\" + getClickListener() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithStaticField.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithStaticField extends EpoxyModel<Object> {\n  @EpoxyAttribute static int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithSuper.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithSuper extends EpoxyModel<Object> {\n  @EpoxyAttribute int valueInt;\n\n  public ModelWithSuper valueInt(int valueInt) {\n    this.valueInt = valueInt;\n    return this;\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithSuperAttributes$SubModelWithSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuperAttributes$SubModelWithSuperAttributes_ extends ModelWithSuperAttributes.SubModelWithSuperAttributes implements GeneratedModel<Object>, ModelWithSuperAttributes_SubModelWithSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ subValue(int subValue) {\n    onMutation();\n    super.subValue = subValue;\n    return this;\n  }\n\n  public int subValue() {\n    return subValue;\n  }\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ superValue(int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.subValue = 0;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuperAttributes$SubModelWithSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuperAttributes$SubModelWithSuperAttributes_ that = (ModelWithSuperAttributes$SubModelWithSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((subValue != that.subValue)) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + subValue;\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuperAttributes$SubModelWithSuperAttributes_{\" +\n        \"subValue=\" + subValue +\n        \", superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithSuperAttributes.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithSuperAttributes extends EpoxyModel<Object> {\n\n  @EpoxyAttribute int superValue;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public static class SubModelWithSuperAttributes extends ModelWithSuperAttributes {\n    @EpoxyAttribute int subValue;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuperAttributes_ extends ModelWithSuperAttributes implements GeneratedModel<Object>, ModelWithSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuperAttributes_ superValue(int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuperAttributes_ that = (ModelWithSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuperAttributes_{\" +\n        \"superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithSuper_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuper_ extends ModelWithSuper implements GeneratedModel<Object>, ModelWithSuperBuilder {\n  private OnModelBoundListener<ModelWithSuper_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuper_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuper_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuper_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuper_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuper_ onBind(OnModelBoundListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuper_ onUnbind(OnModelUnboundListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuper_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuper_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuper_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    super.valueInt(valueInt);\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  @Override\n  public ModelWithSuper_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuper_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuper_ that = (ModelWithSuper_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + valueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuper_{\" +\n        \"valueInt=\" + valueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithType.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithType<T extends String> extends EpoxyModel<Object> {\n\n  @EpoxyAttribute int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof ModelWithType_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n\n    ModelWithType that = (ModelWithType) o;\n\n    return value == that.value;\n  }\n\n  @Override\n  public int hashCode() {\n    int result = super.hashCode();\n    result = 31 * result + value;\n    return result;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithType_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithType_<T extends String> extends ModelWithType<T> implements GeneratedModel<Object>, ModelWithTypeBuilder<T> {\n  private OnModelBoundListener<ModelWithType_<T>, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithType_<T>, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithType_<T>, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithType_<T>, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithType_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithType_<T> onBind(OnModelBoundListener<ModelWithType_<T>, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithType_<T> onUnbind(OnModelUnboundListener<ModelWithType_<T>, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithType_<T> onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithType_<T>, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithType_<T> onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithType_<T>, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithType_<T> value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelWithType_<T> id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithType_<T> reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithType_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithType_ that = (ModelWithType_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithType_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithVarargsConstructors.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithVarargsConstructors extends EpoxyModel<Object> {\n  @EpoxyAttribute int valueInt;\n  @EpoxyAttribute String[] varargs;\n\n  public ModelWithVarargsConstructors(String... varargs) {\n    this.varargs = varargs;\n  }\n\n  public ModelWithVarargsConstructors(int valueInt, String... varargs) {\n    this.valueInt = valueInt;\n    this.varargs = varargs;\n  }\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithVarargsConstructors_.java",
    "content": "\npackage com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.Arrays;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithVarargsConstructors_ extends ModelWithVarargsConstructors implements GeneratedModel<Object>, ModelWithVarargsConstructorsBuilder {\n  private OnModelBoundListener<ModelWithVarargsConstructors_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithVarargsConstructors_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithVarargsConstructors_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithVarargsConstructors_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithVarargsConstructors_(String... varargs) {\n    super(varargs);\n  }\n\n  public ModelWithVarargsConstructors_(int valueInt, String... varargs) {\n    super(valueInt, varargs);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithVarargsConstructors_ onBind(\n      OnModelBoundListener<ModelWithVarargsConstructors_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithVarargsConstructors_ onUnbind(\n      OnModelUnboundListener<ModelWithVarargsConstructors_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithVarargsConstructors_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithVarargsConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithVarargsConstructors_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithVarargsConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithVarargsConstructors_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public ModelWithVarargsConstructors_ varargs(String[] varargs) {\n    onMutation();\n    super.varargs = varargs;\n    return this;\n  }\n\n  public String[] varargs() {\n    return varargs;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithVarargsConstructors_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.varargs = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithVarargsConstructors_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithVarargsConstructors_ that = (ModelWithVarargsConstructors_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if (!Arrays.equals(varargs, that.varargs)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + Arrays.hashCode(varargs);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithVarargsConstructors_{\" +\n        \"valueInt=\" + valueInt +\n        \", varargs=\" + varargs +\n        \"}\" + super.toString();\n  }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithViewClickListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport static com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash;\n\npublic class ModelWithViewClickListener extends EpoxyModel<Object> {\n  @EpoxyAttribute(DoNotHash) View.OnClickListener clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithViewClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithViewClickListener_ extends ModelWithViewClickListener implements GeneratedModel<Object>, ModelWithViewClickListenerBuilder {\n  private OnModelBoundListener<ModelWithViewClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithViewClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithViewClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithViewClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithViewClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewClickListener_ onBind(\n      OnModelBoundListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithViewClickListener_ clickListener(\n      final OnModelClickListener<ModelWithViewClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.clickListener = null;\n    }\n    else {\n      super.clickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  public ModelWithViewClickListener_ clickListener(View.OnClickListener clickListener) {\n    onMutation();\n    super.clickListener = clickListener;\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return clickListener;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.clickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithViewClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithViewClickListener_ that = (ModelWithViewClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((clickListener == null) != (that.clickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithViewClickListener_{\" +\n        \"clickListener=\" + clickListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithViewLongClickListener.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport static com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash;\n\npublic class ModelWithViewLongClickListener extends EpoxyModel<Object> {\n  @EpoxyAttribute(DoNotHash) View.OnLongClickListener clickListener;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithViewLongClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithViewLongClickListener_ extends ModelWithViewLongClickListener implements GeneratedModel<Object>, ModelWithViewLongClickListenerBuilder {\n  private OnModelBoundListener<ModelWithViewLongClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithViewLongClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithViewLongClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithViewLongClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithViewLongClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewLongClickListener_ onBind(\n      OnModelBoundListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewLongClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewLongClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewLongClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithViewLongClickListener_ clickListener(\n      final OnModelLongClickListener<ModelWithViewLongClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.clickListener = null;\n    }\n    else {\n      super.clickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  public ModelWithViewLongClickListener_ clickListener(View.OnLongClickListener clickListener) {\n    onMutation();\n    super.clickListener = clickListener;\n    return this;\n  }\n\n  public View.OnLongClickListener clickListener() {\n    return clickListener;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.clickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithViewLongClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithViewLongClickListener_ that = (ModelWithViewLongClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((clickListener == null) != (that.clickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithViewLongClickListener_{\" +\n        \"clickListener=\" + clickListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithoutEpoxyExtension.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithoutEpoxyExtension extends Object {\n  @EpoxyAttribute int valueInt;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithoutHash.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithoutHash extends EpoxyModel<Object> {\n  @EpoxyAttribute int value;\n  @EpoxyAttribute(hash = false) int value2;\n  @EpoxyAttribute(hash = false) String value3;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithoutHash_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithoutHash_ extends ModelWithoutHash implements GeneratedModel<Object>, ModelWithoutHashBuilder {\n  private OnModelBoundListener<ModelWithoutHash_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithoutHash_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithoutHash_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithoutHash_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithoutHash_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutHash_ onBind(OnModelBoundListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutHash_ onUnbind(OnModelUnboundListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutHash_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutHash_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithoutHash_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelWithoutHash_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelWithoutHash_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithoutHash_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithoutHash_ that = (ModelWithoutHash_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if (((value3 == null) != (that.value3 == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + (value3 != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithoutHash_{\" +\n        \"value=\" + value +\n        \", value2=\" + value2 +\n        \", value3=\" + value3 +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithoutSetter.java",
    "content": "package com.airbnb.epoxy;\n\npublic class ModelWithoutSetter extends EpoxyModel<Object> {\n  @EpoxyAttribute(setter = false) int value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ModelWithoutSetter_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithoutSetter_ extends ModelWithoutSetter implements GeneratedModel<Object>, ModelWithoutSetterBuilder {\n  private OnModelBoundListener<ModelWithoutSetter_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithoutSetter_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithoutSetter_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithoutSetter_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithoutSetter_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutSetter_ onBind(OnModelBoundListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutSetter_ onUnbind(\n      OnModelUnboundListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutSetter_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutSetter_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithoutSetter_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithoutSetter_ that = (ModelWithoutSetter_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithoutSetter_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/NullOnRecycleView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class NullOnRecycleView extends View {\n\n  public NullOnRecycleView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = Option.NullOnRecycle)\n  public void setTitle(@Nullable CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/NullOnRecycleViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class NullOnRecycleViewModel_ extends EpoxyModel<NullOnRecycleView> implements GeneratedModel<NullOnRecycleView>, NullOnRecycleViewModelBuilder {\n  private OnModelBoundListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private CharSequence title_CharSequence = (CharSequence) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final NullOnRecycleView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final NullOnRecycleView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final NullOnRecycleView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof NullOnRecycleViewModel_)) {\n      bind(object);\n      return;\n    }\n    NullOnRecycleViewModel_ that = (NullOnRecycleViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final NullOnRecycleView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public NullOnRecycleViewModel_ onBind(\n      OnModelBoundListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(NullOnRecycleView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setTitle((CharSequence) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public NullOnRecycleViewModel_ onUnbind(\n      OnModelUnboundListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final NullOnRecycleView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public NullOnRecycleViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final NullOnRecycleView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public NullOnRecycleViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see NullOnRecycleView#setTitle(CharSequence)\n   */\n  public NullOnRecycleViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.title_CharSequence = (CharSequence) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof NullOnRecycleViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    NullOnRecycleViewModel_ that = (NullOnRecycleViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"NullOnRecycleViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/NullOnRecycleView_throwsIfNotNullable.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelProp.Option;\n\n@ModelView(defaultLayout = 1)\npublic class NullOnRecycleView_throwsIfNotNullable extends View {\n\n  public NullOnRecycleView_throwsIfNotNullable(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = Option.NullOnRecycle)\n  public void setTitle(CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ObjectWithoutEqualsThrowsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class ObjectWithoutEqualsThrowsView extends View {\n\n  public ObjectWithoutEqualsThrowsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setClickListener(View.OnClickListener title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnViewRecycledView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnViewRecycledView extends View {\n\n  public OnViewRecycledView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnViewRecycled\n  void onRecycled1() {\n    // also testing package private works\n  }\n\n  @OnViewRecycled\n  public void onRecycled2() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnViewRecycledViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnViewRecycledViewModel_ extends EpoxyModel<OnViewRecycledView> implements GeneratedModel<OnViewRecycledView>, OnViewRecycledViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnViewRecycledView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnViewRecycledView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnViewRecycledView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnViewRecycledViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnViewRecycledViewModel_ that = (OnViewRecycledViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnViewRecycledView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnViewRecycledViewModel_ onBind(\n      OnModelBoundListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnViewRecycledView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onRecycled1();\n    object.onRecycled2();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnViewRecycledViewModel_ onUnbind(\n      OnModelUnboundListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final OnViewRecycledView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnViewRecycledViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnViewRecycledView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnViewRecycledViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnViewRecycledView#setTitle(CharSequence)\n   */\n  public OnViewRecycledViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnViewRecycledViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnViewRecycledViewModel_ that = (OnViewRecycledViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnViewRecycledViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnViewRecycledView_throwsIfHasParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnViewRecycledView_throwsIfHasParams extends View {\n\n  public OnViewRecycledView_throwsIfHasParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnViewRecycled\n  private void onRecycled1(int param) {\n  }\n\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnViewRecycledView_throwsIfPrivate.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnViewRecycledView_throwsIfPrivate extends View {\n\n  public OnViewRecycledView_throwsIfPrivate(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnViewRecycled\n  private void onRecycled1() {\n  }\n\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnViewRecycledView_throwsIfStatic.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnViewRecycledView_throwsIfStatic extends View {\n\n  public OnViewRecycledView_throwsIfStatic(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnViewRecycled\n  static void onRecycled1() {\n  }\n\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityChangedView extends View {\n\n  public OnVisibilityChangedView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityChanged\n  void onVisibilityChanged1(float ph, float pw, int vh, int vw) {\n    // also testing package private works\n  }\n\n  @OnVisibilityChanged\n  public void onVisibilityChanged2(float ph, float pw, int vh, int vw) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnVisibilityChangedViewModel_ extends EpoxyModel<OnVisibilityChangedView> implements GeneratedModel<OnVisibilityChangedView>, OnVisibilityChangedViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnVisibilityChangedView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnVisibilityChangedView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnVisibilityChangedView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnVisibilityChangedViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnVisibilityChangedViewModel_ that = (OnVisibilityChangedViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnVisibilityChangedView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityChangedViewModel_ onBind(\n      OnModelBoundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnVisibilityChangedView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityChangedViewModel_ onUnbind(\n      OnModelUnboundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final OnVisibilityChangedView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityChangedViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnVisibilityChangedView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    object.onVisibilityChanged1(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    object.onVisibilityChanged2(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityChangedViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnVisibilityChangedView#setTitle(CharSequence)\n   */\n  public OnVisibilityChangedViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnVisibilityChangedViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnVisibilityChangedViewModel_ that = (OnVisibilityChangedViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnVisibilityChangedViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedView_throwsIfInvalidParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityChangedView_throwsIfInvalidParams extends View {\n\n  public OnVisibilityChangedView_throwsIfInvalidParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityChanged\n  public void onVisibilityChanged(boolean ph, boolean pw, int vh, int vw) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedView_throwsIfNoParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityChangedView_throwsIfNoParams extends View {\n\n  public OnVisibilityChangedView_throwsIfNoParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityChanged\n  void onVisibilityChanged() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedView_throwsIfPrivate.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityChangedView_throwsIfPrivate extends View {\n\n  public OnVisibilityChangedView_throwsIfPrivate(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityChanged\n  private void onVisibilityChanged(float ph, float pw, int vh, int vw) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityChangedView_throwsIfStatic.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityChangedView_throwsIfStatic extends View {\n\n  public OnVisibilityChangedView_throwsIfStatic(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityChanged\n  static void onVisibilityChanged(float ph, float pw, int vh, int vw) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityStateChangedView extends View {\n\n  public OnVisibilityStateChangedView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityStateChanged\n  void onVisibilityStateChanged1(int s) {\n    // also testing package private works\n  }\n\n  @OnVisibilityStateChanged\n  public void onVisibilityStateChanged2(int s) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnVisibilityStateChangedViewModel_ extends EpoxyModel<OnVisibilityStateChangedView> implements GeneratedModel<OnVisibilityStateChangedView>, OnVisibilityStateChangedViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnVisibilityStateChangedView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnVisibilityStateChangedView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnVisibilityStateChangedView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnVisibilityStateChangedViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnVisibilityStateChangedViewModel_ that = (OnVisibilityStateChangedViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnVisibilityStateChangedView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityStateChangedViewModel_ onBind(\n      OnModelBoundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnVisibilityStateChangedView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityStateChangedViewModel_ onUnbind(\n      OnModelUnboundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final OnVisibilityStateChangedView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    object.onVisibilityStateChanged1(visibilityState);\n    object.onVisibilityStateChanged2(visibilityState);\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityStateChangedViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnVisibilityStateChangedView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityStateChangedViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnVisibilityStateChangedView#setTitle(CharSequence)\n   */\n  public OnVisibilityStateChangedViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnVisibilityStateChangedViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnVisibilityStateChangedViewModel_ that = (OnVisibilityStateChangedViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnVisibilityStateChangedViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedView_throwsIfInvalidParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityStateChangedView_throwsIfInvalidParams extends View {\n\n  public OnVisibilityStateChangedView_throwsIfInvalidParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityStateChanged\n  public void onVisibilityStateChanged(boolean s) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedView_throwsIfNoParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityStateChangedView_throwsIfNoParams extends View {\n\n  public OnVisibilityStateChangedView_throwsIfNoParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityStateChanged\n  void onVisibilityStateChanged() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedView_throwsIfPrivate.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityStateChangedView_throwsIfPrivate extends View {\n\n  public OnVisibilityStateChangedView_throwsIfPrivate(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityStateChanged\n  private void onVisibilityStateChanged(int s) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/OnVisibilityStateChangedView_throwsIfStatic.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class OnVisibilityStateChangedView_throwsIfStatic extends View {\n\n  public OnVisibilityStateChangedView_throwsIfStatic(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @OnVisibilityStateChanged\n  static void onVisibilityStateChanged(int s) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView extends View {\n  static final int PRIMITIVE_DEFAULT = 23;\n  static final String STRING_DEFAULT = \"hello world\";\n\n  public PropDefaultsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void defaultsToNull(@Nullable CharSequence title) {\n\n  }\n\n  @ModelProp\n  public void noDefaultSoItIsRequired(CharSequence title) {\n\n  }\n\n  @ModelProp\n  public void primitivesHaveImplicitDefaultsAndCannotBeRequired(int title) {\n\n  }\n\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n\n  @ModelProp(defaultValue = \"STRING_DEFAULT\")\n  public void objectWithDefault(String title) {\n\n  }\n\n  @ModelProp(defaultValue = \"STRING_DEFAULT\")\n  public void objectWithDefaultAndNullable(@Nullable String title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class PropDefaultsViewModel_ extends EpoxyModel<PropDefaultsView> implements GeneratedModel<PropDefaultsView>, PropDefaultsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(6);\n\n  private OnModelBoundListener<PropDefaultsViewModel_, PropDefaultsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<PropDefaultsViewModel_, PropDefaultsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<PropDefaultsViewModel_, PropDefaultsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<PropDefaultsViewModel_, PropDefaultsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private CharSequence defaultsToNull_CharSequence = (CharSequence) null;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private CharSequence noDefaultSoItIsRequired_CharSequence;\n\n  private int primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = 0;\n\n  private int primitiveWithExplicitDefault_Int = PropDefaultsView.PRIMITIVE_DEFAULT;\n\n  @NonNull\n  private String objectWithDefault_String = PropDefaultsView.STRING_DEFAULT;\n\n  @Nullable\n  private String objectWithDefaultAndNullable_String = PropDefaultsView.STRING_DEFAULT;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for noDefaultSoItIsRequired\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final PropDefaultsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final PropDefaultsView object) {\n    super.bind(object);\n    object.primitiveWithExplicitDefault(primitiveWithExplicitDefault_Int);\n    object.defaultsToNull(defaultsToNull_CharSequence);\n    object.noDefaultSoItIsRequired(noDefaultSoItIsRequired_CharSequence);\n    object.objectWithDefaultAndNullable(objectWithDefaultAndNullable_String);\n    object.objectWithDefault(objectWithDefault_String);\n    object.primitivesHaveImplicitDefaultsAndCannotBeRequired(primitivesHaveImplicitDefaultsAndCannotBeRequired_Int);\n  }\n\n  @Override\n  public void bind(final PropDefaultsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof PropDefaultsViewModel_)) {\n      bind(object);\n      return;\n    }\n    PropDefaultsViewModel_ that = (PropDefaultsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((primitiveWithExplicitDefault_Int != that.primitiveWithExplicitDefault_Int)) {\n      object.primitiveWithExplicitDefault(primitiveWithExplicitDefault_Int);\n    }\n\n    if ((defaultsToNull_CharSequence != null ? !defaultsToNull_CharSequence.equals(that.defaultsToNull_CharSequence) : that.defaultsToNull_CharSequence != null)) {\n      object.defaultsToNull(defaultsToNull_CharSequence);\n    }\n\n    if ((noDefaultSoItIsRequired_CharSequence != null ? !noDefaultSoItIsRequired_CharSequence.equals(that.noDefaultSoItIsRequired_CharSequence) : that.noDefaultSoItIsRequired_CharSequence != null)) {\n      object.noDefaultSoItIsRequired(noDefaultSoItIsRequired_CharSequence);\n    }\n\n    if ((objectWithDefaultAndNullable_String != null ? !objectWithDefaultAndNullable_String.equals(that.objectWithDefaultAndNullable_String) : that.objectWithDefaultAndNullable_String != null)) {\n      object.objectWithDefaultAndNullable(objectWithDefaultAndNullable_String);\n    }\n\n    if ((objectWithDefault_String != null ? !objectWithDefault_String.equals(that.objectWithDefault_String) : that.objectWithDefault_String != null)) {\n      object.objectWithDefault(objectWithDefault_String);\n    }\n\n    if ((primitivesHaveImplicitDefaultsAndCannotBeRequired_Int != that.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int)) {\n      object.primitivesHaveImplicitDefaultsAndCannotBeRequired(primitivesHaveImplicitDefaultsAndCannotBeRequired_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final PropDefaultsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropDefaultsViewModel_ onBind(\n      OnModelBoundListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(PropDefaultsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropDefaultsViewModel_ onUnbind(\n      OnModelUnboundListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final PropDefaultsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropDefaultsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final PropDefaultsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropDefaultsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see PropDefaultsView#defaultsToNull(CharSequence)\n   */\n  public PropDefaultsViewModel_ defaultsToNull(@Nullable CharSequence defaultsToNull) {\n    onMutation();\n    this.defaultsToNull_CharSequence = defaultsToNull;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence defaultsToNull() {\n    return defaultsToNull_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropDefaultsView#noDefaultSoItIsRequired(CharSequence)\n   */\n  public PropDefaultsViewModel_ noDefaultSoItIsRequired(\n      @NonNull CharSequence noDefaultSoItIsRequired) {\n    if (noDefaultSoItIsRequired == null) {\n      throw new IllegalArgumentException(\"noDefaultSoItIsRequired cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.noDefaultSoItIsRequired_CharSequence = noDefaultSoItIsRequired;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence noDefaultSoItIsRequired() {\n    return noDefaultSoItIsRequired_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropDefaultsView#primitivesHaveImplicitDefaultsAndCannotBeRequired(int)\n   */\n  public PropDefaultsViewModel_ primitivesHaveImplicitDefaultsAndCannotBeRequired(\n      int primitivesHaveImplicitDefaultsAndCannotBeRequired) {\n    onMutation();\n    this.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = primitivesHaveImplicitDefaultsAndCannotBeRequired;\n    return this;\n  }\n\n  public int primitivesHaveImplicitDefaultsAndCannotBeRequired() {\n    return primitivesHaveImplicitDefaultsAndCannotBeRequired_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#PRIMITIVE_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#primitiveWithExplicitDefault(int)\n   */\n  public PropDefaultsViewModel_ primitiveWithExplicitDefault(int primitiveWithExplicitDefault) {\n    onMutation();\n    this.primitiveWithExplicitDefault_Int = primitiveWithExplicitDefault;\n    return this;\n  }\n\n  public int primitiveWithExplicitDefault() {\n    return primitiveWithExplicitDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#STRING_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#objectWithDefault(String)\n   */\n  public PropDefaultsViewModel_ objectWithDefault(@NonNull String objectWithDefault) {\n    if (objectWithDefault == null) {\n      throw new IllegalArgumentException(\"objectWithDefault cannot be null\");\n    }\n    onMutation();\n    this.objectWithDefault_String = objectWithDefault;\n    return this;\n  }\n\n  @NonNull\n  public String objectWithDefault() {\n    return objectWithDefault_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#STRING_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#objectWithDefaultAndNullable(String)\n   */\n  public PropDefaultsViewModel_ objectWithDefaultAndNullable(\n      @Nullable String objectWithDefaultAndNullable) {\n    onMutation();\n    this.objectWithDefaultAndNullable_String = objectWithDefaultAndNullable;\n    return this;\n  }\n\n  @Nullable\n  public String objectWithDefaultAndNullable() {\n    return objectWithDefaultAndNullable_String;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.defaultsToNull_CharSequence = (CharSequence) null;\n    this.noDefaultSoItIsRequired_CharSequence = null;\n    this.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = 0;\n    this.primitiveWithExplicitDefault_Int = PropDefaultsView.PRIMITIVE_DEFAULT;\n    this.objectWithDefault_String = PropDefaultsView.STRING_DEFAULT;\n    this.objectWithDefaultAndNullable_String = PropDefaultsView.STRING_DEFAULT;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof PropDefaultsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    PropDefaultsViewModel_ that = (PropDefaultsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((defaultsToNull_CharSequence != null ? !defaultsToNull_CharSequence.equals(that.defaultsToNull_CharSequence) : that.defaultsToNull_CharSequence != null)) {\n      return false;\n    }\n    if ((noDefaultSoItIsRequired_CharSequence != null ? !noDefaultSoItIsRequired_CharSequence.equals(that.noDefaultSoItIsRequired_CharSequence) : that.noDefaultSoItIsRequired_CharSequence != null)) {\n      return false;\n    }\n    if ((primitivesHaveImplicitDefaultsAndCannotBeRequired_Int != that.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int)) {\n      return false;\n    }\n    if ((primitiveWithExplicitDefault_Int != that.primitiveWithExplicitDefault_Int)) {\n      return false;\n    }\n    if ((objectWithDefault_String != null ? !objectWithDefault_String.equals(that.objectWithDefault_String) : that.objectWithDefault_String != null)) {\n      return false;\n    }\n    if ((objectWithDefaultAndNullable_String != null ? !objectWithDefaultAndNullable_String.equals(that.objectWithDefaultAndNullable_String) : that.objectWithDefaultAndNullable_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (defaultsToNull_CharSequence != null ? defaultsToNull_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (noDefaultSoItIsRequired_CharSequence != null ? noDefaultSoItIsRequired_CharSequence.hashCode() : 0);\n    _result = 31 * _result + primitivesHaveImplicitDefaultsAndCannotBeRequired_Int;\n    _result = 31 * _result + primitiveWithExplicitDefault_Int;\n    _result = 31 * _result + (objectWithDefault_String != null ? objectWithDefault_String.hashCode() : 0);\n    _result = 31 * _result + (objectWithDefaultAndNullable_String != null ? objectWithDefaultAndNullable_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"PropDefaultsViewModel_{\" +\n        \"defaultsToNull_CharSequence=\" + defaultsToNull_CharSequence +\n        \", noDefaultSoItIsRequired_CharSequence=\" + noDefaultSoItIsRequired_CharSequence +\n        \", primitivesHaveImplicitDefaultsAndCannotBeRequired_Int=\" + primitivesHaveImplicitDefaultsAndCannotBeRequired_Int +\n        \", primitiveWithExplicitDefault_Int=\" + primitiveWithExplicitDefault_Int +\n        \", objectWithDefault_String=\" + objectWithDefault_String +\n        \", objectWithDefaultAndNullable_String=\" + objectWithDefaultAndNullable_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView_throwsForNonFinalValue.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView_throwsForNonFinalValue extends View {\n  static int PRIMITIVE_DEFAULT = 23;\n\n  public PropDefaultsView_throwsForNonFinalValue(Context context) {\n    super(context);\n  }\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView_throwsForNonStaticValue.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView_throwsForNonStaticValue extends View {\n  final int PRIMITIVE_DEFAULT = 23;\n\n  public PropDefaultsView_throwsForNonStaticValue(Context context) {\n    super(context);\n  }\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView_throwsForNotFound.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView_throwsForNotFound extends View {\n\n  public PropDefaultsView_throwsForNotFound(Context context) {\n    super(context);\n  }\n\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView_throwsForPrivateValue.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView_throwsForPrivateValue extends View {\n  private static final int PRIMITIVE_DEFAULT = 23;\n\n  public PropDefaultsView_throwsForPrivateValue(Context context) {\n    super(context);\n  }\n\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropDefaultsView_throwsForWrongType.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropDefaultsView_throwsForWrongType extends View {\n  static final String PRIMITIVE_DEFAULT = 23;\n\n  public PropDefaultsView_throwsForWrongType(Context context) {\n    super(context);\n  }\n\n  @ModelProp(defaultValue = \"PRIMITIVE_DEFAULT\")\n  public void primitiveWithExplicitDefault(int title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropGroupsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class PropGroupsView extends View {\n  static final long DEFAULT_PRIMITIVE = 234;\n\n  public PropGroupsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setSomething(@Nullable CharSequence title) {\n    // The default value for this group should be to set null on this prop, since that is clearer\n    // than setting 0 on the primitive prop\n  }\n\n  @ModelProp\n  public void setSomething(int title) {\n    // Implicit grouping by having the same method name\n  }\n\n  @ModelProp\n  public void setSomethingElse(CharSequence title) {\n\n  }\n\n  @ModelProp\n  public void setSomethingElse(int title) {\n    // Implicit grouping by having the same method name\n  }\n\n  @ModelProp\n  public void setPrimitive(int title) {\n  }\n\n  @ModelProp\n  public void setPrimitive(long title) {\n    // Implicit grouping by having the same method name\n    // This should be optional, with the default value being either primitive prop (it is\n    // undefined which is used)\n  }\n\n  @ModelProp\n  public void setPrimitiveWithDefault(int title) {\n  }\n\n  @ModelProp(defaultValue = \"DEFAULT_PRIMITIVE\")\n  public void setPrimitiveWithDefault(long title) {\n    // Implicit grouping by having the same method name\n    // This should be optional, with the specified default\n  }\n\n  @ModelProp(defaultValue = \"DEFAULT_PRIMITIVE\")\n  public void primitiveAndObjectGroupWithPrimitiveDefault(long title) {\n  }\n\n  @ModelProp\n  public void primitiveAndObjectGroupWithPrimitiveDefault(CharSequence title) {\n\n  }\n\n  @ModelProp(group = \"myGroup\")\n  public void setOneThing(long title) {\n  }\n\n  @ModelProp(group = \"myGroup\")\n  public void setAnotherThing(CharSequence title) {\n    // should be in same group because of group key\n  }\n\n  @ModelProp\n  public void requiredGroup(String title) {\n  }\n\n  @ModelProp\n  public void requiredGroup(CharSequence title) {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/PropGroupsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class PropGroupsViewModel_ extends EpoxyModel<PropGroupsView> implements GeneratedModel<PropGroupsView>, PropGroupsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(14);\n\n  private OnModelBoundListener<PropGroupsViewModel_, PropGroupsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<PropGroupsViewModel_, PropGroupsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<PropGroupsViewModel_, PropGroupsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<PropGroupsViewModel_, PropGroupsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @Nullable\n  private CharSequence something_CharSequence = (CharSequence) null;\n\n  /**\n   * Bitset index: 1\n   */\n  private int something_Int = 0;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence somethingElse_CharSequence;\n\n  /**\n   * Bitset index: 3\n   */\n  private int somethingElse_Int = 0;\n\n  /**\n   * Bitset index: 4\n   */\n  private int primitive_Int = 0;\n\n  /**\n   * Bitset index: 5\n   */\n  private long primitive_Long = 0L;\n\n  /**\n   * Bitset index: 6\n   */\n  private int primitiveWithDefault_Int = 0;\n\n  /**\n   * Bitset index: 7\n   */\n  private long primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n\n  /**\n   * Bitset index: 8\n   */\n  private long primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n\n  /**\n   * Bitset index: 9\n   */\n  @NonNull\n  private CharSequence primitiveAndObjectGroupWithPrimitiveDefault_CharSequence;\n\n  /**\n   * Bitset index: 10\n   */\n  private long oneThing_Long = 0L;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private CharSequence anotherThing_CharSequence;\n\n  /**\n   * Bitset index: 12\n   */\n  @NonNull\n  private String requiredGroup_String;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private CharSequence requiredGroup_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(12) && !assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for requiredGroup\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final PropGroupsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final PropGroupsView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(4)) {\n      object.setPrimitive(primitive_Int);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(5)) {\n      object.setPrimitive(primitive_Long);\n    }\n    else {\n      object.setPrimitive(primitive_Int);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(12)) {\n      object.requiredGroup(requiredGroup_String);\n    }\n    else {\n      object.requiredGroup(requiredGroup_CharSequence);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(8)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(9)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_CharSequence);\n    }\n    else {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setOneThing(oneThing_Long);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(11)) {\n      object.setAnotherThing(anotherThing_CharSequence);\n    }\n    else {\n      object.setOneThing(oneThing_Long);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setSomething(something_CharSequence);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setSomething(something_Int);\n    }\n    else {\n      object.setSomething(something_CharSequence);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(2)) {\n      object.setSomethingElse(somethingElse_CharSequence);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(3)) {\n      object.setSomethingElse(somethingElse_Int);\n    }\n    else {\n      object.setSomethingElse(somethingElse_Int);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(6)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Int);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(7)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n    else {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n  }\n\n  @Override\n  public void bind(final PropGroupsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof PropGroupsViewModel_)) {\n      bind(object);\n      return;\n    }\n    PropGroupsViewModel_ that = (PropGroupsViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(4)) {\n      if ((primitive_Int != that.primitive_Int)) {\n        object.setPrimitive(primitive_Int);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(5)) {\n      if ((primitive_Long != that.primitive_Long)) {\n        object.setPrimitive(primitive_Long);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(4) || that.assignedAttributes_epoxyGeneratedModel.get(5)) {\n      object.setPrimitive(primitive_Int);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(12)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(12) || (requiredGroup_String != null ? !requiredGroup_String.equals(that.requiredGroup_String) : that.requiredGroup_String != null)) {\n        object.requiredGroup(requiredGroup_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(13)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(13) || (requiredGroup_CharSequence != null ? !requiredGroup_CharSequence.equals(that.requiredGroup_CharSequence) : that.requiredGroup_CharSequence != null)) {\n        object.requiredGroup(requiredGroup_CharSequence);\n      }\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(8)) {\n      if ((primitiveAndObjectGroupWithPrimitiveDefault_Long != that.primitiveAndObjectGroupWithPrimitiveDefault_Long)) {\n        object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(9)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(9) || (primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? !primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.equals(that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence) : that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null)) {\n        object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_CharSequence);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(8) || that.assignedAttributes_epoxyGeneratedModel.get(9)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      if ((oneThing_Long != that.oneThing_Long)) {\n        object.setOneThing(oneThing_Long);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(11)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(11) || (anotherThing_CharSequence != null ? !anotherThing_CharSequence.equals(that.anotherThing_CharSequence) : that.anotherThing_CharSequence != null)) {\n        object.setAnotherThing(anotherThing_CharSequence);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(10) || that.assignedAttributes_epoxyGeneratedModel.get(11)) {\n      object.setOneThing(oneThing_Long);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (something_CharSequence != null ? !something_CharSequence.equals(that.something_CharSequence) : that.something_CharSequence != null)) {\n        object.setSomething(something_CharSequence);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((something_Int != that.something_Int)) {\n        object.setSomething(something_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setSomething(something_CharSequence);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(2)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(2) || (somethingElse_CharSequence != null ? !somethingElse_CharSequence.equals(that.somethingElse_CharSequence) : that.somethingElse_CharSequence != null)) {\n        object.setSomethingElse(somethingElse_CharSequence);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(3)) {\n      if ((somethingElse_Int != that.somethingElse_Int)) {\n        object.setSomethingElse(somethingElse_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(2) || that.assignedAttributes_epoxyGeneratedModel.get(3)) {\n      object.setSomethingElse(somethingElse_Int);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(6)) {\n      if ((primitiveWithDefault_Int != that.primitiveWithDefault_Int)) {\n        object.setPrimitiveWithDefault(primitiveWithDefault_Int);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(7)) {\n      if ((primitiveWithDefault_Long != that.primitiveWithDefault_Long)) {\n        object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(6) || that.assignedAttributes_epoxyGeneratedModel.get(7)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final PropGroupsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropGroupsViewModel_ onBind(\n      OnModelBoundListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(PropGroupsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropGroupsViewModel_ onUnbind(\n      OnModelUnboundListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final PropGroupsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropGroupsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final PropGroupsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropGroupsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see PropGroupsView#setSomething(CharSequence)\n   */\n  public PropGroupsViewModel_ something(@Nullable CharSequence something) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.something_Int = 0;\n    onMutation();\n    this.something_CharSequence = something;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence somethingCharSequence() {\n    return something_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setSomething(int)\n   */\n  public PropGroupsViewModel_ something(int something) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.something_CharSequence = (CharSequence) null;\n    onMutation();\n    this.something_Int = something;\n    return this;\n  }\n\n  public int somethingInt() {\n    return something_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#setSomethingElse(CharSequence)\n   */\n  public PropGroupsViewModel_ somethingElse(@NonNull CharSequence somethingElse) {\n    if (somethingElse == null) {\n      throw new IllegalArgumentException(\"somethingElse cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    assignedAttributes_epoxyGeneratedModel.clear(3);\n    this.somethingElse_Int = 0;\n    onMutation();\n    this.somethingElse_CharSequence = somethingElse;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence somethingElseCharSequence() {\n    return somethingElse_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setSomethingElse(int)\n   */\n  public PropGroupsViewModel_ somethingElse(int somethingElse) {\n    assignedAttributes_epoxyGeneratedModel.set(3);\n    assignedAttributes_epoxyGeneratedModel.clear(2);\n    this.somethingElse_CharSequence = null;\n    onMutation();\n    this.somethingElse_Int = somethingElse;\n    return this;\n  }\n\n  public int somethingElseInt() {\n    return somethingElse_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setPrimitive(int)\n   */\n  public PropGroupsViewModel_ primitive(int primitive) {\n    assignedAttributes_epoxyGeneratedModel.set(4);\n    assignedAttributes_epoxyGeneratedModel.clear(5);\n    this.primitive_Long = 0L;\n    onMutation();\n    this.primitive_Int = primitive;\n    return this;\n  }\n\n  public int primitiveInt() {\n    return primitive_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see PropGroupsView#setPrimitive(long)\n   */\n  public PropGroupsViewModel_ primitive(long primitive) {\n    assignedAttributes_epoxyGeneratedModel.set(5);\n    assignedAttributes_epoxyGeneratedModel.clear(4);\n    this.primitive_Int = 0;\n    onMutation();\n    this.primitive_Long = primitive;\n    return this;\n  }\n\n  public long primitiveLong() {\n    return primitive_Long;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setPrimitiveWithDefault(int)\n   */\n  public PropGroupsViewModel_ primitiveWithDefault(int primitiveWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    assignedAttributes_epoxyGeneratedModel.clear(7);\n    this.primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    onMutation();\n    this.primitiveWithDefault_Int = primitiveWithDefault;\n    return this;\n  }\n\n  public int primitiveWithDefaultInt() {\n    return primitiveWithDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropGroupsView#DEFAULT_PRIMITIVE}</b>\n   *\n   * @see PropGroupsView#setPrimitiveWithDefault(long)\n   */\n  public PropGroupsViewModel_ primitiveWithDefault(long primitiveWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(7);\n    assignedAttributes_epoxyGeneratedModel.clear(6);\n    this.primitiveWithDefault_Int = 0;\n    onMutation();\n    this.primitiveWithDefault_Long = primitiveWithDefault;\n    return this;\n  }\n\n  public long primitiveWithDefaultLong() {\n    return primitiveWithDefault_Long;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropGroupsView#DEFAULT_PRIMITIVE}</b>\n   *\n   * @see PropGroupsView#primitiveAndObjectGroupWithPrimitiveDefault(long)\n   */\n  public PropGroupsViewModel_ primitiveAndObjectGroupWithPrimitiveDefault(\n      long primitiveAndObjectGroupWithPrimitiveDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    assignedAttributes_epoxyGeneratedModel.clear(9);\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = null;\n    onMutation();\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = primitiveAndObjectGroupWithPrimitiveDefault;\n    return this;\n  }\n\n  public long primitiveAndObjectGroupWithPrimitiveDefaultLong() {\n    return primitiveAndObjectGroupWithPrimitiveDefault_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#primitiveAndObjectGroupWithPrimitiveDefault(CharSequence)\n   */\n  public PropGroupsViewModel_ primitiveAndObjectGroupWithPrimitiveDefault(\n      @NonNull CharSequence primitiveAndObjectGroupWithPrimitiveDefault) {\n    if (primitiveAndObjectGroupWithPrimitiveDefault == null) {\n      throw new IllegalArgumentException(\"primitiveAndObjectGroupWithPrimitiveDefault cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(9);\n    assignedAttributes_epoxyGeneratedModel.clear(8);\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    onMutation();\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = primitiveAndObjectGroupWithPrimitiveDefault;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence primitiveAndObjectGroupWithPrimitiveDefaultCharSequence() {\n    return primitiveAndObjectGroupWithPrimitiveDefault_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see PropGroupsView#setOneThing(long)\n   */\n  public PropGroupsViewModel_ oneThing(long oneThing) {\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    assignedAttributes_epoxyGeneratedModel.clear(11);\n    this.anotherThing_CharSequence = null;\n    onMutation();\n    this.oneThing_Long = oneThing;\n    return this;\n  }\n\n  public long oneThingLong() {\n    return oneThing_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#setAnotherThing(CharSequence)\n   */\n  public PropGroupsViewModel_ anotherThing(@NonNull CharSequence anotherThing) {\n    if (anotherThing == null) {\n      throw new IllegalArgumentException(\"anotherThing cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    assignedAttributes_epoxyGeneratedModel.clear(10);\n    this.oneThing_Long = 0L;\n    onMutation();\n    this.anotherThing_CharSequence = anotherThing;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence anotherThingCharSequence() {\n    return anotherThing_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#requiredGroup(String)\n   */\n  public PropGroupsViewModel_ requiredGroup(@NonNull String requiredGroup) {\n    if (requiredGroup == null) {\n      throw new IllegalArgumentException(\"requiredGroup cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(12);\n    assignedAttributes_epoxyGeneratedModel.clear(13);\n    this.requiredGroup_CharSequence = null;\n    onMutation();\n    this.requiredGroup_String = requiredGroup;\n    return this;\n  }\n\n  @NonNull\n  public String requiredGroupString() {\n    return requiredGroup_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#requiredGroup(CharSequence)\n   */\n  public PropGroupsViewModel_ requiredGroup(@NonNull CharSequence requiredGroup) {\n    if (requiredGroup == null) {\n      throw new IllegalArgumentException(\"requiredGroup cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    assignedAttributes_epoxyGeneratedModel.clear(12);\n    this.requiredGroup_String = null;\n    onMutation();\n    this.requiredGroup_CharSequence = requiredGroup;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence requiredGroupCharSequence() {\n    return requiredGroup_CharSequence;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public PropGroupsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.something_CharSequence = (CharSequence) null;\n    this.something_Int = 0;\n    this.somethingElse_CharSequence = null;\n    this.somethingElse_Int = 0;\n    this.primitive_Int = 0;\n    this.primitive_Long = 0L;\n    this.primitiveWithDefault_Int = 0;\n    this.primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = null;\n    this.oneThing_Long = 0L;\n    this.anotherThing_CharSequence = null;\n    this.requiredGroup_String = null;\n    this.requiredGroup_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof PropGroupsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    PropGroupsViewModel_ that = (PropGroupsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((something_CharSequence != null ? !something_CharSequence.equals(that.something_CharSequence) : that.something_CharSequence != null)) {\n      return false;\n    }\n    if ((something_Int != that.something_Int)) {\n      return false;\n    }\n    if ((somethingElse_CharSequence != null ? !somethingElse_CharSequence.equals(that.somethingElse_CharSequence) : that.somethingElse_CharSequence != null)) {\n      return false;\n    }\n    if ((somethingElse_Int != that.somethingElse_Int)) {\n      return false;\n    }\n    if ((primitive_Int != that.primitive_Int)) {\n      return false;\n    }\n    if ((primitive_Long != that.primitive_Long)) {\n      return false;\n    }\n    if ((primitiveWithDefault_Int != that.primitiveWithDefault_Int)) {\n      return false;\n    }\n    if ((primitiveWithDefault_Long != that.primitiveWithDefault_Long)) {\n      return false;\n    }\n    if ((primitiveAndObjectGroupWithPrimitiveDefault_Long != that.primitiveAndObjectGroupWithPrimitiveDefault_Long)) {\n      return false;\n    }\n    if ((primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? !primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.equals(that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence) : that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null)) {\n      return false;\n    }\n    if ((oneThing_Long != that.oneThing_Long)) {\n      return false;\n    }\n    if ((anotherThing_CharSequence != null ? !anotherThing_CharSequence.equals(that.anotherThing_CharSequence) : that.anotherThing_CharSequence != null)) {\n      return false;\n    }\n    if ((requiredGroup_String != null ? !requiredGroup_String.equals(that.requiredGroup_String) : that.requiredGroup_String != null)) {\n      return false;\n    }\n    if ((requiredGroup_CharSequence != null ? !requiredGroup_CharSequence.equals(that.requiredGroup_CharSequence) : that.requiredGroup_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (something_CharSequence != null ? something_CharSequence.hashCode() : 0);\n    _result = 31 * _result + something_Int;\n    _result = 31 * _result + (somethingElse_CharSequence != null ? somethingElse_CharSequence.hashCode() : 0);\n    _result = 31 * _result + somethingElse_Int;\n    _result = 31 * _result + primitive_Int;\n    _result = 31 * _result + (int) (primitive_Long ^ (primitive_Long >>> 32));\n    _result = 31 * _result + primitiveWithDefault_Int;\n    _result = 31 * _result + (int) (primitiveWithDefault_Long ^ (primitiveWithDefault_Long >>> 32));\n    _result = 31 * _result + (int) (primitiveAndObjectGroupWithPrimitiveDefault_Long ^ (primitiveAndObjectGroupWithPrimitiveDefault_Long >>> 32));\n    _result = 31 * _result + (primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (int) (oneThing_Long ^ (oneThing_Long >>> 32));\n    _result = 31 * _result + (anotherThing_CharSequence != null ? anotherThing_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (requiredGroup_String != null ? requiredGroup_String.hashCode() : 0);\n    _result = 31 * _result + (requiredGroup_CharSequence != null ? requiredGroup_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"PropGroupsViewModel_{\" +\n        \"something_CharSequence=\" + something_CharSequence +\n        \", something_Int=\" + something_Int +\n        \", somethingElse_CharSequence=\" + somethingElse_CharSequence +\n        \", somethingElse_Int=\" + somethingElse_Int +\n        \", primitive_Int=\" + primitive_Int +\n        \", primitive_Long=\" + primitive_Long +\n        \", primitiveWithDefault_Int=\" + primitiveWithDefault_Int +\n        \", primitiveWithDefault_Long=\" + primitiveWithDefault_Long +\n        \", primitiveAndObjectGroupWithPrimitiveDefault_Long=\" + primitiveAndObjectGroupWithPrimitiveDefault_Long +\n        \", primitiveAndObjectGroupWithPrimitiveDefault_CharSequence=\" + primitiveAndObjectGroupWithPrimitiveDefault_CharSequence +\n        \", oneThing_Long=\" + oneThing_Long +\n        \", anotherThing_CharSequence=\" + anotherThing_CharSequence +\n        \", requiredGroup_String=\" + requiredGroup_String +\n        \", requiredGroup_CharSequence=\" + requiredGroup_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/Prop_throwsIfMultipleParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class Prop_throwsIfMultipleParams extends View {\n\n  public Prop_throwsIfMultipleParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle(CharSequence title, int prop) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/Prop_throwsIfNoParams.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class Prop_throwsIfNoParams extends View {\n\n  public Prop_throwsIfNoParams(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setTitle() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/Prop_throwsIfPrivate.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class Prop_throwsIfPrivate extends View {\n\n  public Prop_throwsIfPrivate(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  private void setTitle(CharSequence title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/Prop_throwsIfStatic.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class Prop_throwsIfStatic extends View {\n\n  public Prop_throwsIfStatic(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public static void setTitle(CharSequence title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/RLayoutInViewModelAnnotationWorksViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class RLayoutInViewModelAnnotationWorksViewModel_ extends EpoxyModel<RLayoutInViewModelAnnotationWorksView> implements GeneratedModel<RLayoutInViewModelAnnotationWorksView>, RLayoutInViewModelAnnotationWorksViewModelBuilder {\n  private OnModelBoundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final RLayoutInViewModelAnnotationWorksView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final RLayoutInViewModelAnnotationWorksView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final RLayoutInViewModelAnnotationWorksView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof RLayoutInViewModelAnnotationWorksViewModel_)) {\n      bind(object);\n      return;\n    }\n    RLayoutInViewModelAnnotationWorksViewModel_ that = (RLayoutInViewModelAnnotationWorksViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final RLayoutInViewModelAnnotationWorksView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onBind(\n      OnModelBoundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(RLayoutInViewModelAnnotationWorksView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onUnbind(\n      OnModelUnboundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final RLayoutInViewModelAnnotationWorksView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final RLayoutInViewModelAnnotationWorksView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.res;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof RLayoutInViewModelAnnotationWorksViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    RLayoutInViewModelAnnotationWorksViewModel_ that = (RLayoutInViewModelAnnotationWorksViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"RLayoutInViewModelAnnotationWorksViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/RequireAbstractModelFailsClassWithAttribute.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class RequireAbstractModelFailsClassWithAttribute extends EpoxyModel<Object> {\n\n  @EpoxyAttribute String value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/RequireAbstractModelFailsEpoxyModelClass.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\n\n@EpoxyModelClass\npublic class RequireAbstractModelFailsEpoxyModelClass extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/RequireAbstractModelPassesClassWithAttribute.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic abstract class RequireAbstractModelPassesClassWithAttribute extends EpoxyModel<Object> {\n\n  @EpoxyAttribute String value;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/RequireAbstractModelPassesEpoxyModelClass.java",
    "content": "package com.airbnb.epoxy.configtest;\n\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelClass;\n\n@EpoxyModelClass\npublic abstract class RequireAbstractModelPassesEpoxyModelClass extends EpoxyModel<Object> {\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/SavedStateView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1, saveViewState = true)\npublic class SavedStateView extends View {\n\n  public SavedStateView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setClickListener(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/SavedStateViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SavedStateViewModel_ extends EpoxyModel<SavedStateView> implements GeneratedModel<SavedStateView>, SavedStateViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<SavedStateViewModel_, SavedStateView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SavedStateViewModel_, SavedStateView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SavedStateViewModel_, SavedStateView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SavedStateViewModel_, SavedStateView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SavedStateView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SavedStateView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final SavedStateView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SavedStateViewModel_)) {\n      bind(object);\n      return;\n    }\n    SavedStateViewModel_ that = (SavedStateViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SavedStateView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SavedStateViewModel_ onBind(\n      OnModelBoundListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SavedStateView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SavedStateViewModel_ onUnbind(\n      OnModelUnboundListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SavedStateView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SavedStateViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SavedStateView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SavedStateViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see SavedStateView#setClickListener(String)\n   */\n  public SavedStateViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public SavedStateViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SavedStateViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SavedStateViewModel_ that = (SavedStateViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SavedStateViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public boolean shouldSaveViewState() {\n    return true;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/StringOverloads_throwsIfNotCharSequence.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class StringOverloads_throwsIfNotCharSequence extends View {\n\n  public StringOverloads_throwsIfNotCharSequence(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = ModelProp.Option.GenerateStringOverloads)\n  public void setTitle(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestAfterBindPropsSuperView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic abstract class TestAfterBindPropsSuperView extends View {\n\n  public TestAfterBindPropsSuperView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setFlagSuper(boolean flag) {\n\n  }\n\n  @AfterPropsSet\n  public void afterFlagSetSuper() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestAfterBindPropsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\n\n@ModelView(defaultLayout = 1)\npublic class TestAfterBindPropsView extends TestAfterBindPropsSuperView {\n\n  public TestAfterBindPropsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setFlag(boolean flag) {\n\n  }\n\n  @AfterPropsSet\n  public void afterFlagSet() {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestAfterBindPropsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestAfterBindPropsViewModel_ extends EpoxyModel<TestAfterBindPropsView> implements GeneratedModel<TestAfterBindPropsView>, TestAfterBindPropsViewModelBuilder {\n  private OnModelBoundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private boolean flag_Boolean = false;\n\n  private boolean flagSuper_Boolean = false;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestAfterBindPropsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestAfterBindPropsView object) {\n    super.bind(object);\n    object.setFlagSuper(flagSuper_Boolean);\n    object.setFlag(flag_Boolean);\n  }\n\n  @Override\n  public void bind(final TestAfterBindPropsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestAfterBindPropsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestAfterBindPropsViewModel_ that = (TestAfterBindPropsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((flagSuper_Boolean != that.flagSuper_Boolean)) {\n      object.setFlagSuper(flagSuper_Boolean);\n    }\n\n    if ((flag_Boolean != that.flag_Boolean)) {\n      object.setFlag(flag_Boolean);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestAfterBindPropsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterFlagSet();\n    object.afterFlagSetSuper();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestAfterBindPropsViewModel_ onBind(\n      OnModelBoundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestAfterBindPropsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestAfterBindPropsViewModel_ onUnbind(\n      OnModelUnboundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestAfterBindPropsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestAfterBindPropsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestAfterBindPropsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestAfterBindPropsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestAfterBindPropsView#setFlag(boolean)\n   */\n  public TestAfterBindPropsViewModel_ flag(boolean flag) {\n    onMutation();\n    this.flag_Boolean = flag;\n    return this;\n  }\n\n  public boolean flag() {\n    return flag_Boolean;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestAfterBindPropsSuperView#setFlagSuper(boolean)\n   */\n  public TestAfterBindPropsViewModel_ flagSuper(boolean flagSuper) {\n    onMutation();\n    this.flagSuper_Boolean = flagSuper;\n    return this;\n  }\n\n  public boolean flagSuper() {\n    return flagSuper_Boolean;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.flag_Boolean = false;\n    this.flagSuper_Boolean = false;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestAfterBindPropsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestAfterBindPropsViewModel_ that = (TestAfterBindPropsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((flag_Boolean != that.flag_Boolean)) {\n      return false;\n    }\n    if ((flagSuper_Boolean != that.flagSuper_Boolean)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (flag_Boolean ? 1 : 0);\n    _result = 31 * _result + (flagSuper_Boolean ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestAfterBindPropsViewModel_{\" +\n        \"flag_Boolean=\" + flag_Boolean +\n        \", flagSuper_Boolean=\" + flagSuper_Boolean +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestCallbackPropMustBeNullableView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TestCallbackPropMustBeNullableView extends View {\n\n  public TestCallbackPropMustBeNullableView(Context context) {\n    super(context);\n  }\n\n  @CallbackProp\n  public void setListener(View.OnClickListener clickListener) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestCallbackPropView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TestCallbackPropView extends View {\n\n  public TestCallbackPropView(Context context) {\n    super(context);\n  }\n\n  @CallbackProp\n  public void setListener(@Nullable View.OnClickListener clickListener) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestCallbackPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestCallbackPropViewModel_ extends EpoxyModel<TestCallbackPropView> implements GeneratedModel<TestCallbackPropView>, TestCallbackPropViewModelBuilder {\n  private OnModelBoundListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener listener_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestCallbackPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestCallbackPropView object) {\n    super.bind(object);\n    object.setListener(listener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final TestCallbackPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestCallbackPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestCallbackPropViewModel_ that = (TestCallbackPropViewModel_) previousModel;\n    super.bind(object);\n\n    if (((listener_OnClickListener == null) != (that.listener_OnClickListener == null))) {\n      object.setListener(listener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestCallbackPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestCallbackPropViewModel_ onBind(\n      OnModelBoundListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestCallbackPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setListener((View.OnClickListener) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestCallbackPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestCallbackPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestCallbackPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestCallbackPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestCallbackPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestCallbackPropViewModel_ listener(\n      @Nullable final OnModelClickListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    if (listener == null) {\n      this.listener_OnClickListener = null;\n    }\n    else {\n      this.listener_OnClickListener = new WrappedEpoxyModelClickListener<>(listener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestCallbackPropView#setListener(View.OnClickListener)\n   */\n  public TestCallbackPropViewModel_ listener(@Nullable View.OnClickListener listener) {\n    onMutation();\n    this.listener_OnClickListener = listener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener listener() {\n    return listener_OnClickListener;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.listener_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestCallbackPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestCallbackPropViewModel_ that = (TestCallbackPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((listener_OnClickListener == null) != (that.listener_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (listener_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestCallbackPropViewModel_{\" +\n        \"listener_OnClickListener=\" + listener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropCallbackPropView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.CallbackProp;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\npublic class TestFieldPropCallbackPropView extends View {\n  @CallbackProp @Nullable OnClickListener value;\n\n  public TestFieldPropCallbackPropView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() { }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropCallbackPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropCallbackPropViewModel_ extends EpoxyModel<TestFieldPropCallbackPropView> implements GeneratedModel<TestFieldPropCallbackPropView>, TestFieldPropCallbackPropViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropView buildView(ViewGroup parent) {\n    TestFieldPropCallbackPropView v = new TestFieldPropCallbackPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropCallbackPropView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropCallbackPropView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropCallbackPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropCallbackPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropCallbackPropViewModel_ that = (TestFieldPropCallbackPropViewModel_) previousModel;\n    super.bind(object);\n\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropCallbackPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropCallbackPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropCallbackPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropCallbackPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropCallbackPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropCallbackPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropCallbackPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropCallbackPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropCallbackPropViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropCallbackPropView#value\n   */\n  public TestFieldPropCallbackPropViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropCallbackPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropCallbackPropViewModel_ that = (TestFieldPropCallbackPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropCallbackPropViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropChildView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\n\nimport com.airbnb.epoxy.ModelView;\nimport com.airbnb.epoxy.TextProp;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropChildView extends TestFieldPropParentView {\n @TextProp CharSequence textValue;\n\n public TestFieldPropChildView(Context context) {\n   super(context);\n }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropChildViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\nimport javax.annotation.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropChildViewModel_ extends EpoxyModel<TestFieldPropChildView> implements GeneratedModel<TestFieldPropChildView>, TestFieldPropChildViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData textValue_StringAttributeData =  new StringAttributeData();\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for textValue\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropChildView buildView(ViewGroup parent) {\n    TestFieldPropChildView v = new TestFieldPropChildView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropChildView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropChildView object) {\n    super.bind(object);\n    object.textValue = textValue_StringAttributeData.toString(object.getContext());\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropChildView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropChildViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropChildViewModel_ that = (TestFieldPropChildViewModel_) previousModel;\n    super.bind(object);\n\n    if ((textValue_StringAttributeData != null ? !textValue_StringAttributeData.equals(that.textValue_StringAttributeData) : that.textValue_StringAttributeData != null)) {\n      object.textValue = textValue_StringAttributeData.toString(object.getContext());\n    }\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropChildView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropChildViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropChildView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropChildViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestFieldPropChildView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropChildViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropChildView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropChildViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTextValue(Context context) {\n    return textValue_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@NonNull CharSequence textValue) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (textValue == null) {\n      throw new IllegalArgumentException(\"textValue cannot be null\");\n    }\n    textValue_StringAttributeData.setValue(textValue);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValueQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropChildViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropChildViewModel_, TestFieldPropChildView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropParentView#value\n   */\n  public TestFieldPropChildViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.textValue_StringAttributeData =  new StringAttributeData();\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropChildViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropChildViewModel_ that = (TestFieldPropChildViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((textValue_StringAttributeData != null ? !textValue_StringAttributeData.equals(that.textValue_StringAttributeData) : that.textValue_StringAttributeData != null)) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (textValue_StringAttributeData != null ? textValue_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropChildViewModel_{\" +\n        \"textValue_StringAttributeData=\" + textValue_StringAttributeData +\n        \", value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropDoNotHashOptionView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropDoNotHashOptionView extends View {\n  @ModelProp(options = Option.DoNotHash) OnClickListener value;\n\n  public TestFieldPropDoNotHashOptionView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropDoNotHashOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropDoNotHashOptionViewModel_ extends EpoxyModel<TestFieldPropDoNotHashOptionView> implements GeneratedModel<TestFieldPropDoNotHashOptionView>, TestFieldPropDoNotHashOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener value_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionView buildView(ViewGroup parent) {\n    TestFieldPropDoNotHashOptionView v = new TestFieldPropDoNotHashOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropDoNotHashOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropDoNotHashOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropDoNotHashOptionView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropDoNotHashOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropDoNotHashOptionViewModel_ that = (TestFieldPropDoNotHashOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropDoNotHashOptionView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropDoNotHashOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropDoNotHashOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropDoNotHashOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ value(\n      @NonNull final OnModelClickListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> value) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropDoNotHashOptionView#value\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ value(@NonNull View.OnClickListener value) {\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropDoNotHashOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropDoNotHashOptionViewModel_ that = (TestFieldPropDoNotHashOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropDoNotHashOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropGenerateStringOverloadsOptionView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropGenerateStringOverloadsOptionView extends View {\n  @ModelProp(options = Option.GenerateStringOverloads) CharSequence value;\n\n  public TestFieldPropGenerateStringOverloadsOptionView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropGenerateStringOverloadsOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropGenerateStringOverloadsOptionViewModel_ extends EpoxyModel<TestFieldPropGenerateStringOverloadsOptionView> implements GeneratedModel<TestFieldPropGenerateStringOverloadsOptionView>, TestFieldPropGenerateStringOverloadsOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData value_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionView buildView(ViewGroup parent) {\n    TestFieldPropGenerateStringOverloadsOptionView v = new TestFieldPropGenerateStringOverloadsOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropGenerateStringOverloadsOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropGenerateStringOverloadsOptionView object) {\n    super.bind(object);\n    object.value = value_StringAttributeData.toString(object.getContext());\n  }\n\n  @Override\n  public void bind(final TestFieldPropGenerateStringOverloadsOptionView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropGenerateStringOverloadsOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropGenerateStringOverloadsOptionViewModel_ that = (TestFieldPropGenerateStringOverloadsOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      object.value = value_StringAttributeData.toString(object.getContext());\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropGenerateStringOverloadsOptionView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropGenerateStringOverloadsOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropGenerateStringOverloadsOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final TestFieldPropGenerateStringOverloadsOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getValue(Context context) {\n    return value_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@NonNull CharSequence value) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    value_StringAttributeData.setValue(value);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ valueQuantityRes(\n      @PluralsRes int pluralRes, int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropGenerateStringOverloadsOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropGenerateStringOverloadsOptionViewModel_ that = (TestFieldPropGenerateStringOverloadsOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_StringAttributeData != null ? value_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropGenerateStringOverloadsOptionViewModel_{\" +\n        \"value_StringAttributeData=\" + value_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropIgnoreRequireHashCodeOptionView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropIgnoreRequireHashCodeOptionView extends View {\n  @ModelProp(options = Option.IgnoreRequireHashCode) OnClickListener value;\n\n  public TestFieldPropIgnoreRequireHashCodeOptionView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropIgnoreRequireHashCodeOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropIgnoreRequireHashCodeOptionViewModel_ extends EpoxyModel<TestFieldPropIgnoreRequireHashCodeOptionView> implements GeneratedModel<TestFieldPropIgnoreRequireHashCodeOptionView>, TestFieldPropIgnoreRequireHashCodeOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener value_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionView buildView(ViewGroup parent) {\n    TestFieldPropIgnoreRequireHashCodeOptionView v = new TestFieldPropIgnoreRequireHashCodeOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropIgnoreRequireHashCodeOptionView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropIgnoreRequireHashCodeOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropIgnoreRequireHashCodeOptionViewModel_ that = (TestFieldPropIgnoreRequireHashCodeOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropIgnoreRequireHashCodeOptionView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ value(\n      @NonNull final OnModelClickListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> value) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropIgnoreRequireHashCodeOptionView#value\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ value(\n      @NonNull View.OnClickListener value) {\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence key,\n      long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropIgnoreRequireHashCodeOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropIgnoreRequireHashCodeOptionViewModel_ that = (TestFieldPropIgnoreRequireHashCodeOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropIgnoreRequireHashCodeOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropModelPropView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\npublic class TestFieldPropModelPropView extends View {\n  @ModelProp int value;\n\n  public TestFieldPropModelPropView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() { }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropModelPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropModelPropViewModel_ extends EpoxyModel<TestFieldPropModelPropView> implements GeneratedModel<TestFieldPropModelPropView>, TestFieldPropModelPropViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropModelPropView buildView(ViewGroup parent) {\n    TestFieldPropModelPropView v = new TestFieldPropModelPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropModelPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropModelPropView object) {\n    super.bind(object);\n    object.value = value_Int;\n  }\n\n  @Override\n  public void bind(final TestFieldPropModelPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropModelPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropModelPropViewModel_ that = (TestFieldPropModelPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.value = value_Int;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropModelPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropModelPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropModelPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropModelPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropModelPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropModelPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropModelPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropModelPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestFieldPropModelPropView#value\n   */\n  public TestFieldPropModelPropViewModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropModelPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropModelPropViewModel_ that = (TestFieldPropModelPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropModelPropViewModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropNullOnRecycleOptionView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\nimport javax.annotation.Nullable;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropNullOnRecycleOptionView extends View {\n  @ModelProp(options = {Option.NullOnRecycle, Option.IgnoreRequireHashCode}) @Nullable\n  OnClickListener value;\n\n  public TestFieldPropNullOnRecycleOptionView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropNullOnRecycleOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport javax.annotation.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropNullOnRecycleOptionViewModel_ extends EpoxyModel<TestFieldPropNullOnRecycleOptionView> implements GeneratedModel<TestFieldPropNullOnRecycleOptionView>, TestFieldPropNullOnRecycleOptionViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionView buildView(ViewGroup parent) {\n    TestFieldPropNullOnRecycleOptionView v = new TestFieldPropNullOnRecycleOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropNullOnRecycleOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropNullOnRecycleOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropNullOnRecycleOptionView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropNullOnRecycleOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropNullOnRecycleOptionViewModel_ that = (TestFieldPropNullOnRecycleOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropNullOnRecycleOptionView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropNullOnRecycleOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropNullOnRecycleOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropNullOnRecycleOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropNullOnRecycleOptionView#value\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropNullOnRecycleOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropNullOnRecycleOptionViewModel_ that = (TestFieldPropNullOnRecycleOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropNullOnRecycleOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropParentView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\nimport javax.annotation.Nullable;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropParentView extends View {\n  @ModelProp(options = {Option.NullOnRecycle, Option.IgnoreRequireHashCode}) @Nullable OnClickListener value;\n\n  public TestFieldPropParentView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropStringOverloadsIfNotCharSequenceView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropStringOverloadsIfNotCharSequenceView extends View {\n  @ModelProp(options = Option.GenerateStringOverloads) OnClickListener value;\n\n  public TestFieldPropStringOverloadsIfNotCharSequenceView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropTextPropView.java",
    "content": "package com.airbnb.epoxy;\n\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelView;\nimport com.airbnb.epoxy.TextProp;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\npublic class TestFieldPropTextPropView extends View {\n  @TextProp CharSequence value;\n\n  public TestFieldPropTextPropView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() { }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropTextPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropTextPropViewModel_ extends EpoxyModel<TestFieldPropTextPropView> implements GeneratedModel<TestFieldPropTextPropView>, TestFieldPropTextPropViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData value_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropTextPropView buildView(ViewGroup parent) {\n    TestFieldPropTextPropView v = new TestFieldPropTextPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropTextPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropTextPropView object) {\n    super.bind(object);\n    object.value = value_StringAttributeData.toString(object.getContext());\n  }\n\n  @Override\n  public void bind(final TestFieldPropTextPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropTextPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropTextPropViewModel_ that = (TestFieldPropTextPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      object.value = value_StringAttributeData.toString(object.getContext());\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropTextPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropTextPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropTextPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropTextPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropTextPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropTextPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropTextPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropTextPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getValue(Context context) {\n    return value_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@NonNull CharSequence value) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    value_StringAttributeData.setValue(value);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ valueQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropTextPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropTextPropViewModel_ that = (TestFieldPropTextPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_StringAttributeData != null ? value_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropTextPropViewModel_{\" +\n        \"value_StringAttributeData=\" + value_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropThrowsIfPrivateView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropThrowsIfPrivateView extends View {\n  @ModelProp private String value;\n\n  public TestFieldPropThrowsIfPrivateView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestFieldPropThrowsIfStaticView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestFieldPropThrowsIfStaticView extends View {\n  @ModelProp public static String value;\n\n  public TestFieldPropThrowsIfStaticView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestManyTypesView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.StringRes;\nimport kotlin.jvm.functions.Function3;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.EpoxyModel;\n\nimport java.util.List;\nimport java.util.Map;\n\n@ModelView(defaultLayout = 1)\npublic class TestManyTypesView extends View {\n  public static final int TO_RANGE = 200;\n\n  public TestManyTypesView(Context context) {\n    super(context);\n  }\n\n  // Also testing package private setters\n  @ModelProp\n  void setStringValue(String value) {\n\n  }\n\n  @ModelProp\n  void setNullableStringValue(@Nullable String value) {\n\n  }\n\n  @ModelProp(Option.DoNotHash)\n  void setFunction(Function3<? super Integer, ? super Integer, ? super Integer, Integer> funct) {\n\n  }\n\n  @ModelProp\n  void setIntValue(int value) {\n\n  }\n\n  @ModelProp\n  void setIntValueWithAnnotation(@StringRes int value) {\n\n  }\n\n  @ModelProp\n  void setIntValueWithRangeAnnotation(@IntRange(from = 0, to = TO_RANGE) int value) {\n\n  }\n\n  @ModelProp\n  void setIntValueWithDimenTypeAnnotation(@Dimension(unit = Dimension.DP) int value) {\n\n  }\n\n  @ModelProp\n  void setIntWithMultipleAnnotations(@IntRange(from = 0, to = TO_RANGE) @Dimension(unit = Dimension.DP) int value) {\n\n  }\n\n  @ModelProp\n  void setIntegerValue(Integer value) {\n\n  }\n\n  @ModelProp\n  void setBoolValue(boolean value) {\n\n  }\n\n  @ModelProp\n  void setModels(List<? extends EpoxyModel<?>> models) {\n\n  }\n\n  @ModelProp\n  public void setBooleanValue(Boolean value) {\n\n  }\n\n  @ModelProp\n  public void setArrayValue(String[] value) {\n\n  }\n\n  @ModelProp\n  public void setListValue(List<String> value) {\n\n  }\n\n  @ModelProp\n  public void setMapValue(Map<Integer, Integer> value) {\n\n  }\n\n  @ModelProp(options = Option.DoNotHash)\n  public void setClickListener(View.OnClickListener value) {\n\n  }\n\n  @ModelProp(options = ModelProp.Option.GenerateStringOverloads)\n  public void setTitle(@Nullable CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestManyTypesViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.String;\nimport java.util.List;\nimport java.util.Map;\nimport kotlin.jvm.functions.Function3;\n\n@EpoxyBuildScope\npublic interface TestManyTypesViewModelBuilder {\n  TestManyTypesViewModelBuilder onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder stringValue(@NonNull String stringValue);\n\n  TestManyTypesViewModelBuilder nullableStringValue(@Nullable String nullableStringValue);\n\n  TestManyTypesViewModelBuilder function(\n      @NonNull Function3<? super Integer, ? super Integer, ? super Integer, Integer> function);\n\n  TestManyTypesViewModelBuilder intValue(int intValue);\n\n  TestManyTypesViewModelBuilder intValueWithAnnotation(@StringRes int intValueWithAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation);\n\n  TestManyTypesViewModelBuilder intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations);\n\n  TestManyTypesViewModelBuilder integerValue(@NonNull Integer integerValue);\n\n  TestManyTypesViewModelBuilder boolValue(boolean boolValue);\n\n  TestManyTypesViewModelBuilder models(@NonNull List<? extends EpoxyModel<?>> models);\n\n  TestManyTypesViewModelBuilder booleanValue(@NonNull Boolean booleanValue);\n\n  TestManyTypesViewModelBuilder arrayValue(@NonNull String[] arrayValue);\n\n  TestManyTypesViewModelBuilder listValue(@NonNull List<String> listValue);\n\n  TestManyTypesViewModelBuilder mapValue(@NonNull Map<Integer, Integer> mapValue);\n\n  TestManyTypesViewModelBuilder clickListener(\n      @NonNull final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener);\n\n  TestManyTypesViewModelBuilder clickListener(@NonNull View.OnClickListener clickListener);\n\n  TestManyTypesViewModelBuilder title(@Nullable CharSequence title);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes, Object... formatArgs);\n\n  TestManyTypesViewModelBuilder titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs);\n\n  TestManyTypesViewModelBuilder id(long id);\n\n  TestManyTypesViewModelBuilder id(@Nullable Number... ids);\n\n  TestManyTypesViewModelBuilder id(long id1, long id2);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence key);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence key, long id);\n\n  TestManyTypesViewModelBuilder layout(@LayoutRes int layoutRes);\n\n  TestManyTypesViewModelBuilder spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestManyTypesViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport java.util.Map;\nimport kotlin.jvm.functions.Function3;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestManyTypesViewModel_ extends EpoxyModel<TestManyTypesView> implements GeneratedModel<TestManyTypesView>, TestManyTypesViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(17);\n\n  private OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String stringValue_String;\n\n  @Nullable\n  private String nullableStringValue_String = (String) null;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private Function3<? super Integer, ? super Integer, ? super Integer, Integer> function_Function3;\n\n  private int intValue_Int = 0;\n\n  @StringRes\n  private int intValueWithAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  private int intValueWithRangeAnnotation_Int = 0;\n\n  @Dimension(\n      unit = 0\n  )\n  private int intValueWithDimenTypeAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  private int intWithMultipleAnnotations_Int = 0;\n\n  /**\n   * Bitset index: 8\n   */\n  @NonNull\n  private Integer integerValue_Integer;\n\n  private boolean boolValue_Boolean = false;\n\n  /**\n   * Bitset index: 10\n   */\n  @NonNull\n  private List<? extends EpoxyModel<?>> models_List;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private Boolean booleanValue_Boolean;\n\n  /**\n   * Bitset index: 12\n   */\n  @NonNull\n  private String[] arrayValue_StringArray;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private List<String> listValue_List;\n\n  /**\n   * Bitset index: 14\n   */\n  @NonNull\n  private Map<Integer, Integer> mapValue_Map;\n\n  /**\n   * Bitset index: 15\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(14)) {\n    \tthrow new IllegalStateException(\"A value is required for setMapValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(12)) {\n    \tthrow new IllegalStateException(\"A value is required for setArrayValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(15)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(11)) {\n    \tthrow new IllegalStateException(\"A value is required for setBooleanValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(8)) {\n    \tthrow new IllegalStateException(\"A value is required for setIntegerValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for setListValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setFunction\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(10)) {\n    \tthrow new IllegalStateException(\"A value is required for setModels\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestManyTypesView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object) {\n    super.bind(object);\n    object.setMapValue(mapValue_Map);\n    object.setArrayValue(arrayValue_StringArray);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    object.setStringValue(stringValue_String);\n    object.setNullableStringValue(nullableStringValue_String);\n    object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    object.setIntegerValue(integerValue_Integer);\n    object.setListValue(listValue_List);\n    object.setIntValue(intValue_Int);\n    object.setFunction(function_Function3);\n    object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    object.setBoolValue(boolValue_Boolean);\n    object.setModels(models_List);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestManyTypesViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) previousModel;\n    super.bind(object);\n\n    if ((mapValue_Map != null ? !mapValue_Map.equals(that.mapValue_Map) : that.mapValue_Map != null)) {\n      object.setMapValue(mapValue_Map);\n    }\n\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      object.setArrayValue(arrayValue_StringArray);\n    }\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      object.setNullableStringValue(nullableStringValue_String);\n    }\n\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    }\n\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    }\n\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    }\n\n    if ((integerValue_Integer != null ? !integerValue_Integer.equals(that.integerValue_Integer) : that.integerValue_Integer != null)) {\n      object.setIntegerValue(integerValue_Integer);\n    }\n\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      object.setListValue(listValue_List);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if (((function_Function3 == null) != (that.function_Function3 == null))) {\n      object.setFunction(function_Function3);\n    }\n\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    }\n\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      object.setBoolValue(boolValue_Boolean);\n    }\n\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      object.setModels(models_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestManyTypesView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestManyTypesView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestManyTypesView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestManyTypesView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setStringValue(String)\n   */\n  public TestManyTypesViewModel_ stringValue(@NonNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NonNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see TestManyTypesView#setNullableStringValue(String)\n   */\n  public TestManyTypesViewModel_ nullableStringValue(@Nullable String nullableStringValue) {\n    onMutation();\n    this.nullableStringValue_String = nullableStringValue;\n    return this;\n  }\n\n  @Nullable\n  public String nullableStringValue() {\n    return nullableStringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setFunction(Function3<? super Integer, ? super Integer, ? super Integer, Integer>)\n   */\n  public TestManyTypesViewModel_ function(\n      @NonNull Function3<? super Integer, ? super Integer, ? super Integer, Integer> function) {\n    if (function == null) {\n      throw new IllegalArgumentException(\"function cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.function_Function3 = function;\n    return this;\n  }\n\n  @NonNull\n  public Function3<? super Integer, ? super Integer, ? super Integer, Integer> function() {\n    return function_Function3;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValue(int)\n   */\n  public TestManyTypesViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithAnnotation(@StringRes int intValueWithAnnotation) {\n    onMutation();\n    this.intValueWithAnnotation_Int = intValueWithAnnotation;\n    return this;\n  }\n\n  @StringRes\n  public int intValueWithAnnotation() {\n    return intValueWithAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithRangeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation) {\n    onMutation();\n    this.intValueWithRangeAnnotation_Int = intValueWithRangeAnnotation;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  public int intValueWithRangeAnnotation() {\n    return intValueWithRangeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithDimenTypeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation) {\n    onMutation();\n    this.intValueWithDimenTypeAnnotation_Int = intValueWithDimenTypeAnnotation;\n    return this;\n  }\n\n  @Dimension(\n      unit = 0\n  )\n  public int intValueWithDimenTypeAnnotation() {\n    return intValueWithDimenTypeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntWithMultipleAnnotations(int)\n   */\n  public TestManyTypesViewModel_ intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations) {\n    onMutation();\n    this.intWithMultipleAnnotations_Int = intWithMultipleAnnotations;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  public int intWithMultipleAnnotations() {\n    return intWithMultipleAnnotations_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setIntegerValue(Integer)\n   */\n  public TestManyTypesViewModel_ integerValue(@NonNull Integer integerValue) {\n    if (integerValue == null) {\n      throw new IllegalArgumentException(\"integerValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    onMutation();\n    this.integerValue_Integer = integerValue;\n    return this;\n  }\n\n  @NonNull\n  public Integer integerValue() {\n    return integerValue_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestManyTypesView#setBoolValue(boolean)\n   */\n  public TestManyTypesViewModel_ boolValue(boolean boolValue) {\n    onMutation();\n    this.boolValue_Boolean = boolValue;\n    return this;\n  }\n\n  public boolean boolValue() {\n    return boolValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setModels(List<? extends EpoxyModel<?>>)\n   */\n  public TestManyTypesViewModel_ models(@NonNull List<? extends EpoxyModel<?>> models) {\n    if (models == null) {\n      throw new IllegalArgumentException(\"models cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.models_List = models;\n    return this;\n  }\n\n  @NonNull\n  public List<? extends EpoxyModel<?>> models() {\n    return models_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setBooleanValue(Boolean)\n   */\n  public TestManyTypesViewModel_ booleanValue(@NonNull Boolean booleanValue) {\n    if (booleanValue == null) {\n      throw new IllegalArgumentException(\"booleanValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  @NonNull\n  public Boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setArrayValue(String[])\n   */\n  public TestManyTypesViewModel_ arrayValue(@NonNull String[] arrayValue) {\n    if (arrayValue == null) {\n      throw new IllegalArgumentException(\"arrayValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(12);\n    onMutation();\n    this.arrayValue_StringArray = arrayValue;\n    return this;\n  }\n\n  @NonNull\n  public String[] arrayValue() {\n    return arrayValue_StringArray;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListValue(List<String>)\n   */\n  public TestManyTypesViewModel_ listValue(@NonNull List<String> listValue) {\n    if (listValue == null) {\n      throw new IllegalArgumentException(\"listValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    onMutation();\n    this.listValue_List = listValue;\n    return this;\n  }\n\n  @NonNull\n  public List<String> listValue() {\n    return listValue_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setMapValue(Map<Integer, Integer>)\n   */\n  public TestManyTypesViewModel_ mapValue(@NonNull Map<Integer, Integer> mapValue) {\n    if (mapValue == null) {\n      throw new IllegalArgumentException(\"mapValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(14);\n    onMutation();\n    this.mapValue_Map = mapValue;\n    return this;\n  }\n\n  @NonNull\n  public Map<Integer, Integer> mapValue() {\n    return mapValue_Map;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestManyTypesViewModel_ clickListener(\n      @NonNull final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(15);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setClickListener(View.OnClickListener)\n   */\n  public TestManyTypesViewModel_ clickListener(@NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(15);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  @Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.stringValue_String = null;\n    this.nullableStringValue_String = (String) null;\n    this.function_Function3 = null;\n    this.intValue_Int = 0;\n    this.intValueWithAnnotation_Int = 0;\n    this.intValueWithRangeAnnotation_Int = 0;\n    this.intValueWithDimenTypeAnnotation_Int = 0;\n    this.intWithMultipleAnnotations_Int = 0;\n    this.integerValue_Integer = null;\n    this.boolValue_Boolean = false;\n    this.models_List = null;\n    this.booleanValue_Boolean = null;\n    this.arrayValue_StringArray = null;\n    this.listValue_List = null;\n    this.mapValue_Map = null;\n    this.clickListener_OnClickListener = null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestManyTypesViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      return false;\n    }\n    if (((function_Function3 == null) != (that.function_Function3 == null))) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      return false;\n    }\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      return false;\n    }\n    if ((integerValue_Integer != null ? !integerValue_Integer.equals(that.integerValue_Integer) : that.integerValue_Integer != null)) {\n      return false;\n    }\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      return false;\n    }\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      return false;\n    }\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      return false;\n    }\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      return false;\n    }\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      return false;\n    }\n    if ((mapValue_Map != null ? !mapValue_Map.equals(that.mapValue_Map) : that.mapValue_Map != null)) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (nullableStringValue_String != null ? nullableStringValue_String.hashCode() : 0);\n    _result = 31 * _result + (function_Function3 != null ? 1 : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + intValueWithAnnotation_Int;\n    _result = 31 * _result + intValueWithRangeAnnotation_Int;\n    _result = 31 * _result + intValueWithDimenTypeAnnotation_Int;\n    _result = 31 * _result + intWithMultipleAnnotations_Int;\n    _result = 31 * _result + (integerValue_Integer != null ? integerValue_Integer.hashCode() : 0);\n    _result = 31 * _result + (boolValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (models_List != null ? models_List.hashCode() : 0);\n    _result = 31 * _result + (booleanValue_Boolean != null ? booleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(arrayValue_StringArray);\n    _result = 31 * _result + (listValue_List != null ? listValue_List.hashCode() : 0);\n    _result = 31 * _result + (mapValue_Map != null ? mapValue_Map.hashCode() : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestManyTypesViewModel_{\" +\n        \"stringValue_String=\" + stringValue_String +\n        \", nullableStringValue_String=\" + nullableStringValue_String +\n        \", intValue_Int=\" + intValue_Int +\n        \", intValueWithAnnotation_Int=\" + intValueWithAnnotation_Int +\n        \", intValueWithRangeAnnotation_Int=\" + intValueWithRangeAnnotation_Int +\n        \", intValueWithDimenTypeAnnotation_Int=\" + intValueWithDimenTypeAnnotation_Int +\n        \", intWithMultipleAnnotations_Int=\" + intWithMultipleAnnotations_Int +\n        \", integerValue_Integer=\" + integerValue_Integer +\n        \", boolValue_Boolean=\" + boolValue_Boolean +\n        \", models_List=\" + models_List +\n        \", booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", arrayValue_StringArray=\" + arrayValue_StringArray +\n        \", listValue_List=\" + listValue_List +\n        \", mapValue_Map=\" + mapValue_Map +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestNullStringOverloadsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TestNullStringOverloadsView extends View {\n\n  public TestNullStringOverloadsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = ModelProp.Option.GenerateStringOverloads)\n  public void setTitle(@Nullable CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestNullStringOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestNullStringOverloadsViewModel_ extends EpoxyModel<TestNullStringOverloadsView> implements GeneratedModel<TestNullStringOverloadsView>, TestNullStringOverloadsViewModelBuilder {\n  private OnModelBoundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestNullStringOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestNullStringOverloadsView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TestNullStringOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestNullStringOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestNullStringOverloadsViewModel_ that = (TestNullStringOverloadsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestNullStringOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestNullStringOverloadsViewModel_ onBind(\n      OnModelBoundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestNullStringOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestNullStringOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestNullStringOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestNullStringOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestNullStringOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestNullStringOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestNullStringOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestNullStringOverloadsViewModel_ that = (TestNullStringOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestNullStringOverloadsViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestStringOverloadsView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\nimport java.util.List;\n\n@ModelView(defaultLayout = 1)\npublic class TestStringOverloadsView extends View {\n\n  public TestStringOverloadsView(Context context) {\n    super(context);\n  }\n\n  @ModelProp(options = ModelProp.Option.GenerateStringOverloads)\n  public void setTitle(CharSequence title) {\n\n  }\n\n  @ModelProp\n  public void setTitle(@Nullable List<CharSequence> title) {\n    // testing that a nullable overload works correctly\n    // test setting options via the value param shortcut\n  }\n\n  @ModelProp(ModelProp.Option.GenerateStringOverloads)\n  public void setTitleViaValueShortcut(CharSequence title) {\n     // test setting options via the value param shortcut\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestStringOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestStringOverloadsViewModel_ extends EpoxyModel<TestStringOverloadsView> implements GeneratedModel<TestStringOverloadsView>, TestStringOverloadsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(3);\n\n  private OnModelBoundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  /**\n   * Bitset index: 1\n   */\n  @Nullable\n  private List<CharSequence> title_List = (List<CharSequence>) null;\n\n  /**\n   * Bitset index: 2\n   */\n  private StringAttributeData titleViaValueShortcut_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitleViaValueShortcut\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestStringOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestStringOverloadsView object) {\n    super.bind(object);\n    object.setTitleViaValueShortcut(titleViaValueShortcut_StringAttributeData.toString(object.getContext()));\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitle(title_List);\n    }\n    else {\n      object.setTitle(title_List);\n    }\n  }\n\n  @Override\n  public void bind(final TestStringOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestStringOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestStringOverloadsViewModel_ that = (TestStringOverloadsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((titleViaValueShortcut_StringAttributeData != null ? !titleViaValueShortcut_StringAttributeData.equals(that.titleViaValueShortcut_StringAttributeData) : that.titleViaValueShortcut_StringAttributeData != null)) {\n      object.setTitleViaValueShortcut(titleViaValueShortcut_StringAttributeData.toString(object.getContext()));\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n        object.setTitle(title_StringAttributeData.toString(object.getContext()));\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(1) || (title_List != null ? !title_List.equals(that.title_List) : that.title_List != null)) {\n        object.setTitle(title_List);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitle(title_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestStringOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestStringOverloadsViewModel_ onBind(\n      OnModelBoundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestStringOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestStringOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestStringOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestStringOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestStringOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestStringOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence titleStringAttributeData(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (List<CharSequence>) null\n   *\n   * @see TestStringOverloadsView#setTitle(List<CharSequence>)\n   */\n  public TestStringOverloadsViewModel_ title(@Nullable List<CharSequence> title) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.title_StringAttributeData =  new StringAttributeData();\n    onMutation();\n    this.title_List = title;\n    return this;\n  }\n\n  @Nullable\n  public List<CharSequence> titleList() {\n    return title_List;\n  }\n\n  public CharSequence getTitleViaValueShortcut(Context context) {\n    return titleViaValueShortcut_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(\n      @NonNull CharSequence titleViaValueShortcut) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    if (titleViaValueShortcut == null) {\n      throw new IllegalArgumentException(\"titleViaValueShortcut cannot be null\");\n    }\n    titleViaValueShortcut_StringAttributeData.setValue(titleViaValueShortcut);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcutQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    this.title_List = (List<CharSequence>) null;\n    this.titleViaValueShortcut_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestStringOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestStringOverloadsViewModel_ that = (TestStringOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    if ((title_List != null ? !title_List.equals(that.title_List) : that.title_List != null)) {\n      return false;\n    }\n    if ((titleViaValueShortcut_StringAttributeData != null ? !titleViaValueShortcut_StringAttributeData.equals(that.titleViaValueShortcut_StringAttributeData) : that.titleViaValueShortcut_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (title_List != null ? title_List.hashCode() : 0);\n    _result = 31 * _result + (titleViaValueShortcut_StringAttributeData != null ? titleViaValueShortcut_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestStringOverloadsViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \", title_List=\" + title_List +\n        \", titleViaValueShortcut_StringAttributeData=\" + titleViaValueShortcut_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestTextPropIfNotCharSequenceView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\nimport com.airbnb.epoxy.AfterPropsSet;\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\n\npublic class TestTextPropIfNotCharSequenceView extends View {\n  @TextProp OnClickListener value;\n\n  public TestTextPropIfNotCharSequenceView(Context context) {\n    super(context);\n  }\n\n  @AfterPropsSet\n  public void call() {\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestTextPropMustBeCharSequenceView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TestTextPropMustBeCharSequenceView extends View {\n\n  public TestTextPropMustBeCharSequenceView(Context context) {\n    super(context);\n  }\n\n  @TextProp\n  public void setTitle(String title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestTextPropView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TestTextPropView extends View {\n\n  public TestTextPropView(Context context) {\n    super(context);\n  }\n\n  @TextProp\n  public void setTitle(CharSequence title) {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TestTextPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestTextPropViewModel_ extends EpoxyModel<TestTextPropView> implements GeneratedModel<TestTextPropView>, TestTextPropViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestTextPropViewModel_, TestTextPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestTextPropViewModel_, TestTextPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestTextPropViewModel_, TestTextPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestTextPropViewModel_, TestTextPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestTextPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestTextPropView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TestTextPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestTextPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestTextPropViewModel_ that = (TestTextPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestTextPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestTextPropViewModel_ onBind(\n      OnModelBoundListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestTextPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestTextPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestTextPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestTextPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestTextPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestTextPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestTextPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestTextPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestTextPropViewModel_ that = (TestTextPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestTextPropViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TextPropDefaultView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TextPropDefaultView extends View {\n\n  public TextPropDefaultView(Context context) {\n    super(context);\n  }\n\n  @TextProp(defaultRes = R.string.string_resource_value)\n  public void textWithDefault(CharSequence title) {\n\n  }\n\n  @TextProp(defaultRes = R.string.string_resource_value)\n  public void nullableTextWithDefault(@Nullable CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TextPropDefaultViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TextPropDefaultViewModel_ extends EpoxyModel<TextPropDefaultView> implements GeneratedModel<TextPropDefaultView>, TextPropDefaultViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData textWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n\n  private StringAttributeData nullableTextWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for textWithDefault\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TextPropDefaultView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TextPropDefaultView object) {\n    super.bind(object);\n    object.textWithDefault(textWithDefault_StringAttributeData.toString(object.getContext()));\n    object.nullableTextWithDefault(nullableTextWithDefault_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TextPropDefaultView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TextPropDefaultViewModel_)) {\n      bind(object);\n      return;\n    }\n    TextPropDefaultViewModel_ that = (TextPropDefaultViewModel_) previousModel;\n    super.bind(object);\n\n    if ((textWithDefault_StringAttributeData != null ? !textWithDefault_StringAttributeData.equals(that.textWithDefault_StringAttributeData) : that.textWithDefault_StringAttributeData != null)) {\n      object.textWithDefault(textWithDefault_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((nullableTextWithDefault_StringAttributeData != null ? !nullableTextWithDefault_StringAttributeData.equals(that.nullableTextWithDefault_StringAttributeData) : that.nullableTextWithDefault_StringAttributeData != null)) {\n      object.nullableTextWithDefault(nullableTextWithDefault_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TextPropDefaultView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropDefaultViewModel_ onBind(\n      OnModelBoundListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TextPropDefaultView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropDefaultViewModel_ onUnbind(\n      OnModelUnboundListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TextPropDefaultView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropDefaultViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TextPropDefaultView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropDefaultViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTextWithDefault(Context context) {\n    return textWithDefault_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@NonNull CharSequence textWithDefault) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (textWithDefault == null) {\n      throw new IllegalArgumentException(\"textWithDefault cannot be null\");\n    }\n    textWithDefault_StringAttributeData.setValue(textWithDefault);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefaultQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Nullable\n  public CharSequence getNullableTextWithDefault(Context context) {\n    return nullableTextWithDefault_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(\n      @Nullable CharSequence nullableTextWithDefault) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(nullableTextWithDefault);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(@StringRes int stringRes) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefaultQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.textWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n    this.nullableTextWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TextPropDefaultViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TextPropDefaultViewModel_ that = (TextPropDefaultViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((textWithDefault_StringAttributeData != null ? !textWithDefault_StringAttributeData.equals(that.textWithDefault_StringAttributeData) : that.textWithDefault_StringAttributeData != null)) {\n      return false;\n    }\n    if ((nullableTextWithDefault_StringAttributeData != null ? !nullableTextWithDefault_StringAttributeData.equals(that.nullableTextWithDefault_StringAttributeData) : that.nullableTextWithDefault_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (textWithDefault_StringAttributeData != null ? textWithDefault_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (nullableTextWithDefault_StringAttributeData != null ? nullableTextWithDefault_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TextPropDefaultViewModel_{\" +\n        \"textWithDefault_StringAttributeData=\" + textWithDefault_StringAttributeData +\n        \", nullableTextWithDefault_StringAttributeData=\" + nullableTextWithDefault_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/TextPropDefaultView_throwsForNonStringRes.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.view.View;\n\n@ModelView(defaultLayout = 1)\npublic class TextPropDefaultView_throwsForNonStringRes extends View {\n\n  public TextPropDefaultView_throwsForNonStringRes(Context context) {\n    super(context);\n  }\n\n  @TextProp(defaultRes = R.layout.res)\n  public void textWithDefault(CharSequence title) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied/SourceView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport android.view.View.OnClickListener\n\n@Deprecated(\"some message\")\n@ModelView(\n    autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,\n)\nclass SourceView(context: Context) : View(context) {\n\n    @ModelProp\n    fun foo(bar: Int) {}\n\n}\n\n\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder foo(int foo);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Deprecated;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\n@Deprecated\npublic class SourceViewModel_ extends EpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int foo_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.foo(foo_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((foo_Int != that.foo_Int)) {\n      object.foo(foo_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see SourceView#foo(int)\n   */\n  public SourceViewModel_ foo(int foo) {\n    onMutation();\n    this.foo_Int = foo;\n    return this;\n  }\n\n  public int foo() {\n    return foo_Int;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.foo_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((foo_Int != that.foo_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + foo_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"foo_Int=\" + foo_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder foo(int foo);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport kotlin.Deprecated;\n\n/**\n * Generated file. Do not modify!\n */\n@Deprecated(\n    message = \"some message\"\n)\npublic class SourceViewModel_ extends EpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int foo_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.foo(foo_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((foo_Int != that.foo_Int)) {\n      object.foo(foo_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see SourceView#foo(int)\n   */\n  public SourceViewModel_ foo(int foo) {\n    onMutation();\n    this.foo_Int = foo;\n    return this;\n  }\n\n  public int foo() {\n    return foo_Int;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.foo_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((foo_Int != that.foo_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + foo_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"foo_Int=\" + foo_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied_java/SourceView.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.widget.FrameLayout;\n\n@ModelView(defaultLayout = 1)\npublic class SourceView extends FrameLayout {\n\n  public SourceView(Context context) {\n    super(context);\n  }\n\n  @SuppressWarnings(\"unused\")\n  @ModelProp String sectionId;\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied_java/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@NonNull String sectionId);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder layout(@LayoutRes int layoutRes);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied_java/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends EpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String sectionId_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for sectionId\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.sectionId = sectionId_String;\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.sectionId = sectionId_String;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see SourceView#sectionId\n   */\n  public SourceViewModel_ sectionId(@NonNull String sectionId) {\n    if (sectionId == null) {\n      throw new IllegalArgumentException(\"sectionId cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @NonNull\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.sectionId_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied_java/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@NonNull String sectionId);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder layout(@LayoutRes int p0);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/annotationsAreCopied_java/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends EpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String sectionId_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for sectionId\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.sectionId = sectionId_String;\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.sectionId = sectionId_String;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see SourceView#sectionId\n   */\n  public SourceViewModel_ sectionId(@NonNull String sectionId) {\n    if (sectionId == null) {\n      throw new IllegalArgumentException(\"sectionId cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @NonNull\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.sectionId_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport java.lang.IllegalStateException\n\n@ModelView(\n    autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,\n    baseModelClass = AirEpoxyModel::class\n)\nclass SourceView(context: Context) : BaseView(context) {\n\n    var sectionId: String? = null\n        @ModelProp set\n}\n\nabstract class AirEpoxyModel<T : View> : EpoxyModel<T>() {\n\n    @EpoxyAttribute(\n        EpoxyAttribute.Option.NoGetter,\n        EpoxyAttribute.Option.NoSetter\n    )\n    var showDivider: Boolean? = null\n\n    @EpoxyAttribute()\n    var showDividerWithSetter: Boolean? = null\n\n    open fun showDividerWithOverriddenMethod(showDivider: Boolean): AirEpoxyModel<T> {\n        return this\n    }\n\n    open fun showDivider(showDivider: Boolean): AirEpoxyModel<T> {\n        return this\n    }\n\n    open fun showDivider(): Boolean {\n        return showDivider == true\n    }\n}\n\n@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)\nopen class BaseView(context: Context) : View(context) {\n\n    @ModelProp\n    fun baseViewProp(prop: Int) {\n    }\n\n    @JvmOverloads\n    @ModelProp\n    fun baseViewPropWithDefaultParamValue(prop: Int = 0) {\n    }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\nimport org.jetbrains.annotations.Nullable;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable String sectionId);\n\n  SourceViewModelBuilder baseViewProp(int baseViewProp);\n\n  SourceViewModelBuilder baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue);\n\n  SourceViewModelBuilder showDividerWithSetter(Boolean showDividerWithSetter);\n\n  SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider);\n\n  SourceViewModelBuilder showDivider(boolean showDivider);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport org.jetbrains.annotations.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private String sectionId_String = (String) null;\n\n  private int baseViewProp_Int = 0;\n\n  private int baseViewPropWithDefaultParamValue_Int = 0;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n    object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int);\n    object.baseViewProp(baseViewProp_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n\n    if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) {\n      object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int);\n    }\n\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      object.baseViewProp(baseViewProp_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewProp(int)\n   */\n  public SourceViewModel_ baseViewProp(int baseViewProp) {\n    onMutation();\n    this.baseViewProp_Int = baseViewProp;\n    return this;\n  }\n\n  public int baseViewProp() {\n    return baseViewProp_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewPropWithDefaultParamValue(int)\n   */\n  public SourceViewModel_ baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue) {\n    onMutation();\n    this.baseViewPropWithDefaultParamValue_Int = baseViewPropWithDefaultParamValue;\n    return this;\n  }\n\n  public int baseViewPropWithDefaultParamValue() {\n    return baseViewPropWithDefaultParamValue_Int;\n  }\n\n  public SourceViewModel_ showDividerWithSetter(Boolean showDividerWithSetter) {\n    onMutation();\n    super.setShowDividerWithSetter(showDividerWithSetter);\n    return this;\n  }\n\n  public Boolean showDividerWithSetter() {\n    return super.getShowDividerWithSetter();\n  }\n\n  @Override\n  public SourceViewModel_ showDividerWithOverriddenMethod(boolean showDivider) {\n    super.showDividerWithOverriddenMethod(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ showDivider(boolean showDivider) {\n    super.showDivider(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    this.baseViewProp_Int = 0;\n    this.baseViewPropWithDefaultParamValue_Int = 0;\n    super.setShowDivider(null);\n    super.setShowDividerWithSetter(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      return false;\n    }\n    if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) {\n      return false;\n    }\n    if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) {\n      return false;\n    }\n    if ((getShowDividerWithSetter() != null ? !getShowDividerWithSetter().equals(that.getShowDividerWithSetter()) : that.getShowDividerWithSetter() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + baseViewProp_Int;\n    _result = 31 * _result + baseViewPropWithDefaultParamValue_Int;\n    _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0);\n    _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", baseViewProp_Int=\" + baseViewProp_Int +\n        \", baseViewPropWithDefaultParamValue_Int=\" + baseViewPropWithDefaultParamValue_Int +\n        \", showDivider=\" + getShowDivider() +\n        \", showDividerWithSetter=\" + getShowDividerWithSetter() +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable String sectionId);\n\n  SourceViewModelBuilder baseViewProp(int baseViewProp);\n\n  SourceViewModelBuilder baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue);\n\n  SourceViewModelBuilder showDividerWithSetter(@Nullable Boolean showDividerWithSetter);\n\n  SourceViewModelBuilder showDivider(boolean showDivider);\n\n  SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private String sectionId_String = (String) null;\n\n  private int baseViewProp_Int = 0;\n\n  private int baseViewPropWithDefaultParamValue_Int = 0;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n    object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int);\n    object.baseViewProp(baseViewProp_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n\n    if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) {\n      object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int);\n    }\n\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      object.baseViewProp(baseViewProp_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewProp(int)\n   */\n  public SourceViewModel_ baseViewProp(int baseViewProp) {\n    onMutation();\n    this.baseViewProp_Int = baseViewProp;\n    return this;\n  }\n\n  public int baseViewProp() {\n    return baseViewProp_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewPropWithDefaultParamValue(int)\n   */\n  public SourceViewModel_ baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue) {\n    onMutation();\n    this.baseViewPropWithDefaultParamValue_Int = baseViewPropWithDefaultParamValue;\n    return this;\n  }\n\n  public int baseViewPropWithDefaultParamValue() {\n    return baseViewPropWithDefaultParamValue_Int;\n  }\n\n  public SourceViewModel_ showDividerWithSetter(@Nullable Boolean showDividerWithSetter) {\n    onMutation();\n    super.setShowDividerWithSetter(showDividerWithSetter);\n    return this;\n  }\n\n  @Nullable\n  public Boolean showDividerWithSetter() {\n    return super.getShowDividerWithSetter();\n  }\n\n  @Override\n  public SourceViewModel_ showDivider(boolean showDivider) {\n    super.showDivider(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ showDividerWithOverriddenMethod(boolean showDivider) {\n    super.showDividerWithOverriddenMethod(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    this.baseViewProp_Int = 0;\n    this.baseViewPropWithDefaultParamValue_Int = 0;\n    super.setShowDivider(null);\n    super.setShowDividerWithSetter(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      return false;\n    }\n    if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) {\n      return false;\n    }\n    if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) {\n      return false;\n    }\n    if ((getShowDividerWithSetter() != null ? !getShowDividerWithSetter().equals(that.getShowDividerWithSetter()) : that.getShowDividerWithSetter() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + baseViewProp_Int;\n    _result = 31 * _result + baseViewPropWithDefaultParamValue_Int;\n    _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0);\n    _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", baseViewProp_Int=\" + baseViewProp_Int +\n        \", baseViewPropWithDefaultParamValue_Int=\" + baseViewPropWithDefaultParamValue_Int +\n        \", showDivider=\" + getShowDivider() +\n        \", showDividerWithSetter=\" + getShowDividerWithSetter() +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model\n\n@ModelView(\n    autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,\n    baseModelClass = ProcessorTest2Model::class\n)\nclass SourceView(context: Context) : View(context) {\n\n    var sectionId: String? = null\n        @ModelProp set\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\nimport org.jetbrains.annotations.Nullable;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable String sectionId);\n\n  SourceViewModelBuilder processorTest2ValueProtected(int processorTest2ValueProtected);\n\n  SourceViewModelBuilder processorTest2ValuePublic(int processorTest2ValuePublic);\n\n  SourceViewModelBuilder someAttributeAlsoWithSetter(int someAttributeAlsoWithSetter);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport org.jetbrains.annotations.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends ProcessorTest2Model<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private String sectionId_String = (String) null;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  public SourceViewModel_ processorTest2ValueProtected(int processorTest2ValueProtected) {\n    onMutation();\n    super.processorTest2ValueProtected = processorTest2ValueProtected;\n    return this;\n  }\n\n  public int processorTest2ValueProtected() {\n    return processorTest2ValueProtected;\n  }\n\n  public SourceViewModel_ processorTest2ValuePublic(int processorTest2ValuePublic) {\n    onMutation();\n    super.processorTest2ValuePublic = processorTest2ValuePublic;\n    return this;\n  }\n\n  public int processorTest2ValuePublic() {\n    return processorTest2ValuePublic;\n  }\n\n  public SourceViewModel_ someAttributeAlsoWithSetter(int someAttributeAlsoWithSetter) {\n    onMutation();\n    super.someAttributeAlsoWithSetter = someAttributeAlsoWithSetter;\n    super.someAttributeAlsoWithSetter(someAttributeAlsoWithSetter);\n    return this;\n  }\n\n  public int someAttributeAlsoWithSetter() {\n    return someAttributeAlsoWithSetter;\n  }\n\n  public int someFinalAttribute() {\n    return someFinalAttribute;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    super.processorTest2ValueProtected = 0;\n    super.processorTest2ValuePublic = 0;\n    super.someAttributeAlsoWithSetter = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((processorTest2ValueProtected != that.processorTest2ValueProtected)) {\n      return false;\n    }\n    if ((processorTest2ValuePublic != that.processorTest2ValuePublic)) {\n      return false;\n    }\n    if ((someAttributeAlsoWithSetter != that.someAttributeAlsoWithSetter)) {\n      return false;\n    }\n    if ((someFinalAttribute != that.someFinalAttribute)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + processorTest2ValueProtected;\n    _result = 31 * _result + processorTest2ValuePublic;\n    _result = 31 * _result + someAttributeAlsoWithSetter;\n    _result = 31 * _result + someFinalAttribute;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", processorTest2ValueProtected=\" + processorTest2ValueProtected +\n        \", processorTest2ValuePublic=\" + processorTest2ValuePublic +\n        \", someAttributeAlsoWithSetter=\" + someAttributeAlsoWithSetter +\n        \", someFinalAttribute=\" + someFinalAttribute +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable String sectionId);\n\n  SourceViewModelBuilder processorTest2ValueProtected(int processorTest2ValueProtected);\n\n  SourceViewModelBuilder processorTest2ValuePublic(int processorTest2ValuePublic);\n\n  SourceViewModelBuilder someAttributeAlsoWithSetter(int someAttributeAlsoWithSetter);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaClassPath/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.epoxy.processortest2.ProcessorTest2Model;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends ProcessorTest2Model<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private String sectionId_String = (String) null;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  public SourceViewModel_ processorTest2ValueProtected(int processorTest2ValueProtected) {\n    onMutation();\n    super.processorTest2ValueProtected = processorTest2ValueProtected;\n    return this;\n  }\n\n  public int processorTest2ValueProtected() {\n    return processorTest2ValueProtected;\n  }\n\n  public SourceViewModel_ processorTest2ValuePublic(int processorTest2ValuePublic) {\n    onMutation();\n    super.processorTest2ValuePublic = processorTest2ValuePublic;\n    return this;\n  }\n\n  public int processorTest2ValuePublic() {\n    return processorTest2ValuePublic;\n  }\n\n  public SourceViewModel_ someAttributeAlsoWithSetter(int someAttributeAlsoWithSetter) {\n    onMutation();\n    super.someAttributeAlsoWithSetter = someAttributeAlsoWithSetter;\n    super.someAttributeAlsoWithSetter(someAttributeAlsoWithSetter);\n    return this;\n  }\n\n  public int someAttributeAlsoWithSetter() {\n    return someAttributeAlsoWithSetter;\n  }\n\n  public int someFinalAttribute() {\n    return someFinalAttribute;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    super.processorTest2ValueProtected = 0;\n    super.processorTest2ValuePublic = 0;\n    super.someAttributeAlsoWithSetter = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((processorTest2ValueProtected != that.processorTest2ValueProtected)) {\n      return false;\n    }\n    if ((processorTest2ValuePublic != that.processorTest2ValuePublic)) {\n      return false;\n    }\n    if ((someAttributeAlsoWithSetter != that.someAttributeAlsoWithSetter)) {\n      return false;\n    }\n    if ((someFinalAttribute != that.someFinalAttribute)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + processorTest2ValueProtected;\n    _result = 31 * _result + processorTest2ValuePublic;\n    _result = 31 * _result + someAttributeAlsoWithSetter;\n    _result = 31 * _result + someFinalAttribute;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", processorTest2ValueProtected=\" + processorTest2ValueProtected +\n        \", processorTest2ValuePublic=\" + processorTest2ValuePublic +\n        \", someAttributeAlsoWithSetter=\" + someAttributeAlsoWithSetter +\n        \", someFinalAttribute=\" + someFinalAttribute +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/AirEpoxyModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport androidx.annotation.Nullable;\n\npublic abstract class AirEpoxyModel<T extends View> extends EpoxyModel<T> {\n\n  /**\n   * Whether the divider should be shown on the bound view. This should only be set if {@link #supportsDividers()} is true for your model.\n   * <p>\n   * If this is left as null then the divider will default to hidden.\n   * <p>\n   * The getter and setter are both omitted so the {@link AirModel} divider methods can be used instead.\n   */\n  @EpoxyAttribute({Option.NoGetter, Option.NoSetter}) protected Boolean showDivider;\n\n  /**\n   * The number of items that should be shown on screen. This assumes the model is used in a horizontal RecyclerView (aka {@link Carousel}), and the\n   * view will have its width resized so that the appropriate number of items fit on screen.\n   * <p>\n   * We don't generate a getter since this class defines one, so it is accessible with just a `AirEpoxyModel` reference.\n   */\n  @Nullable @EpoxyAttribute(Option.NoGetter) protected SomeType numCarouselItemsShown;\n\n  public AirEpoxyModel<T> numCarouselItemsShown(SomeType numCarouselItemsShown) {\n    this.numCarouselItemsShown = numCarouselItemsShown;\n    return this;\n  }\n\n  @Nullable\n  public SomeType numCarouselItemsShown() {\n    return numCarouselItemsShown;\n  }\n\n  public static class SomeType {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\n\n@ModelView(\n    autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,\n    baseModelClass = AirEpoxyModel::class\n)\nclass SourceView(context: Context) : BaseView(context) {\n\n    var sectionId: String? = null\n        @ModelProp set\n}\n\n@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)\nopen class BaseView(context: Context) : View(context) {\n\n    @ModelProp\n    fun baseViewProp(prop: Int) {\n    }\n}\n\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\nimport org.jetbrains.annotations.Nullable;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable(\"\") String sectionId);\n\n  SourceViewModelBuilder baseViewProp(int baseViewProp);\n\n  SourceViewModelBuilder showDividerWithSetter(Boolean showDividerWithSetter);\n\n  SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport org.jetbrains.annotations.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable(\"\")\n  private String sectionId_String = (String) null;\n\n  private int baseViewProp_Int = 0;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n    object.baseViewProp(baseViewProp_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      object.baseViewProp(baseViewProp_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable(\"\") String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable(\"\")\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewProp(int)\n   */\n  public SourceViewModel_ baseViewProp(int baseViewProp) {\n    onMutation();\n    this.baseViewProp_Int = baseViewProp;\n    return this;\n  }\n\n  public int baseViewProp() {\n    return baseViewProp_Int;\n  }\n\n  public SourceViewModel_ showDividerWithSetter(Boolean showDividerWithSetter) {\n    onMutation();\n    super.setShowDividerWithSetter(showDividerWithSetter);\n    return this;\n  }\n\n  public Boolean showDividerWithSetter() {\n    return super.getShowDividerWithSetter();\n  }\n\n  @Override\n  public SourceViewModel_ showDividerWithOverriddenMethod(boolean showDivider) {\n    super.showDividerWithOverriddenMethod(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    this.baseViewProp_Int = 0;\n    super.setShowDivider(null);\n    super.setShowDividerWithSetter(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      return false;\n    }\n    if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) {\n      return false;\n    }\n    if ((getShowDividerWithSetter() != null ? !getShowDividerWithSetter().equals(that.getShowDividerWithSetter()) : that.getShowDividerWithSetter() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + baseViewProp_Int;\n    _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0);\n    _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", baseViewProp_Int=\" + baseViewProp_Int +\n        \", showDivider=\" + getShowDivider() +\n        \", showDividerWithSetter=\" + getShowDividerWithSetter() +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable String sectionId);\n\n  SourceViewModelBuilder baseViewProp(int baseViewProp);\n\n  SourceViewModelBuilder numCarouselItemsShown(\n      @Nullable AirEpoxyModel.SomeType numCarouselItemsShown);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectlyJavaSources/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private String sectionId_String = (String) null;\n\n  private int baseViewProp_Int = 0;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n    object.baseViewProp(baseViewProp_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      object.baseViewProp(baseViewProp_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewProp(int)\n   */\n  public SourceViewModel_ baseViewProp(int baseViewProp) {\n    onMutation();\n    this.baseViewProp_Int = baseViewProp;\n    return this;\n  }\n\n  public int baseViewProp() {\n    return baseViewProp_Int;\n  }\n\n  /**\n   * The number of items that should be shown on screen. This assumes the model is used in a horizontal RecyclerView (aka {@link Carousel}), and the\n   *  view will have its width resized so that the appropriate number of items fit on screen.\n   *  <p>\n   *  We don't generate a getter since this class defines one, so it is accessible with just a `AirEpoxyModel` reference.\n   */\n  public SourceViewModel_ numCarouselItemsShown(\n      @Nullable AirEpoxyModel.SomeType numCarouselItemsShown) {\n    onMutation();\n    super.numCarouselItemsShown = numCarouselItemsShown;\n    super.numCarouselItemsShown(numCarouselItemsShown);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    this.baseViewProp_Int = 0;\n    super.showDivider = null;\n    super.numCarouselItemsShown = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      return false;\n    }\n    if ((showDivider != null ? !showDivider.equals(that.showDivider) : that.showDivider != null)) {\n      return false;\n    }\n    if ((numCarouselItemsShown != null ? !numCarouselItemsShown.equals(that.numCarouselItemsShown) : that.numCarouselItemsShown != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + baseViewProp_Int;\n    _result = 31 * _result + (showDivider != null ? showDivider.hashCode() : 0);\n    _result = 31 * _result + (numCarouselItemsShown != null ? numCarouselItemsShown.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", baseViewProp_Int=\" + baseViewProp_Int +\n        \", showDivider=\" + showDivider +\n        \", numCarouselItemsShown=\" + numCarouselItemsShown +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/EpoxyModelViewProcessorKotlinExtensions.kt",
    "content": "@file:Suppress(\"DEPRECATION\")\n\npackage com.airbnb.epoxy\n\nimport kotlin.Suppress\nimport kotlin.Unit\n\npublic inline fun ModelCollector.testManyTypesView(modelInitializer: TestManyTypesViewModelBuilder.() -> Unit) {\n  add(\n  TestManyTypesViewModel_().apply {\n    modelInitializer()\n  }\n  )\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/TestManyTypesView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport androidx.annotation.Dimension\nimport androidx.annotation.IntRange\nimport androidx.annotation.StringRes\nimport kotlin.properties.Delegates\nimport kotlin.properties.ObservableProperty\n\n@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)\nclass TestManyTypesView(context: Context?) : View(context) {\n\n    @set:ModelProp\n    var myProperty: Int = 0\n\n    @set:ModelProp\n    var myNullableProperty: Int? = 0\n\n    @set:ModelProp\n    var delegatedProperty: Int by Delegates.observable(0) { _, _, _ ->\n\n    }\n\n    @ModelProp(defaultValue = \"DEFAULT_ENABLED\")\n    override fun setEnabled(enabled: Boolean) {\n    }\n\n    @ModelProp\n    fun setStringValue(value: String) {\n    }\n\n    @ModelProp(ModelProp.Option.DoNotHash)\n    fun setFunctionType(value: (String, String) -> Integer) {\n    }\n\n    @ModelProp\n    fun setListOfDataClass(value: List<SomeDataClass>) {\n    }\n\n    @ModelProp\n    fun setListOfEnumClass(value: List<SomeEnumClass>) {\n    }\n\n    @ModelProp\n    fun setNullableStringValue(value: String?) {\n    }\n\n    @ModelProp\n    fun setIntValue(value: Int) {\n    }\n\n    @JvmOverloads\n    @ModelProp\n    fun setIntValueWithDefault(value: Int = 3) {\n    }\n\n    @ModelProp\n    fun setIntValueWithAnnotation(@StringRes value: Int) {\n    }\n\n    @ModelProp\n    fun setIntValueWithRangeAnnotation(@IntRange(from = 0, to = TO_RANGE.toLong()) value: Int) {\n    }\n\n    @ModelProp\n    fun setIntValueWithDimenTypeAnnotation(@Dimension(unit = Dimension.DP) value: Int) {\n    }\n\n    @ModelProp\n    fun setIntWithMultipleAnnotations(\n        @IntRange(\n            from = 0,\n            to = TO_RANGE.toLong()\n        ) @Dimension(unit = Dimension.DP) value: Int\n    ) {\n    }\n\n    @ModelProp\n    fun setIntegerValue(value: Int) {\n    }\n\n    @ModelProp\n    fun setBoolValue(value: Boolean) {\n    }\n\n    @ModelProp\n    fun setModels(models: List<EpoxyModel<*>?>) {\n    }\n\n    @ModelProp\n    fun setBooleanValue(value: Boolean?) {\n    }\n\n    @ModelProp\n    fun setArrayValue(value: Array<String?>?) {\n    }\n\n    @ModelProp\n    fun setListValue(value: List<String?>?) {\n    }\n\n    @ModelProp(options = [ModelProp.Option.DoNotHash])\n    fun setClickListener(value: OnClickListener?) {\n    }\n\n    @ModelProp(options = [ModelProp.Option.DoNotHash])\n    fun setCustomClickListener(value: CustomClickListenerSubclass?) {\n    }\n\n    @ModelProp(options = [ModelProp.Option.GenerateStringOverloads])\n    fun setTitle(title: CharSequence?) {\n    }\n\n    companion object {\n        const val TO_RANGE = 200\n        const val DEFAULT_ENABLED = true\n    }\n}\n\ndata class SomeDataClass(\n    val title: String\n)\n\nenum class SomeEnumClass {\n    Foo\n}\n\n// Should not be used with modelfactory or \"model click listener\" code gen as those require the exact\n// OnClickListener type.\nclass CustomClickListenerSubclass : View.OnClickListener {\n    override fun onClick(v: View?) {\n\n    }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/TestManyTypesViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.String;\nimport java.util.List;\nimport kotlin.jvm.functions.Function2;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n@EpoxyBuildScope\npublic interface TestManyTypesViewModelBuilder {\n  TestManyTypesViewModelBuilder onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder myProperty(int myProperty);\n\n  TestManyTypesViewModelBuilder myNullableProperty(@Nullable Integer myNullableProperty);\n\n  TestManyTypesViewModelBuilder delegatedProperty(int delegatedProperty);\n\n  TestManyTypesViewModelBuilder enabled(boolean enabled);\n\n  TestManyTypesViewModelBuilder stringValue(@NotNull String stringValue);\n\n  TestManyTypesViewModelBuilder functionType(\n      @NotNull Function2<? super String, ? super String, Integer> functionType);\n\n  TestManyTypesViewModelBuilder listOfDataClass(@NotNull List<SomeDataClass> listOfDataClass);\n\n  TestManyTypesViewModelBuilder listOfEnumClass(\n      @NotNull List<? extends SomeEnumClass> listOfEnumClass);\n\n  TestManyTypesViewModelBuilder nullableStringValue(@Nullable String nullableStringValue);\n\n  TestManyTypesViewModelBuilder intValue(int intValue);\n\n  TestManyTypesViewModelBuilder intValueWithDefault(int intValueWithDefault);\n\n  TestManyTypesViewModelBuilder intValueWithAnnotation(@StringRes int intValueWithAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation);\n\n  TestManyTypesViewModelBuilder intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations);\n\n  TestManyTypesViewModelBuilder integerValue(int integerValue);\n\n  TestManyTypesViewModelBuilder boolValue(boolean boolValue);\n\n  TestManyTypesViewModelBuilder models(@NotNull List<? extends EpoxyModel<?>> models);\n\n  TestManyTypesViewModelBuilder booleanValue(@Nullable Boolean booleanValue);\n\n  TestManyTypesViewModelBuilder arrayValue(@Nullable String[] arrayValue);\n\n  TestManyTypesViewModelBuilder listValue(@Nullable List<String> listValue);\n\n  TestManyTypesViewModelBuilder clickListener(\n      @Nullable final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener);\n\n  TestManyTypesViewModelBuilder clickListener(@Nullable View.OnClickListener clickListener);\n\n  TestManyTypesViewModelBuilder customClickListener(\n      @Nullable CustomClickListenerSubclass customClickListener);\n\n  TestManyTypesViewModelBuilder title(@androidx.annotation.Nullable CharSequence title);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes, Object... formatArgs);\n\n  TestManyTypesViewModelBuilder titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs);\n\n  TestManyTypesViewModelBuilder id(long id);\n\n  TestManyTypesViewModelBuilder id(@androidx.annotation.Nullable Number... ids);\n\n  TestManyTypesViewModelBuilder id(long id1, long id2);\n\n  TestManyTypesViewModelBuilder id(@androidx.annotation.Nullable CharSequence key);\n\n  TestManyTypesViewModelBuilder id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys);\n\n  TestManyTypesViewModelBuilder id(@androidx.annotation.Nullable CharSequence key, long id);\n\n  TestManyTypesViewModelBuilder spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/TestManyTypesViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport kotlin.jvm.functions.Function2;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestManyTypesViewModel_ extends EpoxyModel<TestManyTypesView> implements GeneratedModel<TestManyTypesView>, TestManyTypesViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(24);\n\n  private OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int myProperty_Int = 0;\n\n  @Nullable\n  private Integer myNullableProperty_Integer = (Integer) null;\n\n  private int delegatedProperty_Int = 0;\n\n  private boolean enabled_Boolean = TestManyTypesView.DEFAULT_ENABLED;\n\n  /**\n   * Bitset index: 4\n   */\n  @NotNull\n  private String stringValue_String;\n\n  /**\n   * Bitset index: 5\n   */\n  @NotNull\n  private Function2<? super String, ? super String, Integer> functionType_Function2;\n\n  /**\n   * Bitset index: 6\n   */\n  @NotNull\n  private List<SomeDataClass> listOfDataClass_List;\n\n  /**\n   * Bitset index: 7\n   */\n  @NotNull\n  private List<? extends SomeEnumClass> listOfEnumClass_List;\n\n  @Nullable\n  private String nullableStringValue_String = (String) null;\n\n  private int intValue_Int = 0;\n\n  /**\n   * Bitset index: 10\n   */\n  private int intValueWithDefault_Int;\n\n  @StringRes\n  private int intValueWithAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  private int intValueWithRangeAnnotation_Int = 0;\n\n  @Dimension(\n      unit = 0\n  )\n  private int intValueWithDimenTypeAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  private int intWithMultipleAnnotations_Int = 0;\n\n  private int integerValue_Int = 0;\n\n  private boolean boolValue_Boolean = false;\n\n  /**\n   * Bitset index: 17\n   */\n  @NotNull\n  private List<? extends EpoxyModel<?>> models_List;\n\n  @Nullable\n  private Boolean booleanValue_Boolean = (Boolean) null;\n\n  @Nullable\n  private String[] arrayValue_StringArray = (String[]) null;\n\n  @Nullable\n  private List<String> listValue_List = (List<String>) null;\n\n  @Nullable\n  private View.OnClickListener clickListener_OnClickListener = (View.OnClickListener) null;\n\n  @Nullable\n  private CustomClickListenerSubclass customClickListener_CustomClickListenerSubclass = (CustomClickListenerSubclass) null;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(7)) {\n    \tthrow new IllegalStateException(\"A value is required for setListOfEnumClass\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(4)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(5)) {\n    \tthrow new IllegalStateException(\"A value is required for setFunctionType\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(6)) {\n    \tthrow new IllegalStateException(\"A value is required for setListOfDataClass\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(17)) {\n    \tthrow new IllegalStateException(\"A value is required for setModels\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestManyTypesView buildView(ViewGroup parent) {\n    TestManyTypesView v = new TestManyTypesView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestManyTypesView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object) {\n    super.bind(object);\n    object.setListOfEnumClass(listOfEnumClass_List);\n    object.setArrayValue(arrayValue_StringArray);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setMyProperty(myProperty_Int);\n    object.setCustomClickListener(customClickListener_CustomClickListenerSubclass);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    object.setStringValue(stringValue_String);\n    object.setNullableStringValue(nullableStringValue_String);\n    object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    object.setEnabled(enabled_Boolean);\n    object.setFunctionType(functionType_Function2);\n    object.setIntegerValue(integerValue_Int);\n    object.setListValue(listValue_List);\n    object.setIntValue(intValue_Int);\n    object.setDelegatedProperty(delegatedProperty_Int);\n    object.setListOfDataClass(listOfDataClass_List);\n    object.setMyNullableProperty(myNullableProperty_Integer);\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setIntValueWithDefault(intValueWithDefault_Int);\n    }\n    else {\n      object.setIntValueWithDefault();\n    }\n    object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    object.setBoolValue(boolValue_Boolean);\n    object.setModels(models_List);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestManyTypesViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) previousModel;\n    super.bind(object);\n\n    if ((listOfEnumClass_List != null ? !listOfEnumClass_List.equals(that.listOfEnumClass_List) : that.listOfEnumClass_List != null)) {\n      object.setListOfEnumClass(listOfEnumClass_List);\n    }\n\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      object.setArrayValue(arrayValue_StringArray);\n    }\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((myProperty_Int != that.myProperty_Int)) {\n      object.setMyProperty(myProperty_Int);\n    }\n\n    if (((customClickListener_CustomClickListenerSubclass == null) != (that.customClickListener_CustomClickListenerSubclass == null))) {\n      object.setCustomClickListener(customClickListener_CustomClickListenerSubclass);\n    }\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      object.setNullableStringValue(nullableStringValue_String);\n    }\n\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    }\n\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    }\n\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    }\n\n    if ((enabled_Boolean != that.enabled_Boolean)) {\n      object.setEnabled(enabled_Boolean);\n    }\n\n    if (((functionType_Function2 == null) != (that.functionType_Function2 == null))) {\n      object.setFunctionType(functionType_Function2);\n    }\n\n    if ((integerValue_Int != that.integerValue_Int)) {\n      object.setIntegerValue(integerValue_Int);\n    }\n\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      object.setListValue(listValue_List);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      object.setDelegatedProperty(delegatedProperty_Int);\n    }\n\n    if ((listOfDataClass_List != null ? !listOfDataClass_List.equals(that.listOfDataClass_List) : that.listOfDataClass_List != null)) {\n      object.setListOfDataClass(listOfDataClass_List);\n    }\n\n    if ((myNullableProperty_Integer != null ? !myNullableProperty_Integer.equals(that.myNullableProperty_Integer) : that.myNullableProperty_Integer != null)) {\n      object.setMyNullableProperty(myNullableProperty_Integer);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      if ((intValueWithDefault_Int != that.intValueWithDefault_Int)) {\n        object.setIntValueWithDefault(intValueWithDefault_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setIntValueWithDefault();\n    }\n\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    }\n\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      object.setBoolValue(boolValue_Boolean);\n    }\n\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      object.setModels(models_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestManyTypesView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestManyTypesView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestManyTypesView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestManyTypesView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setMyProperty(int)\n   */\n  public TestManyTypesViewModel_ myProperty(int myProperty) {\n    onMutation();\n    this.myProperty_Int = myProperty;\n    return this;\n  }\n\n  public int myProperty() {\n    return myProperty_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (Integer) null\n   *\n   * @see TestManyTypesView#setMyNullableProperty(Integer)\n   */\n  public TestManyTypesViewModel_ myNullableProperty(@Nullable Integer myNullableProperty) {\n    onMutation();\n    this.myNullableProperty_Integer = myNullableProperty;\n    return this;\n  }\n\n  @Nullable\n  public Integer myNullableProperty() {\n    return myNullableProperty_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setDelegatedProperty(int)\n   */\n  public TestManyTypesViewModel_ delegatedProperty(int delegatedProperty) {\n    onMutation();\n    this.delegatedProperty_Int = delegatedProperty;\n    return this;\n  }\n\n  public int delegatedProperty() {\n    return delegatedProperty_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value TestManyTypesView#DEFAULT_ENABLED}</b>\n   *\n   * @see TestManyTypesView#setEnabled(boolean)\n   */\n  public TestManyTypesViewModel_ enabled(boolean enabled) {\n    onMutation();\n    this.enabled_Boolean = enabled;\n    return this;\n  }\n\n  public boolean enabled() {\n    return enabled_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setStringValue(String)\n   */\n  public TestManyTypesViewModel_ stringValue(@NotNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(4);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NotNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setFunctionType(Function2<? super String, ? super String, Integer>)\n   */\n  public TestManyTypesViewModel_ functionType(\n      @NotNull Function2<? super String, ? super String, Integer> functionType) {\n    if (functionType == null) {\n      throw new IllegalArgumentException(\"functionType cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(5);\n    onMutation();\n    this.functionType_Function2 = functionType;\n    return this;\n  }\n\n  @NotNull\n  public Function2<? super String, ? super String, Integer> functionType() {\n    return functionType_Function2;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListOfDataClass(List<SomeDataClass>)\n   */\n  public TestManyTypesViewModel_ listOfDataClass(@NotNull List<SomeDataClass> listOfDataClass) {\n    if (listOfDataClass == null) {\n      throw new IllegalArgumentException(\"listOfDataClass cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    onMutation();\n    this.listOfDataClass_List = listOfDataClass;\n    return this;\n  }\n\n  @NotNull\n  public List<SomeDataClass> listOfDataClass() {\n    return listOfDataClass_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListOfEnumClass(List<? extends SomeEnumClass>)\n   */\n  public TestManyTypesViewModel_ listOfEnumClass(\n      @NotNull List<? extends SomeEnumClass> listOfEnumClass) {\n    if (listOfEnumClass == null) {\n      throw new IllegalArgumentException(\"listOfEnumClass cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(7);\n    onMutation();\n    this.listOfEnumClass_List = listOfEnumClass;\n    return this;\n  }\n\n  @NotNull\n  public List<? extends SomeEnumClass> listOfEnumClass() {\n    return listOfEnumClass_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see TestManyTypesView#setNullableStringValue(String)\n   */\n  public TestManyTypesViewModel_ nullableStringValue(@Nullable String nullableStringValue) {\n    onMutation();\n    this.nullableStringValue_String = nullableStringValue;\n    return this;\n  }\n\n  @Nullable\n  public String nullableStringValue() {\n    return nullableStringValue_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValue(int)\n   */\n  public TestManyTypesViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: View function has a Kotlin default argument\n   *\n   * @see TestManyTypesView#setIntValueWithDefault(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDefault(int intValueWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.intValueWithDefault_Int = intValueWithDefault;\n    return this;\n  }\n\n  public int intValueWithDefault() {\n    return intValueWithDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithAnnotation(@StringRes int intValueWithAnnotation) {\n    onMutation();\n    this.intValueWithAnnotation_Int = intValueWithAnnotation;\n    return this;\n  }\n\n  @StringRes\n  public int intValueWithAnnotation() {\n    return intValueWithAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithRangeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation) {\n    onMutation();\n    this.intValueWithRangeAnnotation_Int = intValueWithRangeAnnotation;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  public int intValueWithRangeAnnotation() {\n    return intValueWithRangeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithDimenTypeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation) {\n    onMutation();\n    this.intValueWithDimenTypeAnnotation_Int = intValueWithDimenTypeAnnotation;\n    return this;\n  }\n\n  @Dimension(\n      unit = 0\n  )\n  public int intValueWithDimenTypeAnnotation() {\n    return intValueWithDimenTypeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntWithMultipleAnnotations(int)\n   */\n  public TestManyTypesViewModel_ intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations) {\n    onMutation();\n    this.intWithMultipleAnnotations_Int = intWithMultipleAnnotations;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  public int intWithMultipleAnnotations() {\n    return intWithMultipleAnnotations_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntegerValue(int)\n   */\n  public TestManyTypesViewModel_ integerValue(int integerValue) {\n    onMutation();\n    this.integerValue_Int = integerValue;\n    return this;\n  }\n\n  public int integerValue() {\n    return integerValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestManyTypesView#setBoolValue(boolean)\n   */\n  public TestManyTypesViewModel_ boolValue(boolean boolValue) {\n    onMutation();\n    this.boolValue_Boolean = boolValue;\n    return this;\n  }\n\n  public boolean boolValue() {\n    return boolValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setModels(List<? extends EpoxyModel<?>>)\n   */\n  public TestManyTypesViewModel_ models(@NotNull List<? extends EpoxyModel<?>> models) {\n    if (models == null) {\n      throw new IllegalArgumentException(\"models cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(17);\n    onMutation();\n    this.models_List = models;\n    return this;\n  }\n\n  @NotNull\n  public List<? extends EpoxyModel<?>> models() {\n    return models_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (Boolean) null\n   *\n   * @see TestManyTypesView#setBooleanValue(Boolean)\n   */\n  public TestManyTypesViewModel_ booleanValue(@Nullable Boolean booleanValue) {\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  @Nullable\n  public Boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String[]) null\n   *\n   * @see TestManyTypesView#setArrayValue(String[])\n   */\n  public TestManyTypesViewModel_ arrayValue(@Nullable String[] arrayValue) {\n    onMutation();\n    this.arrayValue_StringArray = arrayValue;\n    return this;\n  }\n\n  @Nullable\n  public String[] arrayValue() {\n    return arrayValue_StringArray;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (List<String>) null\n   *\n   * @see TestManyTypesView#setListValue(List<String>)\n   */\n  public TestManyTypesViewModel_ listValue(@Nullable List<String> listValue) {\n    onMutation();\n    this.listValue_List = listValue;\n    return this;\n  }\n\n  @Nullable\n  public List<String> listValue() {\n    return listValue_List;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestManyTypesViewModel_ clickListener(\n      @Nullable final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestManyTypesView#setClickListener(View.OnClickListener)\n   */\n  public TestManyTypesViewModel_ clickListener(@Nullable View.OnClickListener clickListener) {\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CustomClickListenerSubclass) null\n   *\n   * @see TestManyTypesView#setCustomClickListener(CustomClickListenerSubclass)\n   */\n  public TestManyTypesViewModel_ customClickListener(\n      @Nullable CustomClickListenerSubclass customClickListener) {\n    onMutation();\n    this.customClickListener_CustomClickListenerSubclass = customClickListener;\n    return this;\n  }\n\n  @Nullable\n  public CustomClickListenerSubclass customClickListener() {\n    return customClickListener_CustomClickListenerSubclass;\n  }\n\n  @androidx.annotation.Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@androidx.annotation.Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestManyTypesViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestManyTypesViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.myProperty_Int = 0;\n    this.myNullableProperty_Integer = (Integer) null;\n    this.delegatedProperty_Int = 0;\n    this.enabled_Boolean = TestManyTypesView.DEFAULT_ENABLED;\n    this.stringValue_String = null;\n    this.functionType_Function2 = null;\n    this.listOfDataClass_List = null;\n    this.listOfEnumClass_List = null;\n    this.nullableStringValue_String = (String) null;\n    this.intValue_Int = 0;\n    this.intValueWithDefault_Int = 0;\n    this.intValueWithAnnotation_Int = 0;\n    this.intValueWithRangeAnnotation_Int = 0;\n    this.intValueWithDimenTypeAnnotation_Int = 0;\n    this.intWithMultipleAnnotations_Int = 0;\n    this.integerValue_Int = 0;\n    this.boolValue_Boolean = false;\n    this.models_List = null;\n    this.booleanValue_Boolean = (Boolean) null;\n    this.arrayValue_StringArray = (String[]) null;\n    this.listValue_List = (List<String>) null;\n    this.clickListener_OnClickListener = (View.OnClickListener) null;\n    this.customClickListener_CustomClickListenerSubclass = (CustomClickListenerSubclass) null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestManyTypesViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((myProperty_Int != that.myProperty_Int)) {\n      return false;\n    }\n    if ((myNullableProperty_Integer != null ? !myNullableProperty_Integer.equals(that.myNullableProperty_Integer) : that.myNullableProperty_Integer != null)) {\n      return false;\n    }\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      return false;\n    }\n    if ((enabled_Boolean != that.enabled_Boolean)) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if (((functionType_Function2 == null) != (that.functionType_Function2 == null))) {\n      return false;\n    }\n    if ((listOfDataClass_List != null ? !listOfDataClass_List.equals(that.listOfDataClass_List) : that.listOfDataClass_List != null)) {\n      return false;\n    }\n    if ((listOfEnumClass_List != null ? !listOfEnumClass_List.equals(that.listOfEnumClass_List) : that.listOfEnumClass_List != null)) {\n      return false;\n    }\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((intValueWithDefault_Int != that.intValueWithDefault_Int)) {\n      return false;\n    }\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      return false;\n    }\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      return false;\n    }\n    if ((integerValue_Int != that.integerValue_Int)) {\n      return false;\n    }\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      return false;\n    }\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      return false;\n    }\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      return false;\n    }\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      return false;\n    }\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if (((customClickListener_CustomClickListenerSubclass == null) != (that.customClickListener_CustomClickListenerSubclass == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + myProperty_Int;\n    _result = 31 * _result + (myNullableProperty_Integer != null ? myNullableProperty_Integer.hashCode() : 0);\n    _result = 31 * _result + delegatedProperty_Int;\n    _result = 31 * _result + (enabled_Boolean ? 1 : 0);\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (functionType_Function2 != null ? 1 : 0);\n    _result = 31 * _result + (listOfDataClass_List != null ? listOfDataClass_List.hashCode() : 0);\n    _result = 31 * _result + (listOfEnumClass_List != null ? listOfEnumClass_List.hashCode() : 0);\n    _result = 31 * _result + (nullableStringValue_String != null ? nullableStringValue_String.hashCode() : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + intValueWithDefault_Int;\n    _result = 31 * _result + intValueWithAnnotation_Int;\n    _result = 31 * _result + intValueWithRangeAnnotation_Int;\n    _result = 31 * _result + intValueWithDimenTypeAnnotation_Int;\n    _result = 31 * _result + intWithMultipleAnnotations_Int;\n    _result = 31 * _result + integerValue_Int;\n    _result = 31 * _result + (boolValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (models_List != null ? models_List.hashCode() : 0);\n    _result = 31 * _result + (booleanValue_Boolean != null ? booleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(arrayValue_StringArray);\n    _result = 31 * _result + (listValue_List != null ? listValue_List.hashCode() : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (customClickListener_CustomClickListenerSubclass != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestManyTypesViewModel_{\" +\n        \"myProperty_Int=\" + myProperty_Int +\n        \", myNullableProperty_Integer=\" + myNullableProperty_Integer +\n        \", delegatedProperty_Int=\" + delegatedProperty_Int +\n        \", enabled_Boolean=\" + enabled_Boolean +\n        \", stringValue_String=\" + stringValue_String +\n        \", listOfDataClass_List=\" + listOfDataClass_List +\n        \", listOfEnumClass_List=\" + listOfEnumClass_List +\n        \", nullableStringValue_String=\" + nullableStringValue_String +\n        \", intValue_Int=\" + intValue_Int +\n        \", intValueWithDefault_Int=\" + intValueWithDefault_Int +\n        \", intValueWithAnnotation_Int=\" + intValueWithAnnotation_Int +\n        \", intValueWithRangeAnnotation_Int=\" + intValueWithRangeAnnotation_Int +\n        \", intValueWithDimenTypeAnnotation_Int=\" + intValueWithDimenTypeAnnotation_Int +\n        \", intWithMultipleAnnotations_Int=\" + intWithMultipleAnnotations_Int +\n        \", integerValue_Int=\" + integerValue_Int +\n        \", boolValue_Boolean=\" + boolValue_Boolean +\n        \", models_List=\" + models_List +\n        \", booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", arrayValue_StringArray=\" + arrayValue_StringArray +\n        \", listValue_List=\" + listValue_List +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", customClickListener_CustomClickListenerSubclass=\" + customClickListener_CustomClickListenerSubclass +\n        \", title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/ksp/EpoxyModelViewProcessorKotlinExtensions.kt",
    "content": "@file:Suppress(\"DEPRECATION\")\n\npackage com.airbnb.epoxy\n\nimport kotlin.Suppress\nimport kotlin.Unit\n\npublic inline fun ModelCollector.testManyTypesView(modelInitializer: TestManyTypesViewModelBuilder.() -> Unit) {\n  add(\n  TestManyTypesViewModel_().apply {\n    modelInitializer()\n  }\n  )\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/ksp/TestManyTypesViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.String;\nimport java.util.List;\nimport kotlin.jvm.functions.Function2;\n\n@EpoxyBuildScope\npublic interface TestManyTypesViewModelBuilder {\n  TestManyTypesViewModelBuilder onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder myProperty(int myProperty);\n\n  TestManyTypesViewModelBuilder myNullableProperty(@Nullable Integer myNullableProperty);\n\n  TestManyTypesViewModelBuilder delegatedProperty(int delegatedProperty);\n\n  TestManyTypesViewModelBuilder enabled(boolean enabled);\n\n  TestManyTypesViewModelBuilder stringValue(@NonNull String stringValue);\n\n  TestManyTypesViewModelBuilder functionType(\n      @NonNull Function2<? super String, ? super String, Integer> functionType);\n\n  TestManyTypesViewModelBuilder listOfDataClass(@NonNull List<SomeDataClass> listOfDataClass);\n\n  TestManyTypesViewModelBuilder listOfEnumClass(@NonNull List<SomeEnumClass> listOfEnumClass);\n\n  TestManyTypesViewModelBuilder nullableStringValue(@Nullable String nullableStringValue);\n\n  TestManyTypesViewModelBuilder intValue(int intValue);\n\n  TestManyTypesViewModelBuilder intValueWithDefault(int intValueWithDefault);\n\n  TestManyTypesViewModelBuilder intValueWithAnnotation(@StringRes int intValueWithAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation);\n\n  TestManyTypesViewModelBuilder intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations);\n\n  TestManyTypesViewModelBuilder integerValue(int integerValue);\n\n  TestManyTypesViewModelBuilder boolValue(boolean boolValue);\n\n  TestManyTypesViewModelBuilder models(@NonNull List<? extends EpoxyModel<?>> models);\n\n  TestManyTypesViewModelBuilder booleanValue(@Nullable Boolean booleanValue);\n\n  TestManyTypesViewModelBuilder arrayValue(@Nullable String[] arrayValue);\n\n  TestManyTypesViewModelBuilder listValue(@Nullable List<String> listValue);\n\n  TestManyTypesViewModelBuilder clickListener(\n      @Nullable final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener);\n\n  TestManyTypesViewModelBuilder clickListener(@Nullable View.OnClickListener clickListener);\n\n  TestManyTypesViewModelBuilder customClickListener(\n      @Nullable CustomClickListenerSubclass customClickListener);\n\n  TestManyTypesViewModelBuilder title(@Nullable CharSequence title);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes, Object... formatArgs);\n\n  TestManyTypesViewModelBuilder titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs);\n\n  TestManyTypesViewModelBuilder id(long p0);\n\n  TestManyTypesViewModelBuilder id(@Nullable Number... p0);\n\n  TestManyTypesViewModelBuilder id(long p0, long p1);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  TestManyTypesViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testManyTypes/ksp/TestManyTypesViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport kotlin.jvm.functions.Function2;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestManyTypesViewModel_ extends EpoxyModel<TestManyTypesView> implements GeneratedModel<TestManyTypesView>, TestManyTypesViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(24);\n\n  private OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int myProperty_Int = 0;\n\n  @Nullable\n  private Integer myNullableProperty_Integer = (Integer) null;\n\n  private int delegatedProperty_Int = 0;\n\n  private boolean enabled_Boolean = TestManyTypesView.DEFAULT_ENABLED;\n\n  /**\n   * Bitset index: 4\n   */\n  @NonNull\n  private String stringValue_String;\n\n  /**\n   * Bitset index: 5\n   */\n  @NonNull\n  private Function2<? super String, ? super String, Integer> functionType_Function2;\n\n  /**\n   * Bitset index: 6\n   */\n  @NonNull\n  private List<SomeDataClass> listOfDataClass_List;\n\n  /**\n   * Bitset index: 7\n   */\n  @NonNull\n  private List<SomeEnumClass> listOfEnumClass_List;\n\n  @Nullable\n  private String nullableStringValue_String = (String) null;\n\n  private int intValue_Int = 0;\n\n  /**\n   * Bitset index: 10\n   */\n  private int intValueWithDefault_Int;\n\n  @StringRes\n  private int intValueWithAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  private int intValueWithRangeAnnotation_Int = 0;\n\n  @Dimension(\n      unit = 0\n  )\n  private int intValueWithDimenTypeAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  private int intWithMultipleAnnotations_Int = 0;\n\n  private int integerValue_Int = 0;\n\n  private boolean boolValue_Boolean = false;\n\n  /**\n   * Bitset index: 17\n   */\n  @NonNull\n  private List<? extends EpoxyModel<?>> models_List;\n\n  @Nullable\n  private Boolean booleanValue_Boolean = (Boolean) null;\n\n  @Nullable\n  private String[] arrayValue_StringArray = (String[]) null;\n\n  @Nullable\n  private List<String> listValue_List = (List<String>) null;\n\n  @Nullable\n  private View.OnClickListener clickListener_OnClickListener = (View.OnClickListener) null;\n\n  @Nullable\n  private CustomClickListenerSubclass customClickListener_CustomClickListenerSubclass = (CustomClickListenerSubclass) null;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(7)) {\n    \tthrow new IllegalStateException(\"A value is required for setListOfEnumClass\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(4)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(5)) {\n    \tthrow new IllegalStateException(\"A value is required for setFunctionType\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(6)) {\n    \tthrow new IllegalStateException(\"A value is required for setListOfDataClass\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(17)) {\n    \tthrow new IllegalStateException(\"A value is required for setModels\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestManyTypesView buildView(ViewGroup parent) {\n    TestManyTypesView v = new TestManyTypesView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestManyTypesView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object) {\n    super.bind(object);\n    object.setListOfEnumClass(listOfEnumClass_List);\n    object.setArrayValue(arrayValue_StringArray);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setMyProperty(myProperty_Int);\n    object.setCustomClickListener(customClickListener_CustomClickListenerSubclass);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    object.setStringValue(stringValue_String);\n    object.setNullableStringValue(nullableStringValue_String);\n    object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    object.setEnabled(enabled_Boolean);\n    object.setFunctionType(functionType_Function2);\n    object.setIntegerValue(integerValue_Int);\n    object.setListValue(listValue_List);\n    object.setIntValue(intValue_Int);\n    object.setDelegatedProperty(delegatedProperty_Int);\n    object.setListOfDataClass(listOfDataClass_List);\n    object.setMyNullableProperty(myNullableProperty_Integer);\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setIntValueWithDefault(intValueWithDefault_Int);\n    }\n    else {\n      object.setIntValueWithDefault();\n    }\n    object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    object.setBoolValue(boolValue_Boolean);\n    object.setModels(models_List);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestManyTypesViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) previousModel;\n    super.bind(object);\n\n    if ((listOfEnumClass_List != null ? !listOfEnumClass_List.equals(that.listOfEnumClass_List) : that.listOfEnumClass_List != null)) {\n      object.setListOfEnumClass(listOfEnumClass_List);\n    }\n\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      object.setArrayValue(arrayValue_StringArray);\n    }\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((myProperty_Int != that.myProperty_Int)) {\n      object.setMyProperty(myProperty_Int);\n    }\n\n    if (((customClickListener_CustomClickListenerSubclass == null) != (that.customClickListener_CustomClickListenerSubclass == null))) {\n      object.setCustomClickListener(customClickListener_CustomClickListenerSubclass);\n    }\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      object.setNullableStringValue(nullableStringValue_String);\n    }\n\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    }\n\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    }\n\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    }\n\n    if ((enabled_Boolean != that.enabled_Boolean)) {\n      object.setEnabled(enabled_Boolean);\n    }\n\n    if (((functionType_Function2 == null) != (that.functionType_Function2 == null))) {\n      object.setFunctionType(functionType_Function2);\n    }\n\n    if ((integerValue_Int != that.integerValue_Int)) {\n      object.setIntegerValue(integerValue_Int);\n    }\n\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      object.setListValue(listValue_List);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      object.setDelegatedProperty(delegatedProperty_Int);\n    }\n\n    if ((listOfDataClass_List != null ? !listOfDataClass_List.equals(that.listOfDataClass_List) : that.listOfDataClass_List != null)) {\n      object.setListOfDataClass(listOfDataClass_List);\n    }\n\n    if ((myNullableProperty_Integer != null ? !myNullableProperty_Integer.equals(that.myNullableProperty_Integer) : that.myNullableProperty_Integer != null)) {\n      object.setMyNullableProperty(myNullableProperty_Integer);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      if ((intValueWithDefault_Int != that.intValueWithDefault_Int)) {\n        object.setIntValueWithDefault(intValueWithDefault_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setIntValueWithDefault();\n    }\n\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    }\n\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      object.setBoolValue(boolValue_Boolean);\n    }\n\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      object.setModels(models_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestManyTypesView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestManyTypesView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestManyTypesView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestManyTypesView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setMyProperty(int)\n   */\n  public TestManyTypesViewModel_ myProperty(int myProperty) {\n    onMutation();\n    this.myProperty_Int = myProperty;\n    return this;\n  }\n\n  public int myProperty() {\n    return myProperty_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (Integer) null\n   *\n   * @see TestManyTypesView#setMyNullableProperty(Integer)\n   */\n  public TestManyTypesViewModel_ myNullableProperty(@Nullable Integer myNullableProperty) {\n    onMutation();\n    this.myNullableProperty_Integer = myNullableProperty;\n    return this;\n  }\n\n  @Nullable\n  public Integer myNullableProperty() {\n    return myNullableProperty_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setDelegatedProperty(int)\n   */\n  public TestManyTypesViewModel_ delegatedProperty(int delegatedProperty) {\n    onMutation();\n    this.delegatedProperty_Int = delegatedProperty;\n    return this;\n  }\n\n  public int delegatedProperty() {\n    return delegatedProperty_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value TestManyTypesView#DEFAULT_ENABLED}</b>\n   *\n   * @see TestManyTypesView#setEnabled(boolean)\n   */\n  public TestManyTypesViewModel_ enabled(boolean enabled) {\n    onMutation();\n    this.enabled_Boolean = enabled;\n    return this;\n  }\n\n  public boolean enabled() {\n    return enabled_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setStringValue(String)\n   */\n  public TestManyTypesViewModel_ stringValue(@NonNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(4);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NonNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setFunctionType(Function2<? super String, ? super String, Integer>)\n   */\n  public TestManyTypesViewModel_ functionType(\n      @NonNull Function2<? super String, ? super String, Integer> functionType) {\n    if (functionType == null) {\n      throw new IllegalArgumentException(\"functionType cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(5);\n    onMutation();\n    this.functionType_Function2 = functionType;\n    return this;\n  }\n\n  @NonNull\n  public Function2<? super String, ? super String, Integer> functionType() {\n    return functionType_Function2;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListOfDataClass(List<SomeDataClass>)\n   */\n  public TestManyTypesViewModel_ listOfDataClass(@NonNull List<SomeDataClass> listOfDataClass) {\n    if (listOfDataClass == null) {\n      throw new IllegalArgumentException(\"listOfDataClass cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    onMutation();\n    this.listOfDataClass_List = listOfDataClass;\n    return this;\n  }\n\n  @NonNull\n  public List<SomeDataClass> listOfDataClass() {\n    return listOfDataClass_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListOfEnumClass(List<SomeEnumClass>)\n   */\n  public TestManyTypesViewModel_ listOfEnumClass(@NonNull List<SomeEnumClass> listOfEnumClass) {\n    if (listOfEnumClass == null) {\n      throw new IllegalArgumentException(\"listOfEnumClass cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(7);\n    onMutation();\n    this.listOfEnumClass_List = listOfEnumClass;\n    return this;\n  }\n\n  @NonNull\n  public List<SomeEnumClass> listOfEnumClass() {\n    return listOfEnumClass_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see TestManyTypesView#setNullableStringValue(String)\n   */\n  public TestManyTypesViewModel_ nullableStringValue(@Nullable String nullableStringValue) {\n    onMutation();\n    this.nullableStringValue_String = nullableStringValue;\n    return this;\n  }\n\n  @Nullable\n  public String nullableStringValue() {\n    return nullableStringValue_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValue(int)\n   */\n  public TestManyTypesViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: View function has a Kotlin default argument\n   *\n   * @see TestManyTypesView#setIntValueWithDefault(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDefault(int intValueWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.intValueWithDefault_Int = intValueWithDefault;\n    return this;\n  }\n\n  public int intValueWithDefault() {\n    return intValueWithDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithAnnotation(@StringRes int intValueWithAnnotation) {\n    onMutation();\n    this.intValueWithAnnotation_Int = intValueWithAnnotation;\n    return this;\n  }\n\n  @StringRes\n  public int intValueWithAnnotation() {\n    return intValueWithAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithRangeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation) {\n    onMutation();\n    this.intValueWithRangeAnnotation_Int = intValueWithRangeAnnotation;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  public int intValueWithRangeAnnotation() {\n    return intValueWithRangeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithDimenTypeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation) {\n    onMutation();\n    this.intValueWithDimenTypeAnnotation_Int = intValueWithDimenTypeAnnotation;\n    return this;\n  }\n\n  @Dimension(\n      unit = 0\n  )\n  public int intValueWithDimenTypeAnnotation() {\n    return intValueWithDimenTypeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntWithMultipleAnnotations(int)\n   */\n  public TestManyTypesViewModel_ intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations) {\n    onMutation();\n    this.intWithMultipleAnnotations_Int = intWithMultipleAnnotations;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  public int intWithMultipleAnnotations() {\n    return intWithMultipleAnnotations_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntegerValue(int)\n   */\n  public TestManyTypesViewModel_ integerValue(int integerValue) {\n    onMutation();\n    this.integerValue_Int = integerValue;\n    return this;\n  }\n\n  public int integerValue() {\n    return integerValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestManyTypesView#setBoolValue(boolean)\n   */\n  public TestManyTypesViewModel_ boolValue(boolean boolValue) {\n    onMutation();\n    this.boolValue_Boolean = boolValue;\n    return this;\n  }\n\n  public boolean boolValue() {\n    return boolValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setModels(List<? extends EpoxyModel<?>>)\n   */\n  public TestManyTypesViewModel_ models(@NonNull List<? extends EpoxyModel<?>> models) {\n    if (models == null) {\n      throw new IllegalArgumentException(\"models cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(17);\n    onMutation();\n    this.models_List = models;\n    return this;\n  }\n\n  @NonNull\n  public List<? extends EpoxyModel<?>> models() {\n    return models_List;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (Boolean) null\n   *\n   * @see TestManyTypesView#setBooleanValue(Boolean)\n   */\n  public TestManyTypesViewModel_ booleanValue(@Nullable Boolean booleanValue) {\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  @Nullable\n  public Boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String[]) null\n   *\n   * @see TestManyTypesView#setArrayValue(String[])\n   */\n  public TestManyTypesViewModel_ arrayValue(@Nullable String[] arrayValue) {\n    onMutation();\n    this.arrayValue_StringArray = arrayValue;\n    return this;\n  }\n\n  @Nullable\n  public String[] arrayValue() {\n    return arrayValue_StringArray;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (List<String>) null\n   *\n   * @see TestManyTypesView#setListValue(List<String>)\n   */\n  public TestManyTypesViewModel_ listValue(@Nullable List<String> listValue) {\n    onMutation();\n    this.listValue_List = listValue;\n    return this;\n  }\n\n  @Nullable\n  public List<String> listValue() {\n    return listValue_List;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestManyTypesViewModel_ clickListener(\n      @Nullable final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestManyTypesView#setClickListener(View.OnClickListener)\n   */\n  public TestManyTypesViewModel_ clickListener(@Nullable View.OnClickListener clickListener) {\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CustomClickListenerSubclass) null\n   *\n   * @see TestManyTypesView#setCustomClickListener(CustomClickListenerSubclass)\n   */\n  public TestManyTypesViewModel_ customClickListener(\n      @Nullable CustomClickListenerSubclass customClickListener) {\n    onMutation();\n    this.customClickListener_CustomClickListenerSubclass = customClickListener;\n    return this;\n  }\n\n  @Nullable\n  public CustomClickListenerSubclass customClickListener() {\n    return customClickListener_CustomClickListenerSubclass;\n  }\n\n  @Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestManyTypesViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestManyTypesViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.myProperty_Int = 0;\n    this.myNullableProperty_Integer = (Integer) null;\n    this.delegatedProperty_Int = 0;\n    this.enabled_Boolean = TestManyTypesView.DEFAULT_ENABLED;\n    this.stringValue_String = null;\n    this.functionType_Function2 = null;\n    this.listOfDataClass_List = null;\n    this.listOfEnumClass_List = null;\n    this.nullableStringValue_String = (String) null;\n    this.intValue_Int = 0;\n    this.intValueWithDefault_Int = 0;\n    this.intValueWithAnnotation_Int = 0;\n    this.intValueWithRangeAnnotation_Int = 0;\n    this.intValueWithDimenTypeAnnotation_Int = 0;\n    this.intWithMultipleAnnotations_Int = 0;\n    this.integerValue_Int = 0;\n    this.boolValue_Boolean = false;\n    this.models_List = null;\n    this.booleanValue_Boolean = (Boolean) null;\n    this.arrayValue_StringArray = (String[]) null;\n    this.listValue_List = (List<String>) null;\n    this.clickListener_OnClickListener = (View.OnClickListener) null;\n    this.customClickListener_CustomClickListenerSubclass = (CustomClickListenerSubclass) null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestManyTypesViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((myProperty_Int != that.myProperty_Int)) {\n      return false;\n    }\n    if ((myNullableProperty_Integer != null ? !myNullableProperty_Integer.equals(that.myNullableProperty_Integer) : that.myNullableProperty_Integer != null)) {\n      return false;\n    }\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      return false;\n    }\n    if ((enabled_Boolean != that.enabled_Boolean)) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if (((functionType_Function2 == null) != (that.functionType_Function2 == null))) {\n      return false;\n    }\n    if ((listOfDataClass_List != null ? !listOfDataClass_List.equals(that.listOfDataClass_List) : that.listOfDataClass_List != null)) {\n      return false;\n    }\n    if ((listOfEnumClass_List != null ? !listOfEnumClass_List.equals(that.listOfEnumClass_List) : that.listOfEnumClass_List != null)) {\n      return false;\n    }\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((intValueWithDefault_Int != that.intValueWithDefault_Int)) {\n      return false;\n    }\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      return false;\n    }\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      return false;\n    }\n    if ((integerValue_Int != that.integerValue_Int)) {\n      return false;\n    }\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      return false;\n    }\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      return false;\n    }\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      return false;\n    }\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      return false;\n    }\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if (((customClickListener_CustomClickListenerSubclass == null) != (that.customClickListener_CustomClickListenerSubclass == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + myProperty_Int;\n    _result = 31 * _result + (myNullableProperty_Integer != null ? myNullableProperty_Integer.hashCode() : 0);\n    _result = 31 * _result + delegatedProperty_Int;\n    _result = 31 * _result + (enabled_Boolean ? 1 : 0);\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (functionType_Function2 != null ? 1 : 0);\n    _result = 31 * _result + (listOfDataClass_List != null ? listOfDataClass_List.hashCode() : 0);\n    _result = 31 * _result + (listOfEnumClass_List != null ? listOfEnumClass_List.hashCode() : 0);\n    _result = 31 * _result + (nullableStringValue_String != null ? nullableStringValue_String.hashCode() : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + intValueWithDefault_Int;\n    _result = 31 * _result + intValueWithAnnotation_Int;\n    _result = 31 * _result + intValueWithRangeAnnotation_Int;\n    _result = 31 * _result + intValueWithDimenTypeAnnotation_Int;\n    _result = 31 * _result + intWithMultipleAnnotations_Int;\n    _result = 31 * _result + integerValue_Int;\n    _result = 31 * _result + (boolValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (models_List != null ? models_List.hashCode() : 0);\n    _result = 31 * _result + (booleanValue_Boolean != null ? booleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(arrayValue_StringArray);\n    _result = 31 * _result + (listValue_List != null ? listValue_List.hashCode() : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (customClickListener_CustomClickListenerSubclass != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestManyTypesViewModel_{\" +\n        \"myProperty_Int=\" + myProperty_Int +\n        \", myNullableProperty_Integer=\" + myNullableProperty_Integer +\n        \", delegatedProperty_Int=\" + delegatedProperty_Int +\n        \", enabled_Boolean=\" + enabled_Boolean +\n        \", stringValue_String=\" + stringValue_String +\n        \", listOfDataClass_List=\" + listOfDataClass_List +\n        \", listOfEnumClass_List=\" + listOfEnumClass_List +\n        \", nullableStringValue_String=\" + nullableStringValue_String +\n        \", intValue_Int=\" + intValue_Int +\n        \", intValueWithDefault_Int=\" + intValueWithDefault_Int +\n        \", intValueWithAnnotation_Int=\" + intValueWithAnnotation_Int +\n        \", intValueWithRangeAnnotation_Int=\" + intValueWithRangeAnnotation_Int +\n        \", intValueWithDimenTypeAnnotation_Int=\" + intValueWithDimenTypeAnnotation_Int +\n        \", intWithMultipleAnnotations_Int=\" + intWithMultipleAnnotations_Int +\n        \", integerValue_Int=\" + integerValue_Int +\n        \", boolValue_Boolean=\" + boolValue_Boolean +\n        \", models_List=\" + models_List +\n        \", booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", arrayValue_StringArray=\" + arrayValue_StringArray +\n        \", listValue_List=\" + listValue_List +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", customClickListener_CustomClickListenerSubclass=\" + customClickListener_CustomClickListenerSubclass +\n        \", title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testStyleableViewKotlinSources/ModelViewWithParis.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.paris.annotations.Style\nimport com.airbnb.paris.annotations.Styleable\nimport com.airbnb.paris.extensions.modelViewWithParisStyle\nimport kotlin.properties.Delegates\n\n@Styleable\n@ModelView\nclass ModelViewWithParis(context: Context?) : View(context) {\n    @set:ModelProp\n    var value = 0\n\n    @set:ModelProp\n    var delegatedProperty: Int by Delegates.observable(0) { _, _, _ ->\n\n    }\n\n    companion object {\n        @JvmStatic\n        @Style(isDefault = true)\n        val headerStyle: com.airbnb.paris.styles.Style = modelViewWithParisStyle  {\n\n        }\n    }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testStyleableViewKotlinSources/ModelViewWithParisModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.AsyncTask;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.paris.StyleApplierUtils;\nimport com.airbnb.paris.styles.Style;\nimport com.airbnb.viewmodeladapter.R;\nimport java.lang.AssertionError;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Runnable;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewWithParisModel_ extends EpoxyModel<ModelViewWithParis> implements GeneratedModel<ModelViewWithParis>, ModelViewWithParisModelBuilder {\n  private static final Style DEFAULT_PARIS_STYLE = new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n\n  private static WeakReference<Style> parisStyleReference_header;\n\n  private static WeakReference<Style> parisStyleReference_other;\n\n  private static WeakReference<Style> parisStyleReference_default;\n\n  private OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  private Style style = DEFAULT_PARIS_STYLE;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewWithParis buildView(ViewGroup parent) {\n    ModelViewWithParis v = new ModelViewWithParis(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewWithParis object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {\n        public void run() {\n          try {\n            StyleApplierUtils.Companion.assertSameAttributes(new ModelViewWithParisStyleApplier(object), style, DEFAULT_PARIS_STYLE);\n          }\n          catch(AssertionError e) {\n            throw new IllegalStateException(\"ModelViewWithParisModel_ model at position \" + position + \" has an invalid style:\\n\\n\" + e.getMessage());\n          }\n        }\n      } );\n    }\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object) {\n\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n    object.value = value_Int;\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewWithParisModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) previousModel;\n\n    if (!Objects.equals(style, that.style)) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.value = value_Int;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewWithParis object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onBind(\n      OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewWithParis object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onUnbind(\n      OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewWithParis object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewWithParis object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ style(Style style) {\n    onMutation();\n    this.style = style;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ styleBuilder(\n      StyleBuilderCallback<ModelViewWithParisStyleApplier.StyleBuilder> builderCallback) {\n    ModelViewWithParisStyleApplier.StyleBuilder builder = new ModelViewWithParisStyleApplier.StyleBuilder();\n    builderCallback.buildStyle(builder.addDefault());\n    return style(builder.build());\n  }\n\n  /**\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withHeaderStyle() {\n    Style style = parisStyleReference_header != null ? parisStyleReference_header.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addHeader().build();\n      parisStyleReference_header = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *  @see ModelViewWithParis#otherStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withOtherStyle() {\n    Style style = parisStyleReference_other != null ? parisStyleReference_other.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addOther().build();\n      parisStyleReference_other = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withDefaultStyle() {\n    Style style = parisStyleReference_default != null ? parisStyleReference_default.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n      parisStyleReference_default = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewWithParis#value\n   */\n  public ModelViewWithParisModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key,\n      @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    this.style = DEFAULT_PARIS_STYLE;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewWithParisModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    if ((style != null ? !style.equals(that.style) : that.style != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    _result = 31 * _result + (style != null ? style.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewWithParisModel_{\" +\n        \"value_Int=\" + value_Int +\n        \", style=\" + style +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/testStyleableViewKotlinSources/ksp/ModelViewWithParisModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.AsyncTask;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.paris.StyleApplierUtils;\nimport com.airbnb.paris.styles.Style;\nimport com.airbnb.viewmodeladapter.R;\nimport java.lang.AssertionError;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Runnable;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewWithParisModel_ extends EpoxyModel<ModelViewWithParis> implements GeneratedModel<ModelViewWithParis>, ModelViewWithParisModelBuilder {\n  private static final Style DEFAULT_PARIS_STYLE = new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n\n  private static WeakReference<Style> parisStyleReference_header;\n\n  private static WeakReference<Style> parisStyleReference_default;\n\n  private OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  private int delegatedProperty_Int = 0;\n\n  private Style style = DEFAULT_PARIS_STYLE;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewWithParis buildView(ViewGroup parent) {\n    ModelViewWithParis v = new ModelViewWithParis(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewWithParis object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {\n        public void run() {\n          try {\n            StyleApplierUtils.Companion.assertSameAttributes(new ModelViewWithParisStyleApplier(object), style, DEFAULT_PARIS_STYLE);\n          }\n          catch(AssertionError e) {\n            throw new IllegalStateException(\"ModelViewWithParisModel_ model at position \" + position + \" has an invalid style:\\n\\n\" + e.getMessage());\n          }\n        }\n      } );\n    }\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object) {\n\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n    object.setValue(value_Int);\n    object.setDelegatedProperty(delegatedProperty_Int);\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewWithParisModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) previousModel;\n\n    if (!Objects.equals(style, that.style)) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      object.setDelegatedProperty(delegatedProperty_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewWithParis object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onBind(\n      OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewWithParis object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onUnbind(\n      OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewWithParis object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewWithParis object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ style(Style style) {\n    onMutation();\n    this.style = style;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ styleBuilder(\n      StyleBuilderCallback<ModelViewWithParisStyleApplier.StyleBuilder> builderCallback) {\n    ModelViewWithParisStyleApplier.StyleBuilder builder = new ModelViewWithParisStyleApplier.StyleBuilder();\n    builderCallback.buildStyle(builder.addDefault());\n    return style(builder.build());\n  }\n\n  /**\n   *\n   *  @see ModelViewWithParis.Companion#headerStyle\n   */\n  public ModelViewWithParisModel_ withHeaderStyle() {\n    Style style = parisStyleReference_header != null ? parisStyleReference_header.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addHeader().build();\n      parisStyleReference_header = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *\n   *  @see ModelViewWithParis.Companion#headerStyle\n   */\n  public ModelViewWithParisModel_ withDefaultStyle() {\n    Style style = parisStyleReference_default != null ? parisStyleReference_default.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n      parisStyleReference_default = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewWithParis#setValue(int)\n   */\n  public ModelViewWithParisModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewWithParis#setDelegatedProperty(int)\n   */\n  public ModelViewWithParisModel_ delegatedProperty(int delegatedProperty) {\n    onMutation();\n    this.delegatedProperty_Int = delegatedProperty;\n    return this;\n  }\n\n  public int delegatedProperty() {\n    return delegatedProperty_Int;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    this.delegatedProperty_Int = 0;\n    this.style = DEFAULT_PARIS_STYLE;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewWithParisModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    if ((delegatedProperty_Int != that.delegatedProperty_Int)) {\n      return false;\n    }\n    if ((style != null ? !style.equals(that.style) : that.style != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    _result = 31 * _result + delegatedProperty_Int;\n    _result = 31 * _result + (style != null ? style.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewWithParisModel_{\" +\n        \"value_Int=\" + value_Int +\n        \", delegatedProperty_Int=\" + delegatedProperty_Int +\n        \", style=\" + style +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/AirEpoxyModel.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute.Option;\n\nimport androidx.annotation.Nullable;\n\npublic abstract class AirEpoxyModel<T extends View> extends EpoxyModel<T> {\n\n  /**\n   * Whether the divider should be shown on the bound view. This should only be set if {@link #supportsDividers()} is true for your model.\n   * <p>\n   * If this is left as null then the divider will default to hidden.\n   * <p>\n   * The getter and setter are both omitted so the {@link AirModel} divider methods can be used instead.\n   */\n  @EpoxyAttribute({Option.NoGetter, Option.NoSetter}) protected Boolean showDivider;\n\n  /**\n   * The number of items that should be shown on screen. This assumes the model is used in a horizontal RecyclerView (aka {@link Carousel}), and the\n   * view will have its width resized so that the appropriate number of items fit on screen.\n   * <p>\n   * We don't generate a getter since this class defines one, so it is accessible with just a `AirEpoxyModel` reference.\n   */\n  @Nullable @EpoxyAttribute(Option.NoGetter) protected SomeType numCarouselItemsShown;\n\n  public AirEpoxyModel<T> numCarouselItemsShown(SomeType numCarouselItemsShown) {\n    this.numCarouselItemsShown = numCarouselItemsShown;\n    return this;\n  }\n\n  @Nullable\n  public SomeType numCarouselItemsShown() {\n    return numCarouselItemsShown;\n  }\n\n  public static class SomeType {\n\n  }\n}"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/SourceView.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport android.view.View.OnClickListener\n\n@ModelView(\n    autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,\n    baseModelClass = AirEpoxyModel::class\n)\nclass SourceView(context: Context) : View(context) {\n\n    @CallbackProp\n    fun setKeyedListener(listener: KeyedListener<*, OnClickListener>?) {}\n\n}\n\ndata class KeyedListener<Key, Listener>(val identifier: Key, val listener: Listener)\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.String;\nimport org.jetbrains.annotations.Nullable;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder sectionId(@Nullable(\"\") String sectionId);\n\n  SourceViewModelBuilder baseViewProp(int baseViewProp);\n\n  SourceViewModelBuilder showDividerWithSetter(Boolean showDividerWithSetter);\n\n  SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider);\n\n  SourceViewModelBuilder id(long id);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable Number... ids);\n\n  SourceViewModelBuilder id(long id1, long id2);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys);\n\n  SourceViewModelBuilder id(@androidx.annotation.Nullable CharSequence key, long id);\n\n  SourceViewModelBuilder spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport org.jetbrains.annotations.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable(\"\")\n  private String sectionId_String = (String) null;\n\n  private int baseViewProp_Int = 0;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setSectionId(sectionId_String);\n    object.baseViewProp(baseViewProp_Int);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      object.setSectionId(sectionId_String);\n    }\n\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      object.baseViewProp(baseViewProp_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see SourceView#setSectionId(String)\n   */\n  public SourceViewModel_ sectionId(@Nullable(\"\") String sectionId) {\n    onMutation();\n    this.sectionId_String = sectionId;\n    return this;\n  }\n\n  @Nullable(\"\")\n  public String sectionId() {\n    return sectionId_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see BaseView#baseViewProp(int)\n   */\n  public SourceViewModel_ baseViewProp(int baseViewProp) {\n    onMutation();\n    this.baseViewProp_Int = baseViewProp;\n    return this;\n  }\n\n  public int baseViewProp() {\n    return baseViewProp_Int;\n  }\n\n  public SourceViewModel_ showDividerWithSetter(Boolean showDividerWithSetter) {\n    onMutation();\n    super.setShowDividerWithSetter(showDividerWithSetter);\n    return this;\n  }\n\n  public Boolean showDividerWithSetter() {\n    return super.getShowDividerWithSetter();\n  }\n\n  @Override\n  public SourceViewModel_ showDividerWithOverriddenMethod(boolean showDivider) {\n    super.showDividerWithOverriddenMethod(showDivider);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key,\n      @androidx.annotation.Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@androidx.annotation.Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int layoutRes) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.sectionId_String = (String) null;\n    this.baseViewProp_Int = 0;\n    super.setShowDivider(null);\n    super.setShowDividerWithSetter(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((sectionId_String != null ? !sectionId_String.equals(that.sectionId_String) : that.sectionId_String != null)) {\n      return false;\n    }\n    if ((baseViewProp_Int != that.baseViewProp_Int)) {\n      return false;\n    }\n    if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) {\n      return false;\n    }\n    if ((getShowDividerWithSetter() != null ? !getShowDividerWithSetter().equals(that.getShowDividerWithSetter()) : that.getShowDividerWithSetter() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0);\n    _result = 31 * _result + baseViewProp_Int;\n    _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0);\n    _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"sectionId_String=\" + sectionId_String +\n        \", baseViewProp_Int=\" + baseViewProp_Int +\n        \", showDivider=\" + getShowDivider() +\n        \", showDividerWithSetter=\" + getShowDividerWithSetter() +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/ksp/SourceViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\n\n@EpoxyBuildScope\npublic interface SourceViewModelBuilder {\n  SourceViewModelBuilder onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener);\n\n  SourceViewModelBuilder keyedListener(\n      @Nullable KeyedListener<?, View.OnClickListener> keyedListener);\n\n  SourceViewModelBuilder numCarouselItemsShown(\n      @Nullable AirEpoxyModel.SomeType numCarouselItemsShown);\n\n  SourceViewModelBuilder id(long p0);\n\n  SourceViewModelBuilder id(@Nullable Number... p0);\n\n  SourceViewModelBuilder id(long p0, long p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  SourceViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  SourceViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ViewProcessorTest/wildcardHandling/ksp/SourceViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SourceViewModel_ extends AirEpoxyModel<SourceView> implements GeneratedModel<SourceView>, SourceViewModelBuilder {\n  private OnModelBoundListener<SourceViewModel_, SourceView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SourceViewModel_, SourceView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SourceViewModel_, SourceView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private KeyedListener<?, View.OnClickListener> keyedListener_KeyedListener = (KeyedListener<?, View.OnClickListener>) null;\n\n  public SourceViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public SourceView buildView(ViewGroup parent) {\n    SourceView v = new SourceView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SourceView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SourceView object) {\n    super.bind(object);\n    object.setKeyedListener(keyedListener_KeyedListener);\n  }\n\n  @Override\n  public void bind(final SourceView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SourceViewModel_)) {\n      bind(object);\n      return;\n    }\n    SourceViewModel_ that = (SourceViewModel_) previousModel;\n    super.bind(object);\n\n    if (((keyedListener_KeyedListener == null) != (that.keyedListener_KeyedListener == null))) {\n      object.setKeyedListener(keyedListener_KeyedListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SourceView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onBind(OnModelBoundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SourceView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setKeyedListener((KeyedListener<?, View.OnClickListener>) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SourceViewModel_ onUnbind(OnModelUnboundListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SourceView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SourceView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SourceViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SourceViewModel_, SourceView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (KeyedListener<?, View.OnClickListener>) null\n   *\n   * @see SourceView#setKeyedListener(KeyedListener<?, View.OnClickListener>)\n   */\n  public SourceViewModel_ keyedListener(\n      @Nullable KeyedListener<?, View.OnClickListener> keyedListener) {\n    onMutation();\n    this.keyedListener_KeyedListener = keyedListener;\n    return this;\n  }\n\n  @Nullable\n  public KeyedListener<?, View.OnClickListener> keyedListener() {\n    return keyedListener_KeyedListener;\n  }\n\n  /**\n   * The number of items that should be shown on screen. This assumes the model is used in a horizontal RecyclerView (aka {@link Carousel}), and the\n   *  view will have its width resized so that the appropriate number of items fit on screen.\n   *  <p>\n   *  We don't generate a getter since this class defines one, so it is accessible with just a `AirEpoxyModel` reference.\n   */\n  public SourceViewModel_ numCarouselItemsShown(\n      @Nullable AirEpoxyModel.SomeType numCarouselItemsShown) {\n    onMutation();\n    super.numCarouselItemsShown = numCarouselItemsShown;\n    super.numCarouselItemsShown(numCarouselItemsShown);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public SourceViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SourceViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public SourceViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.keyedListener_KeyedListener = (KeyedListener<?, View.OnClickListener>) null;\n    super.showDivider = null;\n    super.numCarouselItemsShown = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SourceViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SourceViewModel_ that = (SourceViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((keyedListener_KeyedListener == null) != (that.keyedListener_KeyedListener == null))) {\n      return false;\n    }\n    if ((showDivider != null ? !showDivider.equals(that.showDivider) : that.showDivider != null)) {\n      return false;\n    }\n    if ((numCarouselItemsShown != null ? !numCarouselItemsShown.equals(that.numCarouselItemsShown) : that.numCarouselItemsShown != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (keyedListener_KeyedListener != null ? 1 : 0);\n    _result = 31 * _result + (showDivider != null ? showDivider.hashCode() : 0);\n    _result = 31 * _result + (numCarouselItemsShown != null ? numCarouselItemsShown.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SourceViewModel_{\" +\n        \"keyedListener_KeyedListener=\" + keyedListener_KeyedListener +\n        \", showDivider=\" + showDivider +\n        \", numCarouselItemsShown=\" + numCarouselItemsShown +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfig/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfig/ksp/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfig/ksp/actual/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfigIsOverriddenByViewSetting/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends EpoxyModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfigIsOverriddenByViewSetting/ksp/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends EpoxyModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelFromPackageConfigIsOverriddenByViewSetting/ksp/actual/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends EpoxyModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithAttribute/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  public BaseModelViewModel_ baseModelString(String baseModelString) {\n    onMutation();\n    super.baseModelString = baseModelString;\n    return this;\n  }\n\n  public String baseModelString() {\n    return baseModelString;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.baseModelString = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    if ((baseModelString != null ? !baseModelString.equals(that.baseModelString) : that.baseModelString != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    _result = 31 * _result + (baseModelString != null ? baseModelString.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \", baseModelString=\" + baseModelString +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithAttribute/ksp/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  public BaseModelViewModel_ baseModelString(String baseModelString) {\n    onMutation();\n    super.baseModelString = baseModelString;\n    return this;\n  }\n\n  public String baseModelString() {\n    return baseModelString;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.baseModelString = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    if ((baseModelString != null ? !baseModelString.equals(that.baseModelString) : that.baseModelString != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    _result = 31 * _result + (baseModelString != null ? baseModelString.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \", baseModelString=\" + baseModelString +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithAttribute/ksp/actual/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  public BaseModelViewModel_ baseModelString(String baseModelString) {\n    onMutation();\n    super.baseModelString = baseModelString;\n    return this;\n  }\n\n  public String baseModelString() {\n    return baseModelString;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.baseModelString = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    if ((baseModelString != null ? !baseModelString.equals(that.baseModelString) : that.baseModelString != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    _result = 31 * _result + (baseModelString != null ? baseModelString.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \", baseModelString=\" + baseModelString +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithDiffBind/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object, previousModel);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id) {\n    super.id(id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... ids) {\n    super.id(ids);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long id1, long id2) {\n    super.id(id1, id2);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key) {\n    super.id(key);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, @Nullable CharSequence... otherKeys) {\n    super.id(key, otherKeys);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence key, long id) {\n    super.id(key, id);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int layoutRes) {\n    super.layout(layoutRes);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback spanSizeCallback) {\n    super.spanSizeOverride(spanSizeCallback);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean show) {\n    super.show(show);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithDiffBind/ksp/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object, previousModel);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/baseModelWithDiffBind/ksp/actual/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object, previousModel);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/AbstractEpoxyModelWithView_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AbstractEpoxyModelWithView_ extends AbstractEpoxyModelWithView implements GeneratedModel<View>, AbstractEpoxyModelWithViewBuilder {\n  private OnModelBoundListener<AbstractEpoxyModelWithView_, View> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AbstractEpoxyModelWithView_, View> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AbstractEpoxyModelWithView_, View> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AbstractEpoxyModelWithView_, View> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public AbstractEpoxyModelWithView_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final View object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final View object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractEpoxyModelWithView_ onBind(\n      OnModelBoundListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(View object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractEpoxyModelWithView_ onUnbind(\n      OnModelUnboundListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final View object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractEpoxyModelWithView_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final View object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractEpoxyModelWithView_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AbstractEpoxyModelWithView_, View> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public AbstractEpoxyModelWithView_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AbstractEpoxyModelWithView_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AbstractEpoxyModelWithView_ that = (AbstractEpoxyModelWithView_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AbstractEpoxyModelWithView_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/AutoLayoutModelViewManualLayoutParamsModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.NullPointerException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewManualLayoutParamsModel_ extends EpoxyModel<AutoLayoutModelViewManualLayoutParams> implements GeneratedModel<AutoLayoutModelViewManualLayoutParams>, AutoLayoutModelViewManualLayoutParamsModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParams buildView(ViewGroup parent) {\n    AutoLayoutModelViewManualLayoutParams v = new AutoLayoutModelViewManualLayoutParams(parent.getContext());\n    if (v.getLayoutParams() == null) {\n      throw new NullPointerException(\"Layout params is required to be set for Size.MANUAL\");\n    }\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final AutoLayoutModelViewManualLayoutParams object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewManualLayoutParams object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewManualLayoutParams object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewManualLayoutParamsModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewManualLayoutParamsModel_ that = (AutoLayoutModelViewManualLayoutParamsModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelViewManualLayoutParams object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelViewManualLayoutParams object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final AutoLayoutModelViewManualLayoutParams object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelViewManualLayoutParams object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewManualLayoutParamsModel_, AutoLayoutModelViewManualLayoutParams> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelViewManualLayoutParams#setValue(int)\n   */\n  public AutoLayoutModelViewManualLayoutParamsModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewManualLayoutParamsModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewManualLayoutParamsModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewManualLayoutParamsModel_ that = (AutoLayoutModelViewManualLayoutParamsModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewManualLayoutParamsModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/AutoLayoutModelViewMatchParentModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewMatchParentModel_ extends EpoxyModel<AutoLayoutModelViewMatchParent> implements GeneratedModel<AutoLayoutModelViewMatchParent>, AutoLayoutModelViewMatchParentModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParent buildView(ViewGroup parent) {\n    AutoLayoutModelViewMatchParent v = new AutoLayoutModelViewMatchParent(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final AutoLayoutModelViewMatchParent object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewMatchParent object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelViewMatchParent object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewMatchParentModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewMatchParentModel_ that = (AutoLayoutModelViewMatchParentModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelViewMatchParent object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewMatchParentModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelViewMatchParent object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewMatchParentModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final AutoLayoutModelViewMatchParent object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewMatchParentModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelViewMatchParent object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewMatchParentModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewMatchParentModel_, AutoLayoutModelViewMatchParent> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelViewMatchParent#setValue(int)\n   */\n  public AutoLayoutModelViewMatchParentModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewMatchParentModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewMatchParentModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewMatchParentModel_ that = (AutoLayoutModelViewMatchParentModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewMatchParentModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/AutoLayoutModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AutoLayoutModelViewModel_ extends EpoxyModel<AutoLayoutModelView> implements GeneratedModel<AutoLayoutModelView>, AutoLayoutModelViewModelBuilder {\n  private OnModelBoundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public AutoLayoutModelView buildView(ViewGroup parent) {\n    AutoLayoutModelView v = new AutoLayoutModelView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final AutoLayoutModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelView object) {\n    super.bind(object);\n    object.setValue(value_Int);\n  }\n\n  @Override\n  public void bind(final AutoLayoutModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof AutoLayoutModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    AutoLayoutModelViewModel_ that = (AutoLayoutModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.setValue(value_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final AutoLayoutModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewModel_ onBind(\n      OnModelBoundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(AutoLayoutModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AutoLayoutModelViewModel_ onUnbind(\n      OnModelUnboundListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final AutoLayoutModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final AutoLayoutModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AutoLayoutModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AutoLayoutModelViewModel_, AutoLayoutModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see AutoLayoutModelView#setValue(int)\n   */\n  public AutoLayoutModelViewModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public AutoLayoutModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AutoLayoutModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AutoLayoutModelViewModel_ that = (AutoLayoutModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AutoLayoutModelViewModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/BaseModelViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BaseModelViewModel_ extends TestBaseModel<BaseModelView> implements GeneratedModel<BaseModelView>, BaseModelViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<BaseModelViewModel_, BaseModelView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BaseModelViewModel_, BaseModelView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  public BaseModelViewModel_(long id) {\n    super(id);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final BaseModelView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final BaseModelView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final BaseModelView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof BaseModelViewModel_)) {\n      bind(object);\n      return;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final BaseModelView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onBind(\n      OnModelBoundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(BaseModelView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BaseModelViewModel_ onUnbind(\n      OnModelUnboundListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final BaseModelView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final BaseModelView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BaseModelViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BaseModelViewModel_, BaseModelView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see BaseModelView#setClickListener(String)\n   */\n  public BaseModelViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BaseModelViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public BaseModelViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BaseModelViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BaseModelViewModel_ that = (BaseModelViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BaseModelViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/BasicModelWithAttribute_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class BasicModelWithAttribute_ extends BasicModelWithAttribute implements GeneratedModel<Object>, BasicModelWithAttributeBuilder {\n  private OnModelBoundListener<BasicModelWithAttribute_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<BasicModelWithAttribute_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<BasicModelWithAttribute_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<BasicModelWithAttribute_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public BasicModelWithAttribute_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithAttribute_ onBind(\n      OnModelBoundListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public BasicModelWithAttribute_ onUnbind(\n      OnModelUnboundListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithAttribute_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public BasicModelWithAttribute_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<BasicModelWithAttribute_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public BasicModelWithAttribute_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public BasicModelWithAttribute_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof BasicModelWithAttribute_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    BasicModelWithAttribute_ that = (BasicModelWithAttribute_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"BasicModelWithAttribute_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass> {\n  private final ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute3;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModelWithSuperClass$SubControllerWithAutoModelWithSuperClass_EpoxyHelper(\n      ControllerWithAutoModelWithSuperClass.SubControllerWithAutoModelWithSuperClass controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute3 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute3.id(-2);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-3);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute3, controller.modelWithAttribute3, \"modelWithAttribute3\", -2);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -3);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute3 = controller.modelWithAttribute3;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ControllerWithAutoModelWithSuperClass_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModelWithSuperClass_EpoxyHelper extends ControllerHelper<ControllerWithAutoModelWithSuperClass> {\n  private final ControllerWithAutoModelWithSuperClass controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModelWithSuperClass_EpoxyHelper(\n      ControllerWithAutoModelWithSuperClass controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ControllerWithAutoModel_EpoxyHelper.java",
    "content": "package com.airbnb.epoxy.adapter;\n\nimport com.airbnb.epoxy.BasicModelWithAttribute_;\nimport com.airbnb.epoxy.ControllerHelper;\nimport com.airbnb.epoxy.EpoxyModel;\nimport java.lang.IllegalStateException;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ControllerWithAutoModel_EpoxyHelper extends ControllerHelper<ControllerWithAutoModel> {\n  private final ControllerWithAutoModel controller;\n\n  private EpoxyModel modelWithAttribute1;\n\n  private EpoxyModel modelWithAttribute2;\n\n  public ControllerWithAutoModel_EpoxyHelper(ControllerWithAutoModel controller) {\n    this.controller = controller;\n  }\n\n  @Override\n  public void resetAutoModels() {\n    validateModelsHaveNotChanged();\n    controller.modelWithAttribute1 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute1.id(-1);\n    controller.modelWithAttribute2 = new BasicModelWithAttribute_();\n    controller.modelWithAttribute2.id(-2);\n    saveModelsForNextValidation();\n  }\n\n  private void validateModelsHaveNotChanged() {\n    validateSameModel(modelWithAttribute1, controller.modelWithAttribute1, \"modelWithAttribute1\", -1);\n    validateSameModel(modelWithAttribute2, controller.modelWithAttribute2, \"modelWithAttribute2\", -2);\n    validateModelHashCodesHaveNotChanged(controller);\n  }\n\n  private void validateSameModel(EpoxyModel expectedObject, EpoxyModel actualObject,\n      String fieldName, int id) {\n    if (expectedObject != actualObject) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot be directly assigned. The controller manages these fields for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n    if (actualObject != null && actualObject.id() != id) {\n      throw new IllegalStateException(\"Fields annotated with AutoModel cannot have their id changed manually. The controller manages the ids of these models for you. (\" + controller.getClass().getSimpleName() + \"#\" + fieldName + \")\");\n    }\n  }\n\n  private void saveModelsForNextValidation() {\n    modelWithAttribute1 = controller.modelWithAttribute1;\n    modelWithAttribute2 = controller.modelWithAttribute2;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/CustomPackageLayoutPatternViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class CustomPackageLayoutPatternViewModel_ extends EpoxyModel<CustomPackageLayoutPatternView> implements GeneratedModel<CustomPackageLayoutPatternView>, CustomPackageLayoutPatternViewModelBuilder {\n  private OnModelBoundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final CustomPackageLayoutPatternView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final CustomPackageLayoutPatternView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final CustomPackageLayoutPatternView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof CustomPackageLayoutPatternViewModel_)) {\n      bind(object);\n      return;\n    }\n    CustomPackageLayoutPatternViewModel_ that = (CustomPackageLayoutPatternViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final CustomPackageLayoutPatternView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CustomPackageLayoutPatternViewModel_ onBind(\n      OnModelBoundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(CustomPackageLayoutPatternView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public CustomPackageLayoutPatternViewModel_ onUnbind(\n      OnModelUnboundListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final CustomPackageLayoutPatternView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CustomPackageLayoutPatternViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final CustomPackageLayoutPatternView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public CustomPackageLayoutPatternViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<CustomPackageLayoutPatternViewModel_, CustomPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.hello_custom_package_layout_pattern_view_me;\n  }\n\n  @Override\n  public CustomPackageLayoutPatternViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof CustomPackageLayoutPatternViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    CustomPackageLayoutPatternViewModel_ that = (CustomPackageLayoutPatternViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"CustomPackageLayoutPatternViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/DataBindingModelWithAllFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.databinding.ViewDataBinding;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DataBindingModelWithAllFieldTypes_ extends DataBindingModelWithAllFieldTypes implements GeneratedModel<DataBindingEpoxyModel.DataBindingHolder>, DataBindingModelWithAllFieldTypesBuilder {\n  private OnModelBoundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public DataBindingModelWithAllFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DataBindingEpoxyModel.DataBindingHolder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final DataBindingEpoxyModel.DataBindingHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypes_ onBind(\n      OnModelBoundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DataBindingEpoxyModel.DataBindingHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DataBindingModelWithAllFieldTypes_ onUnbind(\n      OnModelUnboundListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DataBindingEpoxyModel.DataBindingHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DataBindingModelWithAllFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DataBindingModelWithAllFieldTypes_, DataBindingEpoxyModel.DataBindingHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.valueInteger = valueInteger;\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return valueInteger;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.valueShort = valueShort;\n    return this;\n  }\n\n  public short valueShort() {\n    return valueShort;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.valueShortWrapper = valueShortWrapper;\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.valueChar = valueChar;\n    return this;\n  }\n\n  public char valueChar() {\n    return valueChar;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.valueCharacter = valueCharacter;\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return valueCharacter;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.valuebByte = valuebByte;\n    return this;\n  }\n\n  public byte valuebByte() {\n    return valuebByte;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.valueByteWrapper = valueByteWrapper;\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.valueLong = valueLong;\n    return this;\n  }\n\n  public long valueLong() {\n    return valueLong;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.valueLongWrapper = valueLongWrapper;\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.valueDouble = valueDouble;\n    return this;\n  }\n\n  public double valueDouble() {\n    return valueDouble;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.valueDoubleWrapper = valueDoubleWrapper;\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.valueFloat = valueFloat;\n    return this;\n  }\n\n  public float valueFloat() {\n    return valueFloat;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.valueFloatWrapper = valueFloatWrapper;\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.valueBoolean = valueBoolean;\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return valueBoolean;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.valueBooleanWrapper = valueBooleanWrapper;\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.valueIntArray = valueIntArray;\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return valueIntArray;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.valueObjectArray = valueObjectArray;\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.valueString = valueString;\n    return this;\n  }\n\n  public String valueString() {\n    return valueString;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.valueObject = valueObject;\n    return this;\n  }\n\n  public Object valueObject() {\n    return valueObject;\n  }\n\n  public DataBindingModelWithAllFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.valueList = valueList;\n    return this;\n  }\n\n  public List<String> valueList() {\n    return valueList;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding) {\n    if (!binding.setVariable(BR.valueInt, valueInt)) {\n      throw new IllegalStateException(\"The attribute valueInt was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueInteger, valueInteger)) {\n      throw new IllegalStateException(\"The attribute valueInteger was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueShort, valueShort)) {\n      throw new IllegalStateException(\"The attribute valueShort was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueShortWrapper, valueShortWrapper)) {\n      throw new IllegalStateException(\"The attribute valueShortWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueChar, valueChar)) {\n      throw new IllegalStateException(\"The attribute valueChar was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueCharacter, valueCharacter)) {\n      throw new IllegalStateException(\"The attribute valueCharacter was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valuebByte, valuebByte)) {\n      throw new IllegalStateException(\"The attribute valuebByte was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueByteWrapper, valueByteWrapper)) {\n      throw new IllegalStateException(\"The attribute valueByteWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueLong, valueLong)) {\n      throw new IllegalStateException(\"The attribute valueLong was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueLongWrapper, valueLongWrapper)) {\n      throw new IllegalStateException(\"The attribute valueLongWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueDouble, valueDouble)) {\n      throw new IllegalStateException(\"The attribute valueDouble was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper)) {\n      throw new IllegalStateException(\"The attribute valueDoubleWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueFloat, valueFloat)) {\n      throw new IllegalStateException(\"The attribute valueFloat was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper)) {\n      throw new IllegalStateException(\"The attribute valueFloatWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueBoolean, valueBoolean)) {\n      throw new IllegalStateException(\"The attribute valueBoolean was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper)) {\n      throw new IllegalStateException(\"The attribute valueBooleanWrapper was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueIntArray, valueIntArray)) {\n      throw new IllegalStateException(\"The attribute valueIntArray was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueObjectArray, valueObjectArray)) {\n      throw new IllegalStateException(\"The attribute valueObjectArray was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueString, valueString)) {\n      throw new IllegalStateException(\"The attribute valueString was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueObject, valueObject)) {\n      throw new IllegalStateException(\"The attribute valueObject was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n    if (!binding.setVariable(BR.valueList, valueList)) {\n      throw new IllegalStateException(\"The attribute valueList was defined in your data binding model (com.airbnb.epoxy.DataBindingModelWithAllFieldTypes) but a data variable of that name was not found in the layout.\");\n    }\n  }\n\n  @Override\n  protected void setDataBindingVariables(ViewDataBinding binding, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DataBindingModelWithAllFieldTypes_)) {\n      setDataBindingVariables(binding);\n      return;\n    }\n    DataBindingModelWithAllFieldTypes_ that = (DataBindingModelWithAllFieldTypes_) previousModel;\n    if ((valueInt != that.valueInt)) {\n      binding.setVariable(BR.valueInt, valueInt);\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      binding.setVariable(BR.valueInteger, valueInteger);\n    }\n    if ((valueShort != that.valueShort)) {\n      binding.setVariable(BR.valueShort, valueShort);\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      binding.setVariable(BR.valueShortWrapper, valueShortWrapper);\n    }\n    if ((valueChar != that.valueChar)) {\n      binding.setVariable(BR.valueChar, valueChar);\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      binding.setVariable(BR.valueCharacter, valueCharacter);\n    }\n    if ((valuebByte != that.valuebByte)) {\n      binding.setVariable(BR.valuebByte, valuebByte);\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      binding.setVariable(BR.valueByteWrapper, valueByteWrapper);\n    }\n    if ((valueLong != that.valueLong)) {\n      binding.setVariable(BR.valueLong, valueLong);\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      binding.setVariable(BR.valueLongWrapper, valueLongWrapper);\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      binding.setVariable(BR.valueDouble, valueDouble);\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      binding.setVariable(BR.valueDoubleWrapper, valueDoubleWrapper);\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      binding.setVariable(BR.valueFloat, valueFloat);\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      binding.setVariable(BR.valueFloatWrapper, valueFloatWrapper);\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      binding.setVariable(BR.valueBoolean, valueBoolean);\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      binding.setVariable(BR.valueBooleanWrapper, valueBooleanWrapper);\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      binding.setVariable(BR.valueIntArray, valueIntArray);\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      binding.setVariable(BR.valueObjectArray, valueObjectArray);\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      binding.setVariable(BR.valueString, valueString);\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      binding.setVariable(BR.valueObject, valueObject);\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      binding.setVariable(BR.valueList, valueList);\n    }\n  }\n\n  @Override\n  public DataBindingModelWithAllFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.valueInteger = null;\n    super.valueShort = (short) 0;\n    super.valueShortWrapper = null;\n    super.valueChar = (char) 0;\n    super.valueCharacter = null;\n    super.valuebByte = (byte) 0;\n    super.valueByteWrapper = null;\n    super.valueLong = 0L;\n    super.valueLongWrapper = null;\n    super.valueDouble = 0.0d;\n    super.valueDoubleWrapper = null;\n    super.valueFloat = 0.0f;\n    super.valueFloatWrapper = null;\n    super.valueBoolean = false;\n    super.valueBooleanWrapper = null;\n    super.valueIntArray = null;\n    super.valueObjectArray = null;\n    super.valueString = null;\n    super.valueObject = null;\n    super.valueList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DataBindingModelWithAllFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DataBindingModelWithAllFieldTypes_ that = (DataBindingModelWithAllFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      return false;\n    }\n    if ((valueShort != that.valueShort)) {\n      return false;\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      return false;\n    }\n    if ((valueChar != that.valueChar)) {\n      return false;\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      return false;\n    }\n    if ((valuebByte != that.valuebByte)) {\n      return false;\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      return false;\n    }\n    if ((valueLong != that.valueLong)) {\n      return false;\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      return false;\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      return false;\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      return false;\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      return false;\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      return false;\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      return false;\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      return false;\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      return false;\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      return false;\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      return false;\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      return false;\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + (valueInteger != null ? valueInteger.hashCode() : 0);\n    _result = 31 * _result + valueShort;\n    _result = 31 * _result + (valueShortWrapper != null ? valueShortWrapper.hashCode() : 0);\n    _result = 31 * _result + valueChar;\n    _result = 31 * _result + (valueCharacter != null ? valueCharacter.hashCode() : 0);\n    _result = 31 * _result + valuebByte;\n    _result = 31 * _result + (valueByteWrapper != null ? valueByteWrapper.hashCode() : 0);\n    _result = 31 * _result + (int) (valueLong ^ (valueLong >>> 32));\n    _result = 31 * _result + (valueLongWrapper != null ? valueLongWrapper.hashCode() : 0);\n    temp = Double.doubleToLongBits(valueDouble);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (valueDoubleWrapper != null ? valueDoubleWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueFloat != +0.0f ? Float.floatToIntBits(valueFloat) : 0);\n    _result = 31 * _result + (valueFloatWrapper != null ? valueFloatWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueBoolean ? 1 : 0);\n    _result = 31 * _result + (valueBooleanWrapper != null ? valueBooleanWrapper.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(valueIntArray);\n    _result = 31 * _result + Arrays.hashCode(valueObjectArray);\n    _result = 31 * _result + (valueString != null ? valueString.hashCode() : 0);\n    _result = 31 * _result + (valueObject != null ? valueObject.hashCode() : 0);\n    _result = 31 * _result + (valueList != null ? valueList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DataBindingModelWithAllFieldTypes_{\" +\n        \"valueInt=\" + valueInt +\n        \", valueInteger=\" + valueInteger +\n        \", valueShort=\" + valueShort +\n        \", valueShortWrapper=\" + valueShortWrapper +\n        \", valueChar=\" + valueChar +\n        \", valueCharacter=\" + valueCharacter +\n        \", valuebByte=\" + valuebByte +\n        \", valueByteWrapper=\" + valueByteWrapper +\n        \", valueLong=\" + valueLong +\n        \", valueLongWrapper=\" + valueLongWrapper +\n        \", valueDouble=\" + valueDouble +\n        \", valueDoubleWrapper=\" + valueDoubleWrapper +\n        \", valueFloat=\" + valueFloat +\n        \", valueFloatWrapper=\" + valueFloatWrapper +\n        \", valueBoolean=\" + valueBoolean +\n        \", valueBooleanWrapper=\" + valueBooleanWrapper +\n        \", valueIntArray=\" + valueIntArray +\n        \", valueObjectArray=\" + valueObjectArray +\n        \", valueString=\" + valueString +\n        \", valueObject=\" + valueObject +\n        \", valueList=\" + valueList +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/DefaultPackageLayoutPatternViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DefaultPackageLayoutPatternViewModel_ extends EpoxyModel<DefaultPackageLayoutPatternView> implements GeneratedModel<DefaultPackageLayoutPatternView>, DefaultPackageLayoutPatternViewModelBuilder {\n  private OnModelBoundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final DefaultPackageLayoutPatternView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final DefaultPackageLayoutPatternView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final DefaultPackageLayoutPatternView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DefaultPackageLayoutPatternViewModel_)) {\n      bind(object);\n      return;\n    }\n    DefaultPackageLayoutPatternViewModel_ that = (DefaultPackageLayoutPatternViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final DefaultPackageLayoutPatternView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DefaultPackageLayoutPatternViewModel_ onBind(\n      OnModelBoundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DefaultPackageLayoutPatternView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DefaultPackageLayoutPatternViewModel_ onUnbind(\n      OnModelUnboundListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final DefaultPackageLayoutPatternView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DefaultPackageLayoutPatternViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DefaultPackageLayoutPatternView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DefaultPackageLayoutPatternViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DefaultPackageLayoutPatternViewModel_, DefaultPackageLayoutPatternView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.default_package_layout_pattern_view;\n  }\n\n  @Override\n  public DefaultPackageLayoutPatternViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DefaultPackageLayoutPatternViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DefaultPackageLayoutPatternViewModel_ that = (DefaultPackageLayoutPatternViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DefaultPackageLayoutPatternViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/DoNotHashViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class DoNotHashViewModel_ extends EpoxyModel<DoNotHashView> implements GeneratedModel<DoNotHashView>, DoNotHashViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(3);\n\n  private OnModelBoundListener<DoNotHashViewModel_, DoNotHashView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<DoNotHashViewModel_, DoNotHashView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<DoNotHashViewModel_, DoNotHashView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<DoNotHashViewModel_, DoNotHashView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence normalProp_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for normalProp\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final DoNotHashView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final DoNotHashView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setTitle(title_CharSequence);\n    object.normalProp(normalProp_CharSequence);\n  }\n\n  @Override\n  public void bind(final DoNotHashView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof DoNotHashViewModel_)) {\n      bind(object);\n      return;\n    }\n    DoNotHashViewModel_ that = (DoNotHashViewModel_) previousModel;\n    super.bind(object);\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if (((title_CharSequence == null) != (that.title_CharSequence == null))) {\n      object.setTitle(title_CharSequence);\n    }\n\n    if ((normalProp_CharSequence != null ? !normalProp_CharSequence.equals(that.normalProp_CharSequence) : that.normalProp_CharSequence != null)) {\n      object.normalProp(normalProp_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final DoNotHashView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DoNotHashViewModel_ onBind(\n      OnModelBoundListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(DoNotHashView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public DoNotHashViewModel_ onUnbind(\n      OnModelUnboundListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final DoNotHashView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DoNotHashViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final DoNotHashView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public DoNotHashViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<DoNotHashViewModel_, DoNotHashView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#setTitle(CharSequence)\n   */\n  public DoNotHashViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public DoNotHashViewModel_ clickListener(\n      @NonNull final OnModelClickListener<DoNotHashViewModel_, DoNotHashView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#setClickListener(View.OnClickListener)\n   */\n  public DoNotHashViewModel_ clickListener(@NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see DoNotHashView#normalProp(CharSequence)\n   */\n  public DoNotHashViewModel_ normalProp(@NonNull CharSequence normalProp) {\n    if (normalProp == null) {\n      throw new IllegalArgumentException(\"normalProp cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.normalProp_CharSequence = normalProp;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence normalProp() {\n    return normalProp_CharSequence;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public DoNotHashViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public DoNotHashViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    this.clickListener_OnClickListener = null;\n    this.normalProp_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof DoNotHashViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    DoNotHashViewModel_ that = (DoNotHashViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((title_CharSequence == null) != (that.title_CharSequence == null))) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((normalProp_CharSequence != null ? !normalProp_CharSequence.equals(that.normalProp_CharSequence) : that.normalProp_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (normalProp_CharSequence != null ? normalProp_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"DoNotHashViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", normalProp_CharSequence=\" + normalProp_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/EpoxyModelGroupWithAnnotations_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.Collection;\n\n/**\n * Generated file. Do not modify!\n */\npublic class EpoxyModelGroupWithAnnotations_ extends EpoxyModelGroupWithAnnotations implements GeneratedModel<ModelGroupHolder>, EpoxyModelGroupWithAnnotationsBuilder {\n  private OnModelBoundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public EpoxyModelGroupWithAnnotations_(int layoutRes,\n      Collection<? extends EpoxyModel<?>> models) {\n    super(layoutRes, models);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelGroupHolder object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final ModelGroupHolder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public EpoxyModelGroupWithAnnotations_ onBind(\n      OnModelBoundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelGroupHolder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public EpoxyModelGroupWithAnnotations_ onUnbind(\n      OnModelUnboundListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelGroupHolder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public EpoxyModelGroupWithAnnotations_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelGroupHolder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public EpoxyModelGroupWithAnnotations_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<EpoxyModelGroupWithAnnotations_, ModelGroupHolder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public EpoxyModelGroupWithAnnotations_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ shouldSaveViewState(boolean p0) {\n    super.shouldSaveViewState(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public EpoxyModelGroupWithAnnotations_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof EpoxyModelGroupWithAnnotations_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    EpoxyModelGroupWithAnnotations_ that = (EpoxyModelGroupWithAnnotations_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"EpoxyModelGroupWithAnnotations_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethodNextParentLayout$NoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.NoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_NoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$NoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$NoLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$NoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$NoLayout_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.StillNoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_StillNoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$StillNoLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethodNextParentLayout$WithLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ extends GenerateDefaultLayoutMethodNextParentLayout.WithLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodNextParentLayout_WithLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodNextParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodNextParentLayout$WithLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodNextParentLayout$WithLayout_ that = (GenerateDefaultLayoutMethodNextParentLayout$WithLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodNextParentLayout$WithLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethodParentLayout$NoLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodParentLayout$NoLayout_ extends GenerateDefaultLayoutMethodParentLayout.NoLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodParentLayout_NoLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$NoLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$NoLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodParentLayout$NoLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodParentLayout$NoLayout_ that = (GenerateDefaultLayoutMethodParentLayout$NoLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodParentLayout$NoLayout_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethodParentLayout$WithLayout_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethodParentLayout$WithLayout_ extends GenerateDefaultLayoutMethodParentLayout.WithLayout implements GeneratedModel<Object>, GenerateDefaultLayoutMethodParentLayout_WithLayoutBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethodParentLayout$WithLayout_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethodParentLayout$WithLayout_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethodParentLayout$WithLayout_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethodParentLayout$WithLayout_ that = (GenerateDefaultLayoutMethodParentLayout$WithLayout_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethodParentLayout$WithLayout_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GenerateDefaultLayoutMethod_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GenerateDefaultLayoutMethod_ extends GenerateDefaultLayoutMethod implements GeneratedModel<Object>, GenerateDefaultLayoutMethodBuilder {\n  private OnModelBoundListener<GenerateDefaultLayoutMethod_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GenerateDefaultLayoutMethod_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethod_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GenerateDefaultLayoutMethod_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public GenerateDefaultLayoutMethod_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethod_ onBind(\n      OnModelBoundListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GenerateDefaultLayoutMethod_ onUnbind(\n      OnModelUnboundListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethod_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GenerateDefaultLayoutMethod_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GenerateDefaultLayoutMethod_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public GenerateDefaultLayoutMethod_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GenerateDefaultLayoutMethod_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GenerateDefaultLayoutMethod_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GenerateDefaultLayoutMethod_ that = (GenerateDefaultLayoutMethod_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GenerateDefaultLayoutMethod_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GeneratedModelSuffixViewSuffix_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GeneratedModelSuffixViewSuffix_ extends EpoxyModel<GeneratedModelSuffixView> implements GeneratedModel<GeneratedModelSuffixView>, GeneratedModelSuffixViewSuffixBuilder {\n  private OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final GeneratedModelSuffixView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GeneratedModelSuffixView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final GeneratedModelSuffixView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof GeneratedModelSuffixViewSuffix_)) {\n      bind(object);\n      return;\n    }\n    GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final GeneratedModelSuffixView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GeneratedModelSuffixViewSuffix_ onBind(\n      OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GeneratedModelSuffixView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GeneratedModelSuffixViewSuffix_ onUnbind(\n      OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final GeneratedModelSuffixView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GeneratedModelSuffixViewSuffix_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final GeneratedModelSuffixView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GeneratedModelSuffixViewSuffix_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.generated_model_suffix_view;\n  }\n\n  @Override\n  public GeneratedModelSuffixViewSuffix_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GeneratedModelSuffixViewSuffix_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GeneratedModelSuffixViewSuffix_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/GridSpanCountViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class GridSpanCountViewModel_ extends EpoxyModel<GridSpanCountView> implements GeneratedModel<GridSpanCountView>, GridSpanCountViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<GridSpanCountViewModel_, GridSpanCountView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<GridSpanCountViewModel_, GridSpanCountView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<GridSpanCountViewModel_, GridSpanCountView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<GridSpanCountViewModel_, GridSpanCountView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final GridSpanCountView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final GridSpanCountView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final GridSpanCountView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof GridSpanCountViewModel_)) {\n      bind(object);\n      return;\n    }\n    GridSpanCountViewModel_ that = (GridSpanCountViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final GridSpanCountView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GridSpanCountViewModel_ onBind(\n      OnModelBoundListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(GridSpanCountView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public GridSpanCountViewModel_ onUnbind(\n      OnModelUnboundListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final GridSpanCountView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GridSpanCountViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final GridSpanCountView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public GridSpanCountViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<GridSpanCountViewModel_, GridSpanCountView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see GridSpanCountView#setClickListener(String)\n   */\n  public GridSpanCountViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public GridSpanCountViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof GridSpanCountViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    GridSpanCountViewModel_ that = (GridSpanCountViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"GridSpanCountViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/IgnoreRequireHashCodeViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class IgnoreRequireHashCodeViewModel_ extends EpoxyModel<IgnoreRequireHashCodeView> implements GeneratedModel<IgnoreRequireHashCodeView>, IgnoreRequireHashCodeViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final IgnoreRequireHashCodeView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final IgnoreRequireHashCodeView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final IgnoreRequireHashCodeView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof IgnoreRequireHashCodeViewModel_)) {\n      bind(object);\n      return;\n    }\n    IgnoreRequireHashCodeViewModel_ that = (IgnoreRequireHashCodeViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_OnClickListener != null ? !clickListener_OnClickListener.equals(that.clickListener_OnClickListener) : that.clickListener_OnClickListener != null)) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final IgnoreRequireHashCodeView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public IgnoreRequireHashCodeViewModel_ onBind(\n      OnModelBoundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(IgnoreRequireHashCodeView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public IgnoreRequireHashCodeViewModel_ onUnbind(\n      OnModelUnboundListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final IgnoreRequireHashCodeView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public IgnoreRequireHashCodeViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final IgnoreRequireHashCodeView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public IgnoreRequireHashCodeViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public IgnoreRequireHashCodeViewModel_ clickListener(\n      @NonNull final OnModelClickListener<IgnoreRequireHashCodeViewModel_, IgnoreRequireHashCodeView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see IgnoreRequireHashCodeView#setClickListener(View.OnClickListener)\n   */\n  public IgnoreRequireHashCodeViewModel_ clickListener(\n      @NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public IgnoreRequireHashCodeViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof IgnoreRequireHashCodeViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    IgnoreRequireHashCodeViewModel_ that = (IgnoreRequireHashCodeViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_OnClickListener != null ? !clickListener_OnClickListener.equals(that.clickListener_OnClickListener) : that.clickListener_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? clickListener_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"IgnoreRequireHashCodeViewModel_{\" +\n        \"clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/LayoutOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class LayoutOverloadsViewModel_ extends EpoxyModel<LayoutOverloadsView> implements GeneratedModel<LayoutOverloadsView>, LayoutOverloadsViewModelBuilder {\n  private OnModelBoundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final LayoutOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final LayoutOverloadsView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final LayoutOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof LayoutOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    LayoutOverloadsViewModel_ that = (LayoutOverloadsViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final LayoutOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public LayoutOverloadsViewModel_ onBind(\n      OnModelBoundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(LayoutOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public LayoutOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final LayoutOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public LayoutOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final LayoutOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public LayoutOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<LayoutOverloadsViewModel_, LayoutOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.layout_overloads_view;\n  }\n\n  public LayoutOverloadsViewModel_ withOneLayout() {\n    layout(R.layout.layout_overloads_view_one);\n    return this;\n  }\n\n  public LayoutOverloadsViewModel_ withTwoLayout() {\n    layout(R.layout.layout_overloads_view_two);\n    return this;\n  }\n\n  @Override\n  public LayoutOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof LayoutOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    LayoutOverloadsViewModel_ that = (LayoutOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"LayoutOverloadsViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelDoNotHash_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelDoNotHash_ extends ModelDoNotHash implements GeneratedModel<Object>, ModelDoNotHashBuilder {\n  private OnModelBoundListener<ModelDoNotHash_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelDoNotHash_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelDoNotHash_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelDoNotHash_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelDoNotHash_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotHash_ onBind(OnModelBoundListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotHash_ onUnbind(OnModelUnboundListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotHash_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotHash_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelDoNotHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelDoNotHash_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelDoNotHash_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelDoNotHash_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotHash_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelDoNotHash_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelDoNotHash_ that = (ModelDoNotHash_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if (((value3 == null) != (that.value3 == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + (value3 != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelDoNotHash_{\" +\n        \"value=\" + value +\n        \", value2=\" + value2 +\n        \", value3=\" + value3 +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelDoNotUseInToString_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelDoNotUseInToString_ extends ModelDoNotUseInToString implements GeneratedModel<Object>, ModelDoNotUseInToStringBuilder {\n  private OnModelBoundListener<ModelDoNotUseInToString_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelDoNotUseInToString_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelDoNotUseInToString_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelDoNotUseInToString_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelDoNotUseInToString_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotUseInToString_ onBind(\n      OnModelBoundListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelDoNotUseInToString_ onUnbind(\n      OnModelUnboundListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotUseInToString_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelDoNotUseInToString_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelDoNotUseInToString_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelDoNotUseInToString_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelDoNotUseInToString_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelDoNotUseInToString_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelDoNotUseInToString_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelDoNotUseInToString_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelDoNotUseInToString_ that = (ModelDoNotUseInToString_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if ((value2 != that.value2)) {\n      return false;\n    }\n    if ((value3 != null ? !value3.equals(that.value3) : that.value3 != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + value2;\n    _result = 31 * _result + (value3 != null ? value3.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelDoNotUseInToString_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelForRProcessingTest_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelForRProcessingTest_ extends ModelForRProcessingTest implements GeneratedModel<Object>, ModelForRProcessingTestBuilder {\n  private OnModelBoundListener<ModelForRProcessingTest_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelForRProcessingTest_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelForRProcessingTest_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelForRProcessingTest_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelForRProcessingTest_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForRProcessingTest_ onBind(\n      OnModelBoundListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelForRProcessingTest_ onUnbind(\n      OnModelUnboundListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForRProcessingTest_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelForRProcessingTest_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelForRProcessingTest_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelForRProcessingTest_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.res;\n  }\n\n  @Override\n  public ModelForRProcessingTest_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelForRProcessingTest_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelForRProcessingTest_ that = (ModelForRProcessingTest_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelForRProcessingTest_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelReturningClassTypeWithVarargs_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelReturningClassTypeWithVarargs_ extends ModelReturningClassTypeWithVarargs implements GeneratedModel<Object>, ModelReturningClassTypeWithVarargsBuilder {\n  private OnModelBoundListener<ModelReturningClassTypeWithVarargs_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelReturningClassTypeWithVarargs_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelReturningClassTypeWithVarargs_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelReturningClassTypeWithVarargs_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelReturningClassTypeWithVarargs_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassTypeWithVarargs_ onBind(\n      OnModelBoundListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassTypeWithVarargs_ onUnbind(\n      OnModelUnboundListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassTypeWithVarargs_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassTypeWithVarargs_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelReturningClassTypeWithVarargs_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelReturningClassTypeWithVarargs_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ classType(String... varargs) {\n    super.classType(varargs);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ classType(String first, String... varargs) {\n    super.classType(first, varargs);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassTypeWithVarargs_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelReturningClassTypeWithVarargs_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelReturningClassTypeWithVarargs_ that = (ModelReturningClassTypeWithVarargs_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelReturningClassTypeWithVarargs_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelReturningClassType_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelReturningClassType_ extends ModelReturningClassType implements GeneratedModel<Object>, ModelReturningClassTypeBuilder {\n  private OnModelBoundListener<ModelReturningClassType_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelReturningClassType_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelReturningClassType_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelReturningClassType_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelReturningClassType_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassType_ onBind(\n      OnModelBoundListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelReturningClassType_ onUnbind(\n      OnModelUnboundListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassType_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelReturningClassType_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelReturningClassType_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelReturningClassType_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelReturningClassType_ classType(int classType) {\n    super.classType(classType);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ classType(int param1, int param2) {\n    super.classType(param1, param2);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ list(List<String> list) {\n    super.list(list);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelReturningClassType_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelReturningClassType_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelReturningClassType_ that = (ModelReturningClassType_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelReturningClassType_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelViewExtendingSuperClassModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewExtendingSuperClassModel_ extends EpoxyModel<ModelViewExtendingSuperClass> implements GeneratedModel<ModelViewExtendingSuperClass>, ModelViewExtendingSuperClassModelBuilder {\n  private OnModelBoundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int subClassValue_Int = 0;\n\n  private int superClassValue_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClass buildView(ViewGroup parent) {\n    ModelViewExtendingSuperClass v = new ModelViewExtendingSuperClass(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewExtendingSuperClass object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelViewExtendingSuperClass object) {\n    super.bind(object);\n    object.subClassValue(subClassValue_Int);\n    object.superClassValue(superClassValue_Int);\n  }\n\n  @Override\n  public void bind(final ModelViewExtendingSuperClass object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewExtendingSuperClassModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewExtendingSuperClassModel_ that = (ModelViewExtendingSuperClassModel_) previousModel;\n    super.bind(object);\n\n    if ((subClassValue_Int != that.subClassValue_Int)) {\n      object.subClassValue(subClassValue_Int);\n    }\n\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      object.superClassValue(superClassValue_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewExtendingSuperClass object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterProps();\n    object.onSubclassAfterPropsSet();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewExtendingSuperClassModel_ onBind(\n      OnModelBoundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewExtendingSuperClass object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onClear();\n    object.onSubClassCleared();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewExtendingSuperClassModel_ onUnbind(\n      OnModelUnboundListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final ModelViewExtendingSuperClass object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewExtendingSuperClassModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewExtendingSuperClass object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewExtendingSuperClassModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewExtendingSuperClassModel_, ModelViewExtendingSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewExtendingSuperClass#subClassValue(int)\n   */\n  public ModelViewExtendingSuperClassModel_ subClassValue(int subClassValue) {\n    onMutation();\n    this.subClassValue_Int = subClassValue;\n    return this;\n  }\n\n  public int subClassValue() {\n    return subClassValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewExtendingSuperClass#superClassValue(int)\n   */\n  public ModelViewExtendingSuperClassModel_ superClassValue(int superClassValue) {\n    onMutation();\n    this.superClassValue_Int = superClassValue;\n    return this;\n  }\n\n  public int superClassValue() {\n    return superClassValue_Int;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewExtendingSuperClassModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.subClassValue_Int = 0;\n    this.superClassValue_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewExtendingSuperClassModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewExtendingSuperClassModel_ that = (ModelViewExtendingSuperClassModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((subClassValue_Int != that.subClassValue_Int)) {\n      return false;\n    }\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + subClassValue_Int;\n    _result = 31 * _result + superClassValue_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewExtendingSuperClassModel_{\" +\n        \"subClassValue_Int=\" + subClassValue_Int +\n        \", superClassValue_Int=\" + superClassValue_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelViewSuperClassModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewSuperClassModel_ extends EpoxyModel<ModelViewSuperClass> implements GeneratedModel<ModelViewSuperClass>, ModelViewSuperClassModelBuilder {\n  private OnModelBoundListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int superClassValue_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewSuperClass buildView(ViewGroup parent) {\n    ModelViewSuperClass v = new ModelViewSuperClass(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewSuperClass object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final ModelViewSuperClass object) {\n    super.bind(object);\n    object.superClassValue(superClassValue_Int);\n  }\n\n  @Override\n  public void bind(final ModelViewSuperClass object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewSuperClassModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewSuperClassModel_ that = (ModelViewSuperClassModel_) previousModel;\n    super.bind(object);\n\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      object.superClassValue(superClassValue_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewSuperClass object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterProps();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewSuperClassModel_ onBind(\n      OnModelBoundListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewSuperClass object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onClear();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewSuperClassModel_ onUnbind(\n      OnModelUnboundListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewSuperClass object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewSuperClassModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewSuperClass object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewSuperClassModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewSuperClassModel_, ModelViewSuperClass> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewSuperClass#superClassValue(int)\n   */\n  public ModelViewSuperClassModel_ superClassValue(int superClassValue) {\n    onMutation();\n    this.superClassValue_Int = superClassValue;\n    return this;\n  }\n\n  public int superClassValue() {\n    return superClassValue_Int;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewSuperClassModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.superClassValue_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewSuperClassModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewSuperClassModel_ that = (ModelViewSuperClassModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superClassValue_Int != that.superClassValue_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superClassValue_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewSuperClassModel_{\" +\n        \"superClassValue_Int=\" + superClassValue_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelViewWithParisModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.os.AsyncTask;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport com.airbnb.paris.StyleApplierUtils;\nimport com.airbnb.paris.styles.Style;\nimport com.airbnb.viewmodeladapter.R;\nimport java.lang.AssertionError;\nimport java.lang.CharSequence;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Runnable;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelViewWithParisModel_ extends EpoxyModel<ModelViewWithParis> implements GeneratedModel<ModelViewWithParis>, ModelViewWithParisModelBuilder {\n  private static final Style DEFAULT_PARIS_STYLE = new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n\n  private static WeakReference<Style> parisStyleReference_header;\n\n  private static WeakReference<Style> parisStyleReference_other;\n\n  private static WeakReference<Style> parisStyleReference_default;\n\n  private OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  private Style style = DEFAULT_PARIS_STYLE;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public ModelViewWithParis buildView(ViewGroup parent) {\n    ModelViewWithParis v = new ModelViewWithParis(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final ModelViewWithParis object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {\n        public void run() {\n          try {\n            StyleApplierUtils.Companion.assertSameAttributes(new ModelViewWithParisStyleApplier(object), style, DEFAULT_PARIS_STYLE);\n          }\n          catch(AssertionError e) {\n            throw new IllegalStateException(\"ModelViewWithParisModel_ model at position \" + position + \" has an invalid style:\\n\\n\" + e.getMessage());\n          }\n        }\n      } );\n    }\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object) {\n\n    if (!Objects.equals(style, object.getTag(R.id.epoxy_saved_view_style))) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n    object.value = value_Int;\n  }\n\n  @Override\n  public void bind(final ModelViewWithParis object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof ModelViewWithParisModel_)) {\n      bind(object);\n      return;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) previousModel;\n\n    if (!Objects.equals(style, that.style)) {\n      ModelViewWithParisStyleApplier styleApplier = new ModelViewWithParisStyleApplier(object);\n      styleApplier.apply(style);\n      object.setTag(R.id.epoxy_saved_view_style, style);\n    }\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.value = value_Int;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final ModelViewWithParis object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onBind(\n      OnModelBoundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(ModelViewWithParis object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelViewWithParisModel_ onUnbind(\n      OnModelUnboundListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final ModelViewWithParis object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final ModelViewWithParis object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelViewWithParisModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelViewWithParisModel_, ModelViewWithParis> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ style(Style style) {\n    onMutation();\n    this.style = style;\n    return this;\n  }\n\n  public ModelViewWithParisModel_ styleBuilder(\n      StyleBuilderCallback<ModelViewWithParisStyleApplier.StyleBuilder> builderCallback) {\n    ModelViewWithParisStyleApplier.StyleBuilder builder = new ModelViewWithParisStyleApplier.StyleBuilder();\n    builderCallback.buildStyle(builder.addDefault());\n    return style(builder.build());\n  }\n\n  /**\n   *\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withHeaderStyle() {\n    Style style = parisStyleReference_header != null ? parisStyleReference_header.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addHeader().build();\n      parisStyleReference_header = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *\n   *  @see ModelViewWithParis#otherStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withOtherStyle() {\n    Style style = parisStyleReference_other != null ? parisStyleReference_other.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addOther().build();\n      parisStyleReference_other = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   *\n   *  @see ModelViewWithParis#headerStyle(ModelViewWithParisStyleApplier.StyleBuilder)\n   */\n  public ModelViewWithParisModel_ withDefaultStyle() {\n    Style style = parisStyleReference_default != null ? parisStyleReference_default.get() : null;\n    if (style == null) {\n      style =  new ModelViewWithParisStyleApplier.StyleBuilder().addDefault().build();\n      parisStyleReference_default = new WeakReference<>(style);\n    }\n    return style(style);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see ModelViewWithParis#value\n   */\n  public ModelViewWithParisModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelViewWithParisModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public ModelViewWithParisModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    this.style = DEFAULT_PARIS_STYLE;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelViewWithParisModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelViewWithParisModel_ that = (ModelViewWithParisModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    if ((style != null ? !style.equals(that.style) : that.style != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    _result = 31 * _result + (style != null ? style.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelViewWithParisModel_{\" +\n        \"value_Int=\" + value_Int +\n        \", style=\" + style +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAbstractClassAndAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAbstractClassAndAnnotation_ extends ModelWithAbstractClassAndAnnotation implements GeneratedModel<Object>, ModelWithAbstractClassAndAnnotationBuilder {\n  private OnModelBoundListener<ModelWithAbstractClassAndAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAbstractClassAndAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAbstractClassAndAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAbstractClassAndAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAbstractClassAndAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAbstractClassAndAnnotation_ onBind(\n      OnModelBoundListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAbstractClassAndAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAbstractClassAndAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAbstractClassAndAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAbstractClassAndAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAbstractClassAndAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAbstractClassAndAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAbstractClassAndAnnotation_ that = (ModelWithAbstractClassAndAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAbstractClassAndAnnotation_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAllFieldTypesBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.List;\n\n@EpoxyBuildScope\npublic interface ModelWithAllFieldTypesBuilder {\n  ModelWithAllFieldTypesBuilder onBind(\n      OnModelBoundListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onUnbind(\n      OnModelUnboundListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> listener);\n\n  ModelWithAllFieldTypesBuilder valueInt(int valueInt);\n\n  ModelWithAllFieldTypesBuilder valueInteger(Integer valueInteger);\n\n  ModelWithAllFieldTypesBuilder valueShort(short valueShort);\n\n  ModelWithAllFieldTypesBuilder valueShortWrapper(Short valueShortWrapper);\n\n  ModelWithAllFieldTypesBuilder valueChar(char valueChar);\n\n  ModelWithAllFieldTypesBuilder valueCharacter(Character valueCharacter);\n\n  ModelWithAllFieldTypesBuilder valuebByte(byte valuebByte);\n\n  ModelWithAllFieldTypesBuilder valueByteWrapper(Byte valueByteWrapper);\n\n  ModelWithAllFieldTypesBuilder valueLong(long valueLong);\n\n  ModelWithAllFieldTypesBuilder valueLongWrapper(Long valueLongWrapper);\n\n  ModelWithAllFieldTypesBuilder valueDouble(double valueDouble);\n\n  ModelWithAllFieldTypesBuilder valueDoubleWrapper(Double valueDoubleWrapper);\n\n  ModelWithAllFieldTypesBuilder valueFloat(float valueFloat);\n\n  ModelWithAllFieldTypesBuilder valueFloatWrapper(Float valueFloatWrapper);\n\n  ModelWithAllFieldTypesBuilder valueBoolean(boolean valueBoolean);\n\n  ModelWithAllFieldTypesBuilder valueBooleanWrapper(Boolean valueBooleanWrapper);\n\n  ModelWithAllFieldTypesBuilder valueIntArray(int[] valueIntArray);\n\n  ModelWithAllFieldTypesBuilder valueObjectArray(Object[] valueObjectArray);\n\n  ModelWithAllFieldTypesBuilder valueString(String valueString);\n\n  ModelWithAllFieldTypesBuilder valueObject(Object valueObject);\n\n  ModelWithAllFieldTypesBuilder valueList(List<String> valueList);\n\n  ModelWithAllFieldTypesBuilder id(long p0);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable Number... p0);\n\n  ModelWithAllFieldTypesBuilder id(long p0, long p1);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence p0);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  ModelWithAllFieldTypesBuilder id(@Nullable CharSequence p0, long p1);\n\n  ModelWithAllFieldTypesBuilder layout(@LayoutRes int p0);\n\n  ModelWithAllFieldTypesBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAllFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAllFieldTypes_ extends ModelWithAllFieldTypes implements GeneratedModel<Object>, ModelWithAllFieldTypesBuilder {\n  private OnModelBoundListener<ModelWithAllFieldTypes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAllFieldTypes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAllFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllFieldTypes_ onBind(\n      OnModelBoundListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllFieldTypes_ onUnbind(\n      OnModelUnboundListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAllFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  public ModelWithAllFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.valueInteger = valueInteger;\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return valueInteger;\n  }\n\n  public ModelWithAllFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.valueShort = valueShort;\n    return this;\n  }\n\n  public short valueShort() {\n    return valueShort;\n  }\n\n  public ModelWithAllFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.valueShortWrapper = valueShortWrapper;\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return valueShortWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.valueChar = valueChar;\n    return this;\n  }\n\n  public char valueChar() {\n    return valueChar;\n  }\n\n  public ModelWithAllFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.valueCharacter = valueCharacter;\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return valueCharacter;\n  }\n\n  public ModelWithAllFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.valuebByte = valuebByte;\n    return this;\n  }\n\n  public byte valuebByte() {\n    return valuebByte;\n  }\n\n  public ModelWithAllFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.valueByteWrapper = valueByteWrapper;\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return valueByteWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.valueLong = valueLong;\n    return this;\n  }\n\n  public long valueLong() {\n    return valueLong;\n  }\n\n  public ModelWithAllFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.valueLongWrapper = valueLongWrapper;\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return valueLongWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.valueDouble = valueDouble;\n    return this;\n  }\n\n  public double valueDouble() {\n    return valueDouble;\n  }\n\n  public ModelWithAllFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.valueDoubleWrapper = valueDoubleWrapper;\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return valueDoubleWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.valueFloat = valueFloat;\n    return this;\n  }\n\n  public float valueFloat() {\n    return valueFloat;\n  }\n\n  public ModelWithAllFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.valueFloatWrapper = valueFloatWrapper;\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return valueFloatWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.valueBoolean = valueBoolean;\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return valueBoolean;\n  }\n\n  public ModelWithAllFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.valueBooleanWrapper = valueBooleanWrapper;\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return valueBooleanWrapper;\n  }\n\n  public ModelWithAllFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.valueIntArray = valueIntArray;\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return valueIntArray;\n  }\n\n  public ModelWithAllFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.valueObjectArray = valueObjectArray;\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return valueObjectArray;\n  }\n\n  public ModelWithAllFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.valueString = valueString;\n    return this;\n  }\n\n  public String valueString() {\n    return valueString;\n  }\n\n  public ModelWithAllFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.valueObject = valueObject;\n    return this;\n  }\n\n  public Object valueObject() {\n    return valueObject;\n  }\n\n  public ModelWithAllFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.valueList = valueList;\n    return this;\n  }\n\n  public List<String> valueList() {\n    return valueList;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.valueInteger = null;\n    super.valueShort = (short) 0;\n    super.valueShortWrapper = null;\n    super.valueChar = (char) 0;\n    super.valueCharacter = null;\n    super.valuebByte = (byte) 0;\n    super.valueByteWrapper = null;\n    super.valueLong = 0L;\n    super.valueLongWrapper = null;\n    super.valueDouble = 0.0d;\n    super.valueDoubleWrapper = null;\n    super.valueFloat = 0.0f;\n    super.valueFloatWrapper = null;\n    super.valueBoolean = false;\n    super.valueBooleanWrapper = null;\n    super.valueIntArray = null;\n    super.valueObjectArray = null;\n    super.valueString = null;\n    super.valueObject = null;\n    super.valueList = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAllFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAllFieldTypes_ that = (ModelWithAllFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    if ((valueInteger != null ? !valueInteger.equals(that.valueInteger) : that.valueInteger != null)) {\n      return false;\n    }\n    if ((valueShort != that.valueShort)) {\n      return false;\n    }\n    if ((valueShortWrapper != null ? !valueShortWrapper.equals(that.valueShortWrapper) : that.valueShortWrapper != null)) {\n      return false;\n    }\n    if ((valueChar != that.valueChar)) {\n      return false;\n    }\n    if ((valueCharacter != null ? !valueCharacter.equals(that.valueCharacter) : that.valueCharacter != null)) {\n      return false;\n    }\n    if ((valuebByte != that.valuebByte)) {\n      return false;\n    }\n    if ((valueByteWrapper != null ? !valueByteWrapper.equals(that.valueByteWrapper) : that.valueByteWrapper != null)) {\n      return false;\n    }\n    if ((valueLong != that.valueLong)) {\n      return false;\n    }\n    if ((valueLongWrapper != null ? !valueLongWrapper.equals(that.valueLongWrapper) : that.valueLongWrapper != null)) {\n      return false;\n    }\n    if ((Double.compare(that.valueDouble, valueDouble) != 0)) {\n      return false;\n    }\n    if ((valueDoubleWrapper != null ? !valueDoubleWrapper.equals(that.valueDoubleWrapper) : that.valueDoubleWrapper != null)) {\n      return false;\n    }\n    if ((Float.compare(that.valueFloat, valueFloat) != 0)) {\n      return false;\n    }\n    if ((valueFloatWrapper != null ? !valueFloatWrapper.equals(that.valueFloatWrapper) : that.valueFloatWrapper != null)) {\n      return false;\n    }\n    if ((valueBoolean != that.valueBoolean)) {\n      return false;\n    }\n    if ((valueBooleanWrapper != null ? !valueBooleanWrapper.equals(that.valueBooleanWrapper) : that.valueBooleanWrapper != null)) {\n      return false;\n    }\n    if (!Arrays.equals(valueIntArray, that.valueIntArray)) {\n      return false;\n    }\n    if (!Arrays.equals(valueObjectArray, that.valueObjectArray)) {\n      return false;\n    }\n    if ((valueString != null ? !valueString.equals(that.valueString) : that.valueString != null)) {\n      return false;\n    }\n    if ((valueObject != null ? !valueObject.equals(that.valueObject) : that.valueObject != null)) {\n      return false;\n    }\n    if ((valueList != null ? !valueList.equals(that.valueList) : that.valueList != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + valueInt;\n    _result = 31 * _result + (valueInteger != null ? valueInteger.hashCode() : 0);\n    _result = 31 * _result + valueShort;\n    _result = 31 * _result + (valueShortWrapper != null ? valueShortWrapper.hashCode() : 0);\n    _result = 31 * _result + valueChar;\n    _result = 31 * _result + (valueCharacter != null ? valueCharacter.hashCode() : 0);\n    _result = 31 * _result + valuebByte;\n    _result = 31 * _result + (valueByteWrapper != null ? valueByteWrapper.hashCode() : 0);\n    _result = 31 * _result + (int) (valueLong ^ (valueLong >>> 32));\n    _result = 31 * _result + (valueLongWrapper != null ? valueLongWrapper.hashCode() : 0);\n    temp = Double.doubleToLongBits(valueDouble);\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (valueDoubleWrapper != null ? valueDoubleWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueFloat != +0.0f ? Float.floatToIntBits(valueFloat) : 0);\n    _result = 31 * _result + (valueFloatWrapper != null ? valueFloatWrapper.hashCode() : 0);\n    _result = 31 * _result + (valueBoolean ? 1 : 0);\n    _result = 31 * _result + (valueBooleanWrapper != null ? valueBooleanWrapper.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(valueIntArray);\n    _result = 31 * _result + Arrays.hashCode(valueObjectArray);\n    _result = 31 * _result + (valueString != null ? valueString.hashCode() : 0);\n    _result = 31 * _result + (valueObject != null ? valueObject.hashCode() : 0);\n    _result = 31 * _result + (valueList != null ? valueList.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAllFieldTypes_{\" +\n        \"valueInt=\" + valueInt +\n        \", valueInteger=\" + valueInteger +\n        \", valueShort=\" + valueShort +\n        \", valueShortWrapper=\" + valueShortWrapper +\n        \", valueChar=\" + valueChar +\n        \", valueCharacter=\" + valueCharacter +\n        \", valuebByte=\" + valuebByte +\n        \", valueByteWrapper=\" + valueByteWrapper +\n        \", valueLong=\" + valueLong +\n        \", valueLongWrapper=\" + valueLongWrapper +\n        \", valueDouble=\" + valueDouble +\n        \", valueDoubleWrapper=\" + valueDoubleWrapper +\n        \", valueFloat=\" + valueFloat +\n        \", valueFloatWrapper=\" + valueFloatWrapper +\n        \", valueBoolean=\" + valueBoolean +\n        \", valueBooleanWrapper=\" + valueBooleanWrapper +\n        \", valueIntArray=\" + valueIntArray +\n        \", valueObjectArray=\" + valueObjectArray +\n        \", valueString=\" + valueString +\n        \", valueObject=\" + valueObject +\n        \", valueList=\" + valueList +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAllPrivateFieldTypes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.Boolean;\nimport java.lang.Byte;\nimport java.lang.CharSequence;\nimport java.lang.Character;\nimport java.lang.Double;\nimport java.lang.Float;\nimport java.lang.Integer;\nimport java.lang.Long;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.Short;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAllPrivateFieldTypes_ extends ModelWithAllPrivateFieldTypes implements GeneratedModel<Object>, ModelWithAllPrivateFieldTypesBuilder {\n  private OnModelBoundListener<ModelWithAllPrivateFieldTypes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAllPrivateFieldTypes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAllPrivateFieldTypes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAllPrivateFieldTypes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAllPrivateFieldTypes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllPrivateFieldTypes_ onBind(\n      OnModelBoundListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAllPrivateFieldTypes_ onUnbind(\n      OnModelUnboundListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllPrivateFieldTypes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAllPrivateFieldTypes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAllPrivateFieldTypes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueInt(int valueInt) {\n    onMutation();\n    super.setValueInt(valueInt);\n    return this;\n  }\n\n  public int valueInt() {\n    return super.getValueInt();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueInteger(Integer valueInteger) {\n    onMutation();\n    super.setValueInteger(valueInteger);\n    return this;\n  }\n\n  public Integer valueInteger() {\n    return super.getValueInteger();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueShort(short valueShort) {\n    onMutation();\n    super.setValueShort(valueShort);\n    return this;\n  }\n\n  public short valueShort() {\n    return super.getValueShort();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueShortWrapper(Short valueShortWrapper) {\n    onMutation();\n    super.setValueShortWrapper(valueShortWrapper);\n    return this;\n  }\n\n  public Short valueShortWrapper() {\n    return super.getValueShortWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueChar(char valueChar) {\n    onMutation();\n    super.setValueChar(valueChar);\n    return this;\n  }\n\n  public char valueChar() {\n    return super.getValueChar();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueCharacter(Character valueCharacter) {\n    onMutation();\n    super.setValueCharacter(valueCharacter);\n    return this;\n  }\n\n  public Character valueCharacter() {\n    return super.getValueCharacter();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valuebByte(byte valuebByte) {\n    onMutation();\n    super.setValuebByte(valuebByte);\n    return this;\n  }\n\n  public byte valuebByte() {\n    return super.getValuebByte();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueByteWrapper(Byte valueByteWrapper) {\n    onMutation();\n    super.setValueByteWrapper(valueByteWrapper);\n    return this;\n  }\n\n  public Byte valueByteWrapper() {\n    return super.getValueByteWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueLong(long valueLong) {\n    onMutation();\n    super.setValueLong(valueLong);\n    return this;\n  }\n\n  public long valueLong() {\n    return super.getValueLong();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueLongWrapper(Long valueLongWrapper) {\n    onMutation();\n    super.setValueLongWrapper(valueLongWrapper);\n    return this;\n  }\n\n  public Long valueLongWrapper() {\n    return super.getValueLongWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueDouble(double valueDouble) {\n    onMutation();\n    super.setValueDouble(valueDouble);\n    return this;\n  }\n\n  public double valueDouble() {\n    return super.getValueDouble();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueDoubleWrapper(Double valueDoubleWrapper) {\n    onMutation();\n    super.setValueDoubleWrapper(valueDoubleWrapper);\n    return this;\n  }\n\n  public Double valueDoubleWrapper() {\n    return super.getValueDoubleWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueFloat(float valueFloat) {\n    onMutation();\n    super.setValueFloat(valueFloat);\n    return this;\n  }\n\n  public float valueFloat() {\n    return super.getValueFloat();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueFloatWrapper(Float valueFloatWrapper) {\n    onMutation();\n    super.setValueFloatWrapper(valueFloatWrapper);\n    return this;\n  }\n\n  public Float valueFloatWrapper() {\n    return super.getValueFloatWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueBoolean(boolean valueBoolean) {\n    onMutation();\n    super.setValueBoolean(valueBoolean);\n    return this;\n  }\n\n  public boolean valueBoolean() {\n    return super.isValueBoolean();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueBooleanWrapper(Boolean valueBooleanWrapper) {\n    onMutation();\n    super.setValueBooleanWrapper(valueBooleanWrapper);\n    return this;\n  }\n\n  public Boolean valueBooleanWrapper() {\n    return super.getValueBooleanWrapper();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueIntArray(int[] valueIntArray) {\n    onMutation();\n    super.setValueIntArray(valueIntArray);\n    return this;\n  }\n\n  public int[] valueIntArray() {\n    return super.getValueIntArray();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueObjectArray(Object[] valueObjectArray) {\n    onMutation();\n    super.setValueObjectArray(valueObjectArray);\n    return this;\n  }\n\n  public Object[] valueObjectArray() {\n    return super.getValueObjectArray();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueString(String valueString) {\n    onMutation();\n    super.setValueString(valueString);\n    return this;\n  }\n\n  public String valueString() {\n    return super.getValueString();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueObject(Object valueObject) {\n    onMutation();\n    super.setValueObject(valueObject);\n    return this;\n  }\n\n  public Object valueObject() {\n    return super.getValueObject();\n  }\n\n  public ModelWithAllPrivateFieldTypes_ valueList(List<String> valueList) {\n    onMutation();\n    super.setValueList(valueList);\n    return this;\n  }\n\n  public List<String> valueList() {\n    return super.getValueList();\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ getValueObject() {\n    super.getValueObject();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAllPrivateFieldTypes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setValueInt(0);\n    super.setValueInteger(null);\n    super.setValueShort((short) 0);\n    super.setValueShortWrapper(null);\n    super.setValueChar((char) 0);\n    super.setValueCharacter(null);\n    super.setValuebByte((byte) 0);\n    super.setValueByteWrapper(null);\n    super.setValueLong(0L);\n    super.setValueLongWrapper(null);\n    super.setValueDouble(0.0d);\n    super.setValueDoubleWrapper(null);\n    super.setValueFloat(0.0f);\n    super.setValueFloatWrapper(null);\n    super.setValueBoolean(false);\n    super.setValueBooleanWrapper(null);\n    super.setValueIntArray(null);\n    super.setValueObjectArray(null);\n    super.setValueString(null);\n    super.setValueObject(null);\n    super.setValueList(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAllPrivateFieldTypes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAllPrivateFieldTypes_ that = (ModelWithAllPrivateFieldTypes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getValueInt() != that.getValueInt())) {\n      return false;\n    }\n    if ((getValueInteger() != null ? !getValueInteger().equals(that.getValueInteger()) : that.getValueInteger() != null)) {\n      return false;\n    }\n    if ((getValueShort() != that.getValueShort())) {\n      return false;\n    }\n    if ((getValueShortWrapper() != null ? !getValueShortWrapper().equals(that.getValueShortWrapper()) : that.getValueShortWrapper() != null)) {\n      return false;\n    }\n    if ((getValueChar() != that.getValueChar())) {\n      return false;\n    }\n    if ((getValueCharacter() != null ? !getValueCharacter().equals(that.getValueCharacter()) : that.getValueCharacter() != null)) {\n      return false;\n    }\n    if ((getValuebByte() != that.getValuebByte())) {\n      return false;\n    }\n    if ((getValueByteWrapper() != null ? !getValueByteWrapper().equals(that.getValueByteWrapper()) : that.getValueByteWrapper() != null)) {\n      return false;\n    }\n    if ((getValueLong() != that.getValueLong())) {\n      return false;\n    }\n    if ((getValueLongWrapper() != null ? !getValueLongWrapper().equals(that.getValueLongWrapper()) : that.getValueLongWrapper() != null)) {\n      return false;\n    }\n    if ((Double.compare(that.getValueDouble(), getValueDouble()) != 0)) {\n      return false;\n    }\n    if ((getValueDoubleWrapper() != null ? !getValueDoubleWrapper().equals(that.getValueDoubleWrapper()) : that.getValueDoubleWrapper() != null)) {\n      return false;\n    }\n    if ((Float.compare(that.getValueFloat(), getValueFloat()) != 0)) {\n      return false;\n    }\n    if ((getValueFloatWrapper() != null ? !getValueFloatWrapper().equals(that.getValueFloatWrapper()) : that.getValueFloatWrapper() != null)) {\n      return false;\n    }\n    if ((isValueBoolean() != that.isValueBoolean())) {\n      return false;\n    }\n    if ((getValueBooleanWrapper() != null ? !getValueBooleanWrapper().equals(that.getValueBooleanWrapper()) : that.getValueBooleanWrapper() != null)) {\n      return false;\n    }\n    if (!Arrays.equals(getValueIntArray(), that.getValueIntArray())) {\n      return false;\n    }\n    if (!Arrays.equals(getValueObjectArray(), that.getValueObjectArray())) {\n      return false;\n    }\n    if ((getValueString() != null ? !getValueString().equals(that.getValueString()) : that.getValueString() != null)) {\n      return false;\n    }\n    if ((getValueObject() != null ? !getValueObject().equals(that.getValueObject()) : that.getValueObject() != null)) {\n      return false;\n    }\n    if ((getValueList() != null ? !getValueList().equals(that.getValueList()) : that.getValueList() != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    long temp;\n    _result = 31 * _result + getValueInt();\n    _result = 31 * _result + (getValueInteger() != null ? getValueInteger().hashCode() : 0);\n    _result = 31 * _result + getValueShort();\n    _result = 31 * _result + (getValueShortWrapper() != null ? getValueShortWrapper().hashCode() : 0);\n    _result = 31 * _result + getValueChar();\n    _result = 31 * _result + (getValueCharacter() != null ? getValueCharacter().hashCode() : 0);\n    _result = 31 * _result + getValuebByte();\n    _result = 31 * _result + (getValueByteWrapper() != null ? getValueByteWrapper().hashCode() : 0);\n    _result = 31 * _result + (int) (getValueLong() ^ (getValueLong() >>> 32));\n    _result = 31 * _result + (getValueLongWrapper() != null ? getValueLongWrapper().hashCode() : 0);\n    temp = Double.doubleToLongBits(getValueDouble());\n    _result = 31 * _result + (int) (temp ^ (temp >>> 32));\n    _result = 31 * _result + (getValueDoubleWrapper() != null ? getValueDoubleWrapper().hashCode() : 0);\n    _result = 31 * _result + (getValueFloat() != +0.0f ? Float.floatToIntBits(getValueFloat()) : 0);\n    _result = 31 * _result + (getValueFloatWrapper() != null ? getValueFloatWrapper().hashCode() : 0);\n    _result = 31 * _result + (isValueBoolean() ? 1 : 0);\n    _result = 31 * _result + (getValueBooleanWrapper() != null ? getValueBooleanWrapper().hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(getValueIntArray());\n    _result = 31 * _result + Arrays.hashCode(getValueObjectArray());\n    _result = 31 * _result + (getValueString() != null ? getValueString().hashCode() : 0);\n    _result = 31 * _result + (getValueObject() != null ? getValueObject().hashCode() : 0);\n    _result = 31 * _result + (getValueList() != null ? getValueList().hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAllPrivateFieldTypes_{\" +\n        \"valueInt=\" + getValueInt() +\n        \", valueInteger=\" + getValueInteger() +\n        \", valueShort=\" + getValueShort() +\n        \", valueShortWrapper=\" + getValueShortWrapper() +\n        \", valueChar=\" + getValueChar() +\n        \", valueCharacter=\" + getValueCharacter() +\n        \", valuebByte=\" + getValuebByte() +\n        \", valueByteWrapper=\" + getValueByteWrapper() +\n        \", valueLong=\" + getValueLong() +\n        \", valueLongWrapper=\" + getValueLongWrapper() +\n        \", valueDouble=\" + getValueDouble() +\n        \", valueDoubleWrapper=\" + getValueDoubleWrapper() +\n        \", valueFloat=\" + getValueFloat() +\n        \", valueFloatWrapper=\" + getValueFloatWrapper() +\n        \", valueBoolean=\" + isValueBoolean() +\n        \", valueBooleanWrapper=\" + getValueBooleanWrapper() +\n        \", valueIntArray=\" + getValueIntArray() +\n        \", valueObjectArray=\" + getValueObjectArray() +\n        \", valueString=\" + getValueString() +\n        \", valueObject=\" + getValueObject() +\n        \", valueList=\" + getValueList() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAnnotatedClass_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithAnnotatedClass_ extends ModelWithAnnotatedClass implements GeneratedModel<Object>, ModelWithAnnotatedClassBuilder {\n  private OnModelBoundListener<ModelWithAnnotatedClass_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotatedClass_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotatedClass_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotatedClass_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotatedClass_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClass_ onBind(\n      OnModelBoundListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotatedClass_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClass_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotatedClass_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotatedClass_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotatedClass_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotatedClass_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotatedClass_ that = (ModelWithAnnotatedClass_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotatedClass_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Deprecated;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\n@Deprecated\npublic class ModelWithAnnotation_ extends ModelWithAnnotation implements GeneratedModel<Object>, ModelWithAnnotationBuilder {\n  private OnModelBoundListener<ModelWithAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotation_ onBind(OnModelBoundListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithAnnotation_ that = (ModelWithAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithAnnotation_{\" +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithCheckedChangeListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.widget.CompoundButton;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithCheckedChangeListener_ extends ModelWithCheckedChangeListener implements GeneratedModel<Object>, ModelWithCheckedChangeListenerBuilder {\n  private OnModelBoundListener<ModelWithCheckedChangeListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithCheckedChangeListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithCheckedChangeListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithCheckedChangeListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithCheckedChangeListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithCheckedChangeListener_ onBind(\n      OnModelBoundListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithCheckedChangeListener_ onUnbind(\n      OnModelUnboundListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithCheckedChangeListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithCheckedChangeListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithCheckedChangeListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a checked change listener that will provide the parent view, model, value, and adapter position of the checked view. This will clear the normal CompoundButton.OnCheckedChangeListener if one has been set\n   */\n  public ModelWithCheckedChangeListener_ checkedListener(\n      final OnModelCheckedChangeListener<ModelWithCheckedChangeListener_, Object> checkedListener) {\n    onMutation();\n    if (checkedListener == null) {\n      super.checkedListener = null;\n    }\n    else {\n      super.checkedListener = new WrappedEpoxyModelCheckedChangeListener(checkedListener);\n    }\n    return this;\n  }\n\n  public ModelWithCheckedChangeListener_ checkedListener(\n      CompoundButton.OnCheckedChangeListener checkedListener) {\n    onMutation();\n    super.checkedListener = checkedListener;\n    return this;\n  }\n\n  public CompoundButton.OnCheckedChangeListener checkedListener() {\n    return checkedListener;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithCheckedChangeListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.checkedListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithCheckedChangeListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithCheckedChangeListener_ that = (ModelWithCheckedChangeListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((checkedListener == null) != (that.checkedListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (checkedListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithCheckedChangeListener_{\" +\n        \"checkedListener=\" + checkedListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithConstructors_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithConstructors_ extends ModelWithConstructors implements GeneratedModel<Object>, ModelWithConstructorsBuilder {\n  private OnModelBoundListener<ModelWithConstructors_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithConstructors_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithConstructors_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithConstructors_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithConstructors_(long id, int valueInt) {\n    super(id, valueInt);\n  }\n\n  public ModelWithConstructors_(int valueInt) {\n    super(valueInt);\n  }\n\n  public ModelWithConstructors_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithConstructors_ onBind(\n      OnModelBoundListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithConstructors_ onUnbind(\n      OnModelUnboundListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithConstructors_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithConstructors_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithConstructors_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithConstructors_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithConstructors_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithConstructors_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithConstructors_ that = (ModelWithConstructors_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + valueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithConstructors_{\" +\n        \"valueInt=\" + valueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithFieldAnnotation_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithFieldAnnotation_ extends ModelWithFieldAnnotation implements GeneratedModel<Object>, ModelWithFieldAnnotationBuilder {\n  private OnModelBoundListener<ModelWithFieldAnnotation_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithFieldAnnotation_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithFieldAnnotation_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithFieldAnnotation_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithFieldAnnotation_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFieldAnnotation_ onBind(\n      OnModelBoundListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFieldAnnotation_ onUnbind(\n      OnModelUnboundListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFieldAnnotation_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFieldAnnotation_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithFieldAnnotation_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithFieldAnnotation_ title(@Nullable String title) {\n    onMutation();\n    super.title = title;\n    return this;\n  }\n\n  @Nullable\n  public String title() {\n    return title;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithFieldAnnotation_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.title = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithFieldAnnotation_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithFieldAnnotation_ that = (ModelWithFieldAnnotation_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title != null ? !title.equals(that.title) : that.title != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title != null ? title.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithFieldAnnotation_{\" +\n        \"title=\" + title +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithFinalField_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithFinalField_ extends ModelWithFinalField implements GeneratedModel<Object>, ModelWithFinalFieldBuilder {\n  private OnModelBoundListener<ModelWithFinalField_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithFinalField_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithFinalField_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithFinalField_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithFinalField_(long id, int valueInt) {\n    super(id, valueInt);\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFinalField_ onBind(OnModelBoundListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithFinalField_ onUnbind(\n      OnModelUnboundListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFinalField_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithFinalField_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithFinalField_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int finalValueInt() {\n    return finalValueInt;\n  }\n\n  public ModelWithFinalField_ nonFinalValueInt(int nonFinalValueInt) {\n    onMutation();\n    super.nonFinalValueInt = nonFinalValueInt;\n    return this;\n  }\n\n  public int nonFinalValueInt() {\n    return nonFinalValueInt;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithFinalField_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.nonFinalValueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithFinalField_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithFinalField_ that = (ModelWithFinalField_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((finalValueInt != that.finalValueInt)) {\n      return false;\n    }\n    if ((nonFinalValueInt != that.nonFinalValueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + finalValueInt;\n    _result = 31 * _result + nonFinalValueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithFinalField_{\" +\n        \"finalValueInt=\" + finalValueInt +\n        \", nonFinalValueInt=\" + nonFinalValueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ extends ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName implements GeneratedModel<Object>, ModelWithPrivateFieldWithSameAsFieldGetterAndSetterNameBuilder {\n  private OnModelBoundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onBind(\n      OnModelBoundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onUnbind(\n      OnModelUnboundListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ isValue(boolean isValue) {\n    onMutation();\n    super.setValue(isValue);\n    return this;\n  }\n\n  public boolean isValue() {\n    return super.isValue();\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setValue(false);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_ that = (ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((isValue() != that.isValue())) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (isValue() ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithPrivateFieldWithSameAsFieldGetterAndSetterName_{\" +\n        \"isValue=\" + isValue() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithPrivateViewClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithPrivateViewClickListener_ extends ModelWithPrivateViewClickListener implements GeneratedModel<Object>, ModelWithPrivateViewClickListenerBuilder {\n  private OnModelBoundListener<ModelWithPrivateViewClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithPrivateViewClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithPrivateViewClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithPrivateViewClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithPrivateViewClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateViewClickListener_ onBind(\n      OnModelBoundListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithPrivateViewClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateViewClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithPrivateViewClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithPrivateViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithPrivateViewClickListener_ clickListener(\n      final OnModelClickListener<ModelWithPrivateViewClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.setClickListener(null);\n    }\n    else {\n      super.setClickListener(new WrappedEpoxyModelClickListener<>(clickListener));\n    }\n    return this;\n  }\n\n  public ModelWithPrivateViewClickListener_ clickListener(View.OnClickListener clickListener) {\n    onMutation();\n    super.setClickListener(clickListener);\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return super.getClickListener();\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithPrivateViewClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setClickListener(null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithPrivateViewClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithPrivateViewClickListener_ that = (ModelWithPrivateViewClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((getClickListener() == null) != (that.getClickListener() == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (getClickListener() != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithPrivateViewClickListener_{\" +\n        \"clickListener=\" + getClickListener() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithSuperAttributes$SubModelWithSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuperAttributes$SubModelWithSuperAttributes_ extends ModelWithSuperAttributes.SubModelWithSuperAttributes implements GeneratedModel<Object>, ModelWithSuperAttributes_SubModelWithSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuperAttributes$SubModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ subValue(int subValue) {\n    onMutation();\n    super.subValue = subValue;\n    return this;\n  }\n\n  public int subValue() {\n    return subValue;\n  }\n\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ superValue(int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes$SubModelWithSuperAttributes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.subValue = 0;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuperAttributes$SubModelWithSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuperAttributes$SubModelWithSuperAttributes_ that = (ModelWithSuperAttributes$SubModelWithSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((subValue != that.subValue)) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + subValue;\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuperAttributes$SubModelWithSuperAttributes_{\" +\n        \"subValue=\" + subValue +\n        \", superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithSuperAttributes_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuperAttributes_ extends ModelWithSuperAttributes implements GeneratedModel<Object>, ModelWithSuperAttributesBuilder {\n  private OnModelBoundListener<ModelWithSuperAttributes_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuperAttributes_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuperAttributes_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuperAttributes_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuperAttributes_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes_ onBind(\n      OnModelBoundListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuperAttributes_ onUnbind(\n      OnModelUnboundListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuperAttributes_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuperAttributes_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuperAttributes_ superValue(int superValue) {\n    onMutation();\n    super.superValue = superValue;\n    return this;\n  }\n\n  public int superValue() {\n    return superValue;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuperAttributes_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.superValue = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuperAttributes_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuperAttributes_ that = (ModelWithSuperAttributes_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((superValue != that.superValue)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + superValue;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuperAttributes_{\" +\n        \"superValue=\" + superValue +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithSuper_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithSuper_ extends ModelWithSuper implements GeneratedModel<Object>, ModelWithSuperBuilder {\n  private OnModelBoundListener<ModelWithSuper_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithSuper_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithSuper_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithSuper_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithSuper_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuper_ onBind(OnModelBoundListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithSuper_ onUnbind(OnModelUnboundListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuper_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithSuper_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithSuper_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithSuper_ valueInt(int valueInt) {\n    onMutation();\n    super.valueInt = valueInt;\n    super.valueInt(valueInt);\n    return this;\n  }\n\n  public int valueInt() {\n    return valueInt;\n  }\n\n  @Override\n  public ModelWithSuper_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithSuper_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.valueInt = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithSuper_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithSuper_ that = (ModelWithSuper_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((valueInt != that.valueInt)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + valueInt;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithSuper_{\" +\n        \"valueInt=\" + valueInt +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithViewClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithViewClickListener_ extends ModelWithViewClickListener implements GeneratedModel<Object>, ModelWithViewClickListenerBuilder {\n  private OnModelBoundListener<ModelWithViewClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithViewClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithViewClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithViewClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithViewClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewClickListener_ onBind(\n      OnModelBoundListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithViewClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithViewClickListener_ clickListener(\n      final OnModelClickListener<ModelWithViewClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.clickListener = null;\n    }\n    else {\n      super.clickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  public ModelWithViewClickListener_ clickListener(View.OnClickListener clickListener) {\n    onMutation();\n    super.clickListener = clickListener;\n    return this;\n  }\n\n  public View.OnClickListener clickListener() {\n    return clickListener;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.clickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithViewClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithViewClickListener_ that = (ModelWithViewClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((clickListener == null) != (that.clickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithViewClickListener_{\" +\n        \"clickListener=\" + clickListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithViewLongClickListener_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithViewLongClickListener_ extends ModelWithViewLongClickListener implements GeneratedModel<Object>, ModelWithViewLongClickListenerBuilder {\n  private OnModelBoundListener<ModelWithViewLongClickListener_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithViewLongClickListener_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithViewLongClickListener_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithViewLongClickListener_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithViewLongClickListener_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewLongClickListener_ onBind(\n      OnModelBoundListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithViewLongClickListener_ onUnbind(\n      OnModelUnboundListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewLongClickListener_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithViewLongClickListener_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithViewLongClickListener_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public ModelWithViewLongClickListener_ clickListener(\n      final OnModelLongClickListener<ModelWithViewLongClickListener_, Object> clickListener) {\n    onMutation();\n    if (clickListener == null) {\n      super.clickListener = null;\n    }\n    else {\n      super.clickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  public ModelWithViewLongClickListener_ clickListener(View.OnLongClickListener clickListener) {\n    onMutation();\n    super.clickListener = clickListener;\n    return this;\n  }\n\n  public View.OnLongClickListener clickListener() {\n    return clickListener;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithViewLongClickListener_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.clickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithViewLongClickListener_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithViewLongClickListener_ that = (ModelWithViewLongClickListener_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((clickListener == null) != (that.clickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithViewLongClickListener_{\" +\n        \"clickListener=\" + clickListener +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithoutHash_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithoutHash_ extends ModelWithoutHash implements GeneratedModel<Object>, ModelWithoutHashBuilder {\n  private OnModelBoundListener<ModelWithoutHash_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithoutHash_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithoutHash_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithoutHash_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithoutHash_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutHash_ onBind(OnModelBoundListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutHash_ onUnbind(OnModelUnboundListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutHash_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutHash_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithoutHash_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public ModelWithoutHash_ value(int value) {\n    onMutation();\n    super.value = value;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  public ModelWithoutHash_ value2(int value2) {\n    onMutation();\n    super.value2 = value2;\n    return this;\n  }\n\n  public int value2() {\n    return value2;\n  }\n\n  public ModelWithoutHash_ value3(String value3) {\n    onMutation();\n    super.value3 = value3;\n    return this;\n  }\n\n  public String value3() {\n    return value3;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutHash_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.value2 = 0;\n    super.value3 = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithoutHash_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithoutHash_ that = (ModelWithoutHash_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    if (((value3 == null) != (that.value3 == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    _result = 31 * _result + (value3 != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithoutHash_{\" +\n        \"value=\" + value +\n        \", value2=\" + value2 +\n        \", value3=\" + value3 +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/ModelWithoutSetter_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class ModelWithoutSetter_ extends ModelWithoutSetter implements GeneratedModel<Object>, ModelWithoutSetterBuilder {\n  private OnModelBoundListener<ModelWithoutSetter_, Object> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<ModelWithoutSetter_, Object> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<ModelWithoutSetter_, Object> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<ModelWithoutSetter_, Object> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public ModelWithoutSetter_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Object object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Object object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutSetter_ onBind(OnModelBoundListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Object object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public ModelWithoutSetter_ onUnbind(\n      OnModelUnboundListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Object object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutSetter_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Object object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public ModelWithoutSetter_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<ModelWithoutSetter_, Object> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int value() {\n    return value;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  public ModelWithoutSetter_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.value = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof ModelWithoutSetter_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    ModelWithoutSetter_ that = (ModelWithoutSetter_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value != that.value)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"ModelWithoutSetter_{\" +\n        \"value=\" + value +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/NullOnRecycleViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class NullOnRecycleViewModel_ extends EpoxyModel<NullOnRecycleView> implements GeneratedModel<NullOnRecycleView>, NullOnRecycleViewModelBuilder {\n  private OnModelBoundListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private CharSequence title_CharSequence = (CharSequence) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final NullOnRecycleView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final NullOnRecycleView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final NullOnRecycleView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof NullOnRecycleViewModel_)) {\n      bind(object);\n      return;\n    }\n    NullOnRecycleViewModel_ that = (NullOnRecycleViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final NullOnRecycleView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public NullOnRecycleViewModel_ onBind(\n      OnModelBoundListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(NullOnRecycleView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setTitle((CharSequence) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public NullOnRecycleViewModel_ onUnbind(\n      OnModelUnboundListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final NullOnRecycleView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public NullOnRecycleViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final NullOnRecycleView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public NullOnRecycleViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<NullOnRecycleViewModel_, NullOnRecycleView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see NullOnRecycleView#setTitle(CharSequence)\n   */\n  public NullOnRecycleViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public NullOnRecycleViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.title_CharSequence = (CharSequence) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof NullOnRecycleViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    NullOnRecycleViewModel_ that = (NullOnRecycleViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"NullOnRecycleViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/OnViewRecycledViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnViewRecycledViewModel_ extends EpoxyModel<OnViewRecycledView> implements GeneratedModel<OnViewRecycledView>, OnViewRecycledViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnViewRecycledView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnViewRecycledView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnViewRecycledView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnViewRecycledViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnViewRecycledViewModel_ that = (OnViewRecycledViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnViewRecycledView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnViewRecycledViewModel_ onBind(\n      OnModelBoundListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnViewRecycledView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.onRecycled1();\n    object.onRecycled2();\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnViewRecycledViewModel_ onUnbind(\n      OnModelUnboundListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final OnViewRecycledView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnViewRecycledViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnViewRecycledView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnViewRecycledViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnViewRecycledViewModel_, OnViewRecycledView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnViewRecycledView#setTitle(CharSequence)\n   */\n  public OnViewRecycledViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnViewRecycledViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnViewRecycledViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnViewRecycledViewModel_ that = (OnViewRecycledViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnViewRecycledViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/OnVisibilityChangedViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnVisibilityChangedViewModel_ extends EpoxyModel<OnVisibilityChangedView> implements GeneratedModel<OnVisibilityChangedView>, OnVisibilityChangedViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnVisibilityChangedView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnVisibilityChangedView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnVisibilityChangedView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnVisibilityChangedViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnVisibilityChangedViewModel_ that = (OnVisibilityChangedViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnVisibilityChangedView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityChangedViewModel_ onBind(\n      OnModelBoundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnVisibilityChangedView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityChangedViewModel_ onUnbind(\n      OnModelUnboundListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final OnVisibilityChangedView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityChangedViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnVisibilityChangedView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    object.onVisibilityChanged1(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    object.onVisibilityChanged2(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityChangedViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnVisibilityChangedViewModel_, OnVisibilityChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnVisibilityChangedView#setTitle(CharSequence)\n   */\n  public OnVisibilityChangedViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnVisibilityChangedViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnVisibilityChangedViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnVisibilityChangedViewModel_ that = (OnVisibilityChangedViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnVisibilityChangedViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/OnVisibilityStateChangedViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class OnVisibilityStateChangedViewModel_ extends EpoxyModel<OnVisibilityStateChangedView> implements GeneratedModel<OnVisibilityStateChangedView>, OnVisibilityStateChangedViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private CharSequence title_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final OnVisibilityStateChangedView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final OnVisibilityStateChangedView object) {\n    super.bind(object);\n    object.setTitle(title_CharSequence);\n  }\n\n  @Override\n  public void bind(final OnVisibilityStateChangedView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof OnVisibilityStateChangedViewModel_)) {\n      bind(object);\n      return;\n    }\n    OnVisibilityStateChangedViewModel_ that = (OnVisibilityStateChangedViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      object.setTitle(title_CharSequence);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final OnVisibilityStateChangedView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityStateChangedViewModel_ onBind(\n      OnModelBoundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(OnVisibilityStateChangedView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public OnVisibilityStateChangedViewModel_ onUnbind(\n      OnModelUnboundListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final OnVisibilityStateChangedView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    object.onVisibilityStateChanged1(visibilityState);\n    object.onVisibilityStateChanged2(visibilityState);\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityStateChangedViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final OnVisibilityStateChangedView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public OnVisibilityStateChangedViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<OnVisibilityStateChangedViewModel_, OnVisibilityStateChangedView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see OnVisibilityStateChangedView#setTitle(CharSequence)\n   */\n  public OnVisibilityStateChangedViewModel_ title(@NonNull CharSequence title) {\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.title_CharSequence = title;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence title() {\n    return title_CharSequence;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public OnVisibilityStateChangedViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof OnVisibilityStateChangedViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    OnVisibilityStateChangedViewModel_ that = (OnVisibilityStateChangedViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_CharSequence != null ? !title_CharSequence.equals(that.title_CharSequence) : that.title_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_CharSequence != null ? title_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"OnVisibilityStateChangedViewModel_{\" +\n        \"title_CharSequence=\" + title_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/PropDefaultsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class PropDefaultsViewModel_ extends EpoxyModel<PropDefaultsView> implements GeneratedModel<PropDefaultsView>, PropDefaultsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(6);\n\n  private OnModelBoundListener<PropDefaultsViewModel_, PropDefaultsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<PropDefaultsViewModel_, PropDefaultsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<PropDefaultsViewModel_, PropDefaultsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<PropDefaultsViewModel_, PropDefaultsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private CharSequence defaultsToNull_CharSequence = (CharSequence) null;\n\n  /**\n   * Bitset index: 1\n   */\n  @NonNull\n  private CharSequence noDefaultSoItIsRequired_CharSequence;\n\n  private int primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = 0;\n\n  private int primitiveWithExplicitDefault_Int = PropDefaultsView.PRIMITIVE_DEFAULT;\n\n  @NonNull\n  private String objectWithDefault_String = PropDefaultsView.STRING_DEFAULT;\n\n  @Nullable\n  private String objectWithDefaultAndNullable_String = PropDefaultsView.STRING_DEFAULT;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(1)) {\n    \tthrow new IllegalStateException(\"A value is required for noDefaultSoItIsRequired\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final PropDefaultsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final PropDefaultsView object) {\n    super.bind(object);\n    object.primitiveWithExplicitDefault(primitiveWithExplicitDefault_Int);\n    object.defaultsToNull(defaultsToNull_CharSequence);\n    object.noDefaultSoItIsRequired(noDefaultSoItIsRequired_CharSequence);\n    object.objectWithDefaultAndNullable(objectWithDefaultAndNullable_String);\n    object.objectWithDefault(objectWithDefault_String);\n    object.primitivesHaveImplicitDefaultsAndCannotBeRequired(primitivesHaveImplicitDefaultsAndCannotBeRequired_Int);\n  }\n\n  @Override\n  public void bind(final PropDefaultsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof PropDefaultsViewModel_)) {\n      bind(object);\n      return;\n    }\n    PropDefaultsViewModel_ that = (PropDefaultsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((primitiveWithExplicitDefault_Int != that.primitiveWithExplicitDefault_Int)) {\n      object.primitiveWithExplicitDefault(primitiveWithExplicitDefault_Int);\n    }\n\n    if ((defaultsToNull_CharSequence != null ? !defaultsToNull_CharSequence.equals(that.defaultsToNull_CharSequence) : that.defaultsToNull_CharSequence != null)) {\n      object.defaultsToNull(defaultsToNull_CharSequence);\n    }\n\n    if ((noDefaultSoItIsRequired_CharSequence != null ? !noDefaultSoItIsRequired_CharSequence.equals(that.noDefaultSoItIsRequired_CharSequence) : that.noDefaultSoItIsRequired_CharSequence != null)) {\n      object.noDefaultSoItIsRequired(noDefaultSoItIsRequired_CharSequence);\n    }\n\n    if ((objectWithDefaultAndNullable_String != null ? !objectWithDefaultAndNullable_String.equals(that.objectWithDefaultAndNullable_String) : that.objectWithDefaultAndNullable_String != null)) {\n      object.objectWithDefaultAndNullable(objectWithDefaultAndNullable_String);\n    }\n\n    if ((objectWithDefault_String != null ? !objectWithDefault_String.equals(that.objectWithDefault_String) : that.objectWithDefault_String != null)) {\n      object.objectWithDefault(objectWithDefault_String);\n    }\n\n    if ((primitivesHaveImplicitDefaultsAndCannotBeRequired_Int != that.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int)) {\n      object.primitivesHaveImplicitDefaultsAndCannotBeRequired(primitivesHaveImplicitDefaultsAndCannotBeRequired_Int);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final PropDefaultsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropDefaultsViewModel_ onBind(\n      OnModelBoundListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(PropDefaultsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropDefaultsViewModel_ onUnbind(\n      OnModelUnboundListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final PropDefaultsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropDefaultsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final PropDefaultsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropDefaultsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<PropDefaultsViewModel_, PropDefaultsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see PropDefaultsView#defaultsToNull(CharSequence)\n   */\n  public PropDefaultsViewModel_ defaultsToNull(@Nullable CharSequence defaultsToNull) {\n    onMutation();\n    this.defaultsToNull_CharSequence = defaultsToNull;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence defaultsToNull() {\n    return defaultsToNull_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropDefaultsView#noDefaultSoItIsRequired(CharSequence)\n   */\n  public PropDefaultsViewModel_ noDefaultSoItIsRequired(\n      @NonNull CharSequence noDefaultSoItIsRequired) {\n    if (noDefaultSoItIsRequired == null) {\n      throw new IllegalArgumentException(\"noDefaultSoItIsRequired cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    onMutation();\n    this.noDefaultSoItIsRequired_CharSequence = noDefaultSoItIsRequired;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence noDefaultSoItIsRequired() {\n    return noDefaultSoItIsRequired_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropDefaultsView#primitivesHaveImplicitDefaultsAndCannotBeRequired(int)\n   */\n  public PropDefaultsViewModel_ primitivesHaveImplicitDefaultsAndCannotBeRequired(\n      int primitivesHaveImplicitDefaultsAndCannotBeRequired) {\n    onMutation();\n    this.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = primitivesHaveImplicitDefaultsAndCannotBeRequired;\n    return this;\n  }\n\n  public int primitivesHaveImplicitDefaultsAndCannotBeRequired() {\n    return primitivesHaveImplicitDefaultsAndCannotBeRequired_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#PRIMITIVE_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#primitiveWithExplicitDefault(int)\n   */\n  public PropDefaultsViewModel_ primitiveWithExplicitDefault(int primitiveWithExplicitDefault) {\n    onMutation();\n    this.primitiveWithExplicitDefault_Int = primitiveWithExplicitDefault;\n    return this;\n  }\n\n  public int primitiveWithExplicitDefault() {\n    return primitiveWithExplicitDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#STRING_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#objectWithDefault(String)\n   */\n  public PropDefaultsViewModel_ objectWithDefault(@NonNull String objectWithDefault) {\n    if (objectWithDefault == null) {\n      throw new IllegalArgumentException(\"objectWithDefault cannot be null\");\n    }\n    onMutation();\n    this.objectWithDefault_String = objectWithDefault;\n    return this;\n  }\n\n  @NonNull\n  public String objectWithDefault() {\n    return objectWithDefault_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropDefaultsView#STRING_DEFAULT}</b>\n   *\n   * @see PropDefaultsView#objectWithDefaultAndNullable(String)\n   */\n  public PropDefaultsViewModel_ objectWithDefaultAndNullable(\n      @Nullable String objectWithDefaultAndNullable) {\n    onMutation();\n    this.objectWithDefaultAndNullable_String = objectWithDefaultAndNullable;\n    return this;\n  }\n\n  @Nullable\n  public String objectWithDefaultAndNullable() {\n    return objectWithDefaultAndNullable_String;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public PropDefaultsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.defaultsToNull_CharSequence = (CharSequence) null;\n    this.noDefaultSoItIsRequired_CharSequence = null;\n    this.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int = 0;\n    this.primitiveWithExplicitDefault_Int = PropDefaultsView.PRIMITIVE_DEFAULT;\n    this.objectWithDefault_String = PropDefaultsView.STRING_DEFAULT;\n    this.objectWithDefaultAndNullable_String = PropDefaultsView.STRING_DEFAULT;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof PropDefaultsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    PropDefaultsViewModel_ that = (PropDefaultsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((defaultsToNull_CharSequence != null ? !defaultsToNull_CharSequence.equals(that.defaultsToNull_CharSequence) : that.defaultsToNull_CharSequence != null)) {\n      return false;\n    }\n    if ((noDefaultSoItIsRequired_CharSequence != null ? !noDefaultSoItIsRequired_CharSequence.equals(that.noDefaultSoItIsRequired_CharSequence) : that.noDefaultSoItIsRequired_CharSequence != null)) {\n      return false;\n    }\n    if ((primitivesHaveImplicitDefaultsAndCannotBeRequired_Int != that.primitivesHaveImplicitDefaultsAndCannotBeRequired_Int)) {\n      return false;\n    }\n    if ((primitiveWithExplicitDefault_Int != that.primitiveWithExplicitDefault_Int)) {\n      return false;\n    }\n    if ((objectWithDefault_String != null ? !objectWithDefault_String.equals(that.objectWithDefault_String) : that.objectWithDefault_String != null)) {\n      return false;\n    }\n    if ((objectWithDefaultAndNullable_String != null ? !objectWithDefaultAndNullable_String.equals(that.objectWithDefaultAndNullable_String) : that.objectWithDefaultAndNullable_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (defaultsToNull_CharSequence != null ? defaultsToNull_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (noDefaultSoItIsRequired_CharSequence != null ? noDefaultSoItIsRequired_CharSequence.hashCode() : 0);\n    _result = 31 * _result + primitivesHaveImplicitDefaultsAndCannotBeRequired_Int;\n    _result = 31 * _result + primitiveWithExplicitDefault_Int;\n    _result = 31 * _result + (objectWithDefault_String != null ? objectWithDefault_String.hashCode() : 0);\n    _result = 31 * _result + (objectWithDefaultAndNullable_String != null ? objectWithDefaultAndNullable_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"PropDefaultsViewModel_{\" +\n        \"defaultsToNull_CharSequence=\" + defaultsToNull_CharSequence +\n        \", noDefaultSoItIsRequired_CharSequence=\" + noDefaultSoItIsRequired_CharSequence +\n        \", primitivesHaveImplicitDefaultsAndCannotBeRequired_Int=\" + primitivesHaveImplicitDefaultsAndCannotBeRequired_Int +\n        \", primitiveWithExplicitDefault_Int=\" + primitiveWithExplicitDefault_Int +\n        \", objectWithDefault_String=\" + objectWithDefault_String +\n        \", objectWithDefaultAndNullable_String=\" + objectWithDefaultAndNullable_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/PropGroupsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class PropGroupsViewModel_ extends EpoxyModel<PropGroupsView> implements GeneratedModel<PropGroupsView>, PropGroupsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(14);\n\n  private OnModelBoundListener<PropGroupsViewModel_, PropGroupsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<PropGroupsViewModel_, PropGroupsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<PropGroupsViewModel_, PropGroupsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<PropGroupsViewModel_, PropGroupsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @Nullable\n  private CharSequence something_CharSequence = (CharSequence) null;\n\n  /**\n   * Bitset index: 1\n   */\n  private int something_Int = 0;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private CharSequence somethingElse_CharSequence;\n\n  /**\n   * Bitset index: 3\n   */\n  private int somethingElse_Int = 0;\n\n  /**\n   * Bitset index: 4\n   */\n  private int primitive_Int = 0;\n\n  /**\n   * Bitset index: 5\n   */\n  private long primitive_Long = 0L;\n\n  /**\n   * Bitset index: 6\n   */\n  private int primitiveWithDefault_Int = 0;\n\n  /**\n   * Bitset index: 7\n   */\n  private long primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n\n  /**\n   * Bitset index: 8\n   */\n  private long primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n\n  /**\n   * Bitset index: 9\n   */\n  @NonNull\n  private CharSequence primitiveAndObjectGroupWithPrimitiveDefault_CharSequence;\n\n  /**\n   * Bitset index: 10\n   */\n  private long oneThing_Long = 0L;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private CharSequence anotherThing_CharSequence;\n\n  /**\n   * Bitset index: 12\n   */\n  @NonNull\n  private String requiredGroup_String;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private CharSequence requiredGroup_CharSequence;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(12) && !assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for requiredGroup\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final PropGroupsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final PropGroupsView object) {\n    super.bind(object);\n    if (assignedAttributes_epoxyGeneratedModel.get(4)) {\n      object.setPrimitive(primitive_Int);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(5)) {\n      object.setPrimitive(primitive_Long);\n    }\n    else {\n      object.setPrimitive(primitive_Int);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(12)) {\n      object.requiredGroup(requiredGroup_String);\n    }\n    else {\n      object.requiredGroup(requiredGroup_CharSequence);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(8)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(9)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_CharSequence);\n    }\n    else {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      object.setOneThing(oneThing_Long);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(11)) {\n      object.setAnotherThing(anotherThing_CharSequence);\n    }\n    else {\n      object.setOneThing(oneThing_Long);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setSomething(something_CharSequence);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setSomething(something_Int);\n    }\n    else {\n      object.setSomething(something_CharSequence);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(2)) {\n      object.setSomethingElse(somethingElse_CharSequence);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(3)) {\n      object.setSomethingElse(somethingElse_Int);\n    }\n    else {\n      object.setSomethingElse(somethingElse_Int);\n    }\n    if (assignedAttributes_epoxyGeneratedModel.get(6)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Int);\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(7)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n    else {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n  }\n\n  @Override\n  public void bind(final PropGroupsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof PropGroupsViewModel_)) {\n      bind(object);\n      return;\n    }\n    PropGroupsViewModel_ that = (PropGroupsViewModel_) previousModel;\n    super.bind(object);\n\n    if (assignedAttributes_epoxyGeneratedModel.get(4)) {\n      if ((primitive_Int != that.primitive_Int)) {\n        object.setPrimitive(primitive_Int);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(5)) {\n      if ((primitive_Long != that.primitive_Long)) {\n        object.setPrimitive(primitive_Long);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(4) || that.assignedAttributes_epoxyGeneratedModel.get(5)) {\n      object.setPrimitive(primitive_Int);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(12)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(12) || (requiredGroup_String != null ? !requiredGroup_String.equals(that.requiredGroup_String) : that.requiredGroup_String != null)) {\n        object.requiredGroup(requiredGroup_String);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(13)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(13) || (requiredGroup_CharSequence != null ? !requiredGroup_CharSequence.equals(that.requiredGroup_CharSequence) : that.requiredGroup_CharSequence != null)) {\n        object.requiredGroup(requiredGroup_CharSequence);\n      }\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(8)) {\n      if ((primitiveAndObjectGroupWithPrimitiveDefault_Long != that.primitiveAndObjectGroupWithPrimitiveDefault_Long)) {\n        object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(9)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(9) || (primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? !primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.equals(that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence) : that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null)) {\n        object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_CharSequence);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(8) || that.assignedAttributes_epoxyGeneratedModel.get(9)) {\n      object.primitiveAndObjectGroupWithPrimitiveDefault(primitiveAndObjectGroupWithPrimitiveDefault_Long);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(10)) {\n      if ((oneThing_Long != that.oneThing_Long)) {\n        object.setOneThing(oneThing_Long);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(11)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(11) || (anotherThing_CharSequence != null ? !anotherThing_CharSequence.equals(that.anotherThing_CharSequence) : that.anotherThing_CharSequence != null)) {\n        object.setAnotherThing(anotherThing_CharSequence);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(10) || that.assignedAttributes_epoxyGeneratedModel.get(11)) {\n      object.setOneThing(oneThing_Long);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (something_CharSequence != null ? !something_CharSequence.equals(that.something_CharSequence) : that.something_CharSequence != null)) {\n        object.setSomething(something_CharSequence);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if ((something_Int != that.something_Int)) {\n        object.setSomething(something_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setSomething(something_CharSequence);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(2)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(2) || (somethingElse_CharSequence != null ? !somethingElse_CharSequence.equals(that.somethingElse_CharSequence) : that.somethingElse_CharSequence != null)) {\n        object.setSomethingElse(somethingElse_CharSequence);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(3)) {\n      if ((somethingElse_Int != that.somethingElse_Int)) {\n        object.setSomethingElse(somethingElse_Int);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(2) || that.assignedAttributes_epoxyGeneratedModel.get(3)) {\n      object.setSomethingElse(somethingElse_Int);\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(6)) {\n      if ((primitiveWithDefault_Int != that.primitiveWithDefault_Int)) {\n        object.setPrimitiveWithDefault(primitiveWithDefault_Int);\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(7)) {\n      if ((primitiveWithDefault_Long != that.primitiveWithDefault_Long)) {\n        object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(6) || that.assignedAttributes_epoxyGeneratedModel.get(7)) {\n      object.setPrimitiveWithDefault(primitiveWithDefault_Long);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final PropGroupsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropGroupsViewModel_ onBind(\n      OnModelBoundListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(PropGroupsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public PropGroupsViewModel_ onUnbind(\n      OnModelUnboundListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final PropGroupsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropGroupsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final PropGroupsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public PropGroupsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<PropGroupsViewModel_, PropGroupsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see PropGroupsView#setSomething(CharSequence)\n   */\n  public PropGroupsViewModel_ something(@Nullable CharSequence something) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    assignedAttributes_epoxyGeneratedModel.clear(1);\n    this.something_Int = 0;\n    onMutation();\n    this.something_CharSequence = something;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence somethingCharSequence() {\n    return something_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setSomething(int)\n   */\n  public PropGroupsViewModel_ something(int something) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.something_CharSequence = (CharSequence) null;\n    onMutation();\n    this.something_Int = something;\n    return this;\n  }\n\n  public int somethingInt() {\n    return something_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#setSomethingElse(CharSequence)\n   */\n  public PropGroupsViewModel_ somethingElse(@NonNull CharSequence somethingElse) {\n    if (somethingElse == null) {\n      throw new IllegalArgumentException(\"somethingElse cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    assignedAttributes_epoxyGeneratedModel.clear(3);\n    this.somethingElse_Int = 0;\n    onMutation();\n    this.somethingElse_CharSequence = somethingElse;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence somethingElseCharSequence() {\n    return somethingElse_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setSomethingElse(int)\n   */\n  public PropGroupsViewModel_ somethingElse(int somethingElse) {\n    assignedAttributes_epoxyGeneratedModel.set(3);\n    assignedAttributes_epoxyGeneratedModel.clear(2);\n    this.somethingElse_CharSequence = null;\n    onMutation();\n    this.somethingElse_Int = somethingElse;\n    return this;\n  }\n\n  public int somethingElseInt() {\n    return somethingElse_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setPrimitive(int)\n   */\n  public PropGroupsViewModel_ primitive(int primitive) {\n    assignedAttributes_epoxyGeneratedModel.set(4);\n    assignedAttributes_epoxyGeneratedModel.clear(5);\n    this.primitive_Long = 0L;\n    onMutation();\n    this.primitive_Int = primitive;\n    return this;\n  }\n\n  public int primitiveInt() {\n    return primitive_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see PropGroupsView#setPrimitive(long)\n   */\n  public PropGroupsViewModel_ primitive(long primitive) {\n    assignedAttributes_epoxyGeneratedModel.set(5);\n    assignedAttributes_epoxyGeneratedModel.clear(4);\n    this.primitive_Int = 0;\n    onMutation();\n    this.primitive_Long = primitive;\n    return this;\n  }\n\n  public long primitiveLong() {\n    return primitive_Long;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see PropGroupsView#setPrimitiveWithDefault(int)\n   */\n  public PropGroupsViewModel_ primitiveWithDefault(int primitiveWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(6);\n    assignedAttributes_epoxyGeneratedModel.clear(7);\n    this.primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    onMutation();\n    this.primitiveWithDefault_Int = primitiveWithDefault;\n    return this;\n  }\n\n  public int primitiveWithDefaultInt() {\n    return primitiveWithDefault_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropGroupsView#DEFAULT_PRIMITIVE}</b>\n   *\n   * @see PropGroupsView#setPrimitiveWithDefault(long)\n   */\n  public PropGroupsViewModel_ primitiveWithDefault(long primitiveWithDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(7);\n    assignedAttributes_epoxyGeneratedModel.clear(6);\n    this.primitiveWithDefault_Int = 0;\n    onMutation();\n    this.primitiveWithDefault_Long = primitiveWithDefault;\n    return this;\n  }\n\n  public long primitiveWithDefaultLong() {\n    return primitiveWithDefault_Long;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is <b>{@value PropGroupsView#DEFAULT_PRIMITIVE}</b>\n   *\n   * @see PropGroupsView#primitiveAndObjectGroupWithPrimitiveDefault(long)\n   */\n  public PropGroupsViewModel_ primitiveAndObjectGroupWithPrimitiveDefault(\n      long primitiveAndObjectGroupWithPrimitiveDefault) {\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    assignedAttributes_epoxyGeneratedModel.clear(9);\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = null;\n    onMutation();\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = primitiveAndObjectGroupWithPrimitiveDefault;\n    return this;\n  }\n\n  public long primitiveAndObjectGroupWithPrimitiveDefaultLong() {\n    return primitiveAndObjectGroupWithPrimitiveDefault_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#primitiveAndObjectGroupWithPrimitiveDefault(CharSequence)\n   */\n  public PropGroupsViewModel_ primitiveAndObjectGroupWithPrimitiveDefault(\n      @NonNull CharSequence primitiveAndObjectGroupWithPrimitiveDefault) {\n    if (primitiveAndObjectGroupWithPrimitiveDefault == null) {\n      throw new IllegalArgumentException(\"primitiveAndObjectGroupWithPrimitiveDefault cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(9);\n    assignedAttributes_epoxyGeneratedModel.clear(8);\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    onMutation();\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = primitiveAndObjectGroupWithPrimitiveDefault;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence primitiveAndObjectGroupWithPrimitiveDefaultCharSequence() {\n    return primitiveAndObjectGroupWithPrimitiveDefault_CharSequence;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0L\n   *\n   * @see PropGroupsView#setOneThing(long)\n   */\n  public PropGroupsViewModel_ oneThing(long oneThing) {\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    assignedAttributes_epoxyGeneratedModel.clear(11);\n    this.anotherThing_CharSequence = null;\n    onMutation();\n    this.oneThing_Long = oneThing;\n    return this;\n  }\n\n  public long oneThingLong() {\n    return oneThing_Long;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#setAnotherThing(CharSequence)\n   */\n  public PropGroupsViewModel_ anotherThing(@NonNull CharSequence anotherThing) {\n    if (anotherThing == null) {\n      throw new IllegalArgumentException(\"anotherThing cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    assignedAttributes_epoxyGeneratedModel.clear(10);\n    this.oneThing_Long = 0L;\n    onMutation();\n    this.anotherThing_CharSequence = anotherThing;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence anotherThingCharSequence() {\n    return anotherThing_CharSequence;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#requiredGroup(String)\n   */\n  public PropGroupsViewModel_ requiredGroup(@NonNull String requiredGroup) {\n    if (requiredGroup == null) {\n      throw new IllegalArgumentException(\"requiredGroup cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(12);\n    assignedAttributes_epoxyGeneratedModel.clear(13);\n    this.requiredGroup_CharSequence = null;\n    onMutation();\n    this.requiredGroup_String = requiredGroup;\n    return this;\n  }\n\n  @NonNull\n  public String requiredGroupString() {\n    return requiredGroup_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see PropGroupsView#requiredGroup(CharSequence)\n   */\n  public PropGroupsViewModel_ requiredGroup(@NonNull CharSequence requiredGroup) {\n    if (requiredGroup == null) {\n      throw new IllegalArgumentException(\"requiredGroup cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    assignedAttributes_epoxyGeneratedModel.clear(12);\n    this.requiredGroup_String = null;\n    onMutation();\n    this.requiredGroup_CharSequence = requiredGroup;\n    return this;\n  }\n\n  @NonNull\n  public CharSequence requiredGroupCharSequence() {\n    return requiredGroup_CharSequence;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public PropGroupsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public PropGroupsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.something_CharSequence = (CharSequence) null;\n    this.something_Int = 0;\n    this.somethingElse_CharSequence = null;\n    this.somethingElse_Int = 0;\n    this.primitive_Int = 0;\n    this.primitive_Long = 0L;\n    this.primitiveWithDefault_Int = 0;\n    this.primitiveWithDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    this.primitiveAndObjectGroupWithPrimitiveDefault_Long = PropGroupsView.DEFAULT_PRIMITIVE;\n    this.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence = null;\n    this.oneThing_Long = 0L;\n    this.anotherThing_CharSequence = null;\n    this.requiredGroup_String = null;\n    this.requiredGroup_CharSequence = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof PropGroupsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    PropGroupsViewModel_ that = (PropGroupsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((something_CharSequence != null ? !something_CharSequence.equals(that.something_CharSequence) : that.something_CharSequence != null)) {\n      return false;\n    }\n    if ((something_Int != that.something_Int)) {\n      return false;\n    }\n    if ((somethingElse_CharSequence != null ? !somethingElse_CharSequence.equals(that.somethingElse_CharSequence) : that.somethingElse_CharSequence != null)) {\n      return false;\n    }\n    if ((somethingElse_Int != that.somethingElse_Int)) {\n      return false;\n    }\n    if ((primitive_Int != that.primitive_Int)) {\n      return false;\n    }\n    if ((primitive_Long != that.primitive_Long)) {\n      return false;\n    }\n    if ((primitiveWithDefault_Int != that.primitiveWithDefault_Int)) {\n      return false;\n    }\n    if ((primitiveWithDefault_Long != that.primitiveWithDefault_Long)) {\n      return false;\n    }\n    if ((primitiveAndObjectGroupWithPrimitiveDefault_Long != that.primitiveAndObjectGroupWithPrimitiveDefault_Long)) {\n      return false;\n    }\n    if ((primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? !primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.equals(that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence) : that.primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null)) {\n      return false;\n    }\n    if ((oneThing_Long != that.oneThing_Long)) {\n      return false;\n    }\n    if ((anotherThing_CharSequence != null ? !anotherThing_CharSequence.equals(that.anotherThing_CharSequence) : that.anotherThing_CharSequence != null)) {\n      return false;\n    }\n    if ((requiredGroup_String != null ? !requiredGroup_String.equals(that.requiredGroup_String) : that.requiredGroup_String != null)) {\n      return false;\n    }\n    if ((requiredGroup_CharSequence != null ? !requiredGroup_CharSequence.equals(that.requiredGroup_CharSequence) : that.requiredGroup_CharSequence != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (something_CharSequence != null ? something_CharSequence.hashCode() : 0);\n    _result = 31 * _result + something_Int;\n    _result = 31 * _result + (somethingElse_CharSequence != null ? somethingElse_CharSequence.hashCode() : 0);\n    _result = 31 * _result + somethingElse_Int;\n    _result = 31 * _result + primitive_Int;\n    _result = 31 * _result + (int) (primitive_Long ^ (primitive_Long >>> 32));\n    _result = 31 * _result + primitiveWithDefault_Int;\n    _result = 31 * _result + (int) (primitiveWithDefault_Long ^ (primitiveWithDefault_Long >>> 32));\n    _result = 31 * _result + (int) (primitiveAndObjectGroupWithPrimitiveDefault_Long ^ (primitiveAndObjectGroupWithPrimitiveDefault_Long >>> 32));\n    _result = 31 * _result + (primitiveAndObjectGroupWithPrimitiveDefault_CharSequence != null ? primitiveAndObjectGroupWithPrimitiveDefault_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (int) (oneThing_Long ^ (oneThing_Long >>> 32));\n    _result = 31 * _result + (anotherThing_CharSequence != null ? anotherThing_CharSequence.hashCode() : 0);\n    _result = 31 * _result + (requiredGroup_String != null ? requiredGroup_String.hashCode() : 0);\n    _result = 31 * _result + (requiredGroup_CharSequence != null ? requiredGroup_CharSequence.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"PropGroupsViewModel_{\" +\n        \"something_CharSequence=\" + something_CharSequence +\n        \", something_Int=\" + something_Int +\n        \", somethingElse_CharSequence=\" + somethingElse_CharSequence +\n        \", somethingElse_Int=\" + somethingElse_Int +\n        \", primitive_Int=\" + primitive_Int +\n        \", primitive_Long=\" + primitive_Long +\n        \", primitiveWithDefault_Int=\" + primitiveWithDefault_Int +\n        \", primitiveWithDefault_Long=\" + primitiveWithDefault_Long +\n        \", primitiveAndObjectGroupWithPrimitiveDefault_Long=\" + primitiveAndObjectGroupWithPrimitiveDefault_Long +\n        \", primitiveAndObjectGroupWithPrimitiveDefault_CharSequence=\" + primitiveAndObjectGroupWithPrimitiveDefault_CharSequence +\n        \", oneThing_Long=\" + oneThing_Long +\n        \", anotherThing_CharSequence=\" + anotherThing_CharSequence +\n        \", requiredGroup_String=\" + requiredGroup_String +\n        \", requiredGroup_CharSequence=\" + requiredGroup_CharSequence +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/RLayoutInViewModelAnnotationWorksViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class RLayoutInViewModelAnnotationWorksViewModel_ extends EpoxyModel<RLayoutInViewModelAnnotationWorksView> implements GeneratedModel<RLayoutInViewModelAnnotationWorksView>, RLayoutInViewModelAnnotationWorksViewModelBuilder {\n  private OnModelBoundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final RLayoutInViewModelAnnotationWorksView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final RLayoutInViewModelAnnotationWorksView object) {\n    super.bind(object);\n  }\n\n  @Override\n  public void bind(final RLayoutInViewModelAnnotationWorksView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof RLayoutInViewModelAnnotationWorksViewModel_)) {\n      bind(object);\n      return;\n    }\n    RLayoutInViewModelAnnotationWorksViewModel_ that = (RLayoutInViewModelAnnotationWorksViewModel_) previousModel;\n    super.bind(object);\n  }\n\n  @Override\n  public void handlePostBind(final RLayoutInViewModelAnnotationWorksView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onBind(\n      OnModelBoundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(RLayoutInViewModelAnnotationWorksView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onUnbind(\n      OnModelUnboundListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final RLayoutInViewModelAnnotationWorksView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final RLayoutInViewModelAnnotationWorksView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public RLayoutInViewModelAnnotationWorksViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<RLayoutInViewModelAnnotationWorksViewModel_, RLayoutInViewModelAnnotationWorksView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return R.layout.res;\n  }\n\n  @Override\n  public RLayoutInViewModelAnnotationWorksViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof RLayoutInViewModelAnnotationWorksViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    RLayoutInViewModelAnnotationWorksViewModel_ that = (RLayoutInViewModelAnnotationWorksViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"RLayoutInViewModelAnnotationWorksViewModel_{\" +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/SavedStateViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class SavedStateViewModel_ extends EpoxyModel<SavedStateView> implements GeneratedModel<SavedStateView>, SavedStateViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<SavedStateViewModel_, SavedStateView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<SavedStateViewModel_, SavedStateView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<SavedStateViewModel_, SavedStateView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<SavedStateViewModel_, SavedStateView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String clickListener_String;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final SavedStateView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final SavedStateView object) {\n    super.bind(object);\n    object.setClickListener(clickListener_String);\n  }\n\n  @Override\n  public void bind(final SavedStateView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof SavedStateViewModel_)) {\n      bind(object);\n      return;\n    }\n    SavedStateViewModel_ that = (SavedStateViewModel_) previousModel;\n    super.bind(object);\n\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      object.setClickListener(clickListener_String);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final SavedStateView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SavedStateViewModel_ onBind(\n      OnModelBoundListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(SavedStateView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public SavedStateViewModel_ onUnbind(\n      OnModelUnboundListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final SavedStateView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SavedStateViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final SavedStateView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public SavedStateViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<SavedStateViewModel_, SavedStateView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see SavedStateView#setClickListener(String)\n   */\n  public SavedStateViewModel_ clickListener(@NonNull String clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.clickListener_String = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public String clickListener() {\n    return clickListener_String;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public SavedStateViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public SavedStateViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.clickListener_String = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof SavedStateViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    SavedStateViewModel_ that = (SavedStateViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((clickListener_String != null ? !clickListener_String.equals(that.clickListener_String) : that.clickListener_String != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (clickListener_String != null ? clickListener_String.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"SavedStateViewModel_{\" +\n        \"clickListener_String=\" + clickListener_String +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public boolean shouldSaveViewState() {\n    return true;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestAfterBindPropsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestAfterBindPropsViewModel_ extends EpoxyModel<TestAfterBindPropsView> implements GeneratedModel<TestAfterBindPropsView>, TestAfterBindPropsViewModelBuilder {\n  private OnModelBoundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private boolean flag_Boolean = false;\n\n  private boolean flagSuper_Boolean = false;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestAfterBindPropsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestAfterBindPropsView object) {\n    super.bind(object);\n    object.setFlagSuper(flagSuper_Boolean);\n    object.setFlag(flag_Boolean);\n  }\n\n  @Override\n  public void bind(final TestAfterBindPropsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestAfterBindPropsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestAfterBindPropsViewModel_ that = (TestAfterBindPropsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((flagSuper_Boolean != that.flagSuper_Boolean)) {\n      object.setFlagSuper(flagSuper_Boolean);\n    }\n\n    if ((flag_Boolean != that.flag_Boolean)) {\n      object.setFlag(flag_Boolean);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestAfterBindPropsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.afterFlagSet();\n    object.afterFlagSetSuper();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestAfterBindPropsViewModel_ onBind(\n      OnModelBoundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestAfterBindPropsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestAfterBindPropsViewModel_ onUnbind(\n      OnModelUnboundListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestAfterBindPropsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestAfterBindPropsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestAfterBindPropsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestAfterBindPropsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestAfterBindPropsViewModel_, TestAfterBindPropsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestAfterBindPropsView#setFlag(boolean)\n   */\n  public TestAfterBindPropsViewModel_ flag(boolean flag) {\n    onMutation();\n    this.flag_Boolean = flag;\n    return this;\n  }\n\n  public boolean flag() {\n    return flag_Boolean;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestAfterBindPropsSuperView#setFlagSuper(boolean)\n   */\n  public TestAfterBindPropsViewModel_ flagSuper(boolean flagSuper) {\n    onMutation();\n    this.flagSuper_Boolean = flagSuper;\n    return this;\n  }\n\n  public boolean flagSuper() {\n    return flagSuper_Boolean;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestAfterBindPropsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.flag_Boolean = false;\n    this.flagSuper_Boolean = false;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestAfterBindPropsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestAfterBindPropsViewModel_ that = (TestAfterBindPropsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((flag_Boolean != that.flag_Boolean)) {\n      return false;\n    }\n    if ((flagSuper_Boolean != that.flagSuper_Boolean)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (flag_Boolean ? 1 : 0);\n    _result = 31 * _result + (flagSuper_Boolean ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestAfterBindPropsViewModel_{\" +\n        \"flag_Boolean=\" + flag_Boolean +\n        \", flagSuper_Boolean=\" + flagSuper_Boolean +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestCallbackPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestCallbackPropViewModel_ extends EpoxyModel<TestCallbackPropView> implements GeneratedModel<TestCallbackPropView>, TestCallbackPropViewModelBuilder {\n  private OnModelBoundListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener listener_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestCallbackPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestCallbackPropView object) {\n    super.bind(object);\n    object.setListener(listener_OnClickListener);\n  }\n\n  @Override\n  public void bind(final TestCallbackPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestCallbackPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestCallbackPropViewModel_ that = (TestCallbackPropViewModel_) previousModel;\n    super.bind(object);\n\n    if (((listener_OnClickListener == null) != (that.listener_OnClickListener == null))) {\n      object.setListener(listener_OnClickListener);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestCallbackPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestCallbackPropViewModel_ onBind(\n      OnModelBoundListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestCallbackPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.setListener((View.OnClickListener) null);\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestCallbackPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestCallbackPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestCallbackPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestCallbackPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestCallbackPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestCallbackPropViewModel_ listener(\n      @Nullable final OnModelClickListener<TestCallbackPropViewModel_, TestCallbackPropView> listener) {\n    onMutation();\n    if (listener == null) {\n      this.listener_OnClickListener = null;\n    }\n    else {\n      this.listener_OnClickListener = new WrappedEpoxyModelClickListener<>(listener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestCallbackPropView#setListener(View.OnClickListener)\n   */\n  public TestCallbackPropViewModel_ listener(@Nullable View.OnClickListener listener) {\n    onMutation();\n    this.listener_OnClickListener = listener;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener listener() {\n    return listener_OnClickListener;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestCallbackPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.listener_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestCallbackPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestCallbackPropViewModel_ that = (TestCallbackPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((listener_OnClickListener == null) != (that.listener_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (listener_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestCallbackPropViewModel_{\" +\n        \"listener_OnClickListener=\" + listener_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropCallbackPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropCallbackPropViewModel_ extends EpoxyModel<TestFieldPropCallbackPropView> implements GeneratedModel<TestFieldPropCallbackPropView>, TestFieldPropCallbackPropViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropView buildView(ViewGroup parent) {\n    TestFieldPropCallbackPropView v = new TestFieldPropCallbackPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropCallbackPropView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropCallbackPropView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropCallbackPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropCallbackPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropCallbackPropViewModel_ that = (TestFieldPropCallbackPropViewModel_) previousModel;\n    super.bind(object);\n\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropCallbackPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropCallbackPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropCallbackPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropCallbackPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropCallbackPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropCallbackPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropCallbackPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropCallbackPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropCallbackPropViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropCallbackPropViewModel_, TestFieldPropCallbackPropView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropCallbackPropView#value\n   */\n  public TestFieldPropCallbackPropViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropCallbackPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropCallbackPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropCallbackPropViewModel_ that = (TestFieldPropCallbackPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropCallbackPropViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropChildViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\nimport javax.annotation.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropChildViewModel_ extends EpoxyModel<TestFieldPropChildView> implements GeneratedModel<TestFieldPropChildView>, TestFieldPropChildViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData textValue_StringAttributeData =  new StringAttributeData();\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for textValue\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropChildView buildView(ViewGroup parent) {\n    TestFieldPropChildView v = new TestFieldPropChildView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropChildView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropChildView object) {\n    super.bind(object);\n    object.textValue = textValue_StringAttributeData.toString(object.getContext());\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropChildView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropChildViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropChildViewModel_ that = (TestFieldPropChildViewModel_) previousModel;\n    super.bind(object);\n\n    if ((textValue_StringAttributeData != null ? !textValue_StringAttributeData.equals(that.textValue_StringAttributeData) : that.textValue_StringAttributeData != null)) {\n      object.textValue = textValue_StringAttributeData.toString(object.getContext());\n    }\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropChildView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropChildViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropChildView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropChildViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestFieldPropChildView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropChildViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropChildView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropChildViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropChildViewModel_, TestFieldPropChildView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTextValue(Context context) {\n    return textValue_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@NonNull CharSequence textValue) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (textValue == null) {\n      throw new IllegalArgumentException(\"textValue cannot be null\");\n    }\n    textValue_StringAttributeData.setValue(textValue);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValue(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropChildView#textValue\n   */\n  public TestFieldPropChildViewModel_ textValueQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textValue_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropChildViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropChildViewModel_, TestFieldPropChildView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropParentView#value\n   */\n  public TestFieldPropChildViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence p0,\n      @androidx.annotation.Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ id(@androidx.annotation.Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropChildViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.textValue_StringAttributeData =  new StringAttributeData();\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropChildViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropChildViewModel_ that = (TestFieldPropChildViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((textValue_StringAttributeData != null ? !textValue_StringAttributeData.equals(that.textValue_StringAttributeData) : that.textValue_StringAttributeData != null)) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (textValue_StringAttributeData != null ? textValue_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropChildViewModel_{\" +\n        \"textValue_StringAttributeData=\" + textValue_StringAttributeData +\n        \", value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropDoNotHashOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropDoNotHashOptionViewModel_ extends EpoxyModel<TestFieldPropDoNotHashOptionView> implements GeneratedModel<TestFieldPropDoNotHashOptionView>, TestFieldPropDoNotHashOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener value_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionView buildView(ViewGroup parent) {\n    TestFieldPropDoNotHashOptionView v = new TestFieldPropDoNotHashOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropDoNotHashOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropDoNotHashOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropDoNotHashOptionView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropDoNotHashOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropDoNotHashOptionViewModel_ that = (TestFieldPropDoNotHashOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropDoNotHashOptionView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropDoNotHashOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropDoNotHashOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropDoNotHashOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ value(\n      @NonNull final OnModelClickListener<TestFieldPropDoNotHashOptionViewModel_, TestFieldPropDoNotHashOptionView> value) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropDoNotHashOptionView#value\n   */\n  public TestFieldPropDoNotHashOptionViewModel_ value(@NonNull View.OnClickListener value) {\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropDoNotHashOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropDoNotHashOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropDoNotHashOptionViewModel_ that = (TestFieldPropDoNotHashOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((value_OnClickListener == null) != (that.value_OnClickListener == null))) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? 1 : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropDoNotHashOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropGenerateStringOverloadsOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropGenerateStringOverloadsOptionViewModel_ extends EpoxyModel<TestFieldPropGenerateStringOverloadsOptionView> implements GeneratedModel<TestFieldPropGenerateStringOverloadsOptionView>, TestFieldPropGenerateStringOverloadsOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData value_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionView buildView(ViewGroup parent) {\n    TestFieldPropGenerateStringOverloadsOptionView v = new TestFieldPropGenerateStringOverloadsOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropGenerateStringOverloadsOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropGenerateStringOverloadsOptionView object) {\n    super.bind(object);\n    object.value = value_StringAttributeData.toString(object.getContext());\n  }\n\n  @Override\n  public void bind(final TestFieldPropGenerateStringOverloadsOptionView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropGenerateStringOverloadsOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropGenerateStringOverloadsOptionViewModel_ that = (TestFieldPropGenerateStringOverloadsOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      object.value = value_StringAttributeData.toString(object.getContext());\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropGenerateStringOverloadsOptionView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropGenerateStringOverloadsOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropGenerateStringOverloadsOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final TestFieldPropGenerateStringOverloadsOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropGenerateStringOverloadsOptionViewModel_, TestFieldPropGenerateStringOverloadsOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getValue(Context context) {\n    return value_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@NonNull CharSequence value) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    value_StringAttributeData.setValue(value);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ value(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropGenerateStringOverloadsOptionView#value\n   */\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ valueQuantityRes(\n      @PluralsRes int pluralRes, int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ id(@Nullable CharSequence p0,\n      long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropGenerateStringOverloadsOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropGenerateStringOverloadsOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropGenerateStringOverloadsOptionViewModel_ that = (TestFieldPropGenerateStringOverloadsOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_StringAttributeData != null ? value_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropGenerateStringOverloadsOptionViewModel_{\" +\n        \"value_StringAttributeData=\" + value_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropIgnoreRequireHashCodeOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropIgnoreRequireHashCodeOptionViewModel_ extends EpoxyModel<TestFieldPropIgnoreRequireHashCodeOptionView> implements GeneratedModel<TestFieldPropIgnoreRequireHashCodeOptionView>, TestFieldPropIgnoreRequireHashCodeOptionViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private View.OnClickListener value_OnClickListener;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionView buildView(ViewGroup parent) {\n    TestFieldPropIgnoreRequireHashCodeOptionView v = new TestFieldPropIgnoreRequireHashCodeOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropIgnoreRequireHashCodeOptionView object,\n      EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropIgnoreRequireHashCodeOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropIgnoreRequireHashCodeOptionViewModel_ that = (TestFieldPropIgnoreRequireHashCodeOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropIgnoreRequireHashCodeOptionView object,\n      int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth,\n      final TestFieldPropIgnoreRequireHashCodeOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ value(\n      @NonNull final OnModelClickListener<TestFieldPropIgnoreRequireHashCodeOptionViewModel_, TestFieldPropIgnoreRequireHashCodeOptionView> value) {\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropIgnoreRequireHashCodeOptionView#value\n   */\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ value(\n      @NonNull View.OnClickListener value) {\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropIgnoreRequireHashCodeOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_OnClickListener = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropIgnoreRequireHashCodeOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropIgnoreRequireHashCodeOptionViewModel_ that = (TestFieldPropIgnoreRequireHashCodeOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropIgnoreRequireHashCodeOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropModelPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropModelPropViewModel_ extends EpoxyModel<TestFieldPropModelPropView> implements GeneratedModel<TestFieldPropModelPropView>, TestFieldPropModelPropViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private int value_Int = 0;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropModelPropView buildView(ViewGroup parent) {\n    TestFieldPropModelPropView v = new TestFieldPropModelPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropModelPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropModelPropView object) {\n    super.bind(object);\n    object.value = value_Int;\n  }\n\n  @Override\n  public void bind(final TestFieldPropModelPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropModelPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropModelPropViewModel_ that = (TestFieldPropModelPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_Int != that.value_Int)) {\n      object.value = value_Int;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropModelPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropModelPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropModelPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropModelPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropModelPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropModelPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropModelPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropModelPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropModelPropViewModel_, TestFieldPropModelPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestFieldPropModelPropView#value\n   */\n  public TestFieldPropModelPropViewModel_ value(int value) {\n    onMutation();\n    this.value_Int = value;\n    return this;\n  }\n\n  public int value() {\n    return value_Int;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropModelPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_Int = 0;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropModelPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropModelPropViewModel_ that = (TestFieldPropModelPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_Int != that.value_Int)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + value_Int;\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropModelPropViewModel_{\" +\n        \"value_Int=\" + value_Int +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropNullOnRecycleOptionViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport javax.annotation.Nullable;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropNullOnRecycleOptionViewModel_ extends EpoxyModel<TestFieldPropNullOnRecycleOptionView> implements GeneratedModel<TestFieldPropNullOnRecycleOptionView>, TestFieldPropNullOnRecycleOptionViewModelBuilder {\n  private OnModelBoundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  @Nullable\n  private View.OnClickListener value_OnClickListener = (View.OnClickListener) null;\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionView buildView(ViewGroup parent) {\n    TestFieldPropNullOnRecycleOptionView v = new TestFieldPropNullOnRecycleOptionView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder,\n      final TestFieldPropNullOnRecycleOptionView object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropNullOnRecycleOptionView object) {\n    super.bind(object);\n    object.value = value_OnClickListener;\n  }\n\n  @Override\n  public void bind(final TestFieldPropNullOnRecycleOptionView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropNullOnRecycleOptionViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropNullOnRecycleOptionViewModel_ that = (TestFieldPropNullOnRecycleOptionViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      object.value = value_OnClickListener;\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropNullOnRecycleOptionView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropNullOnRecycleOptionView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n    object.value = (View.OnClickListener) null;\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropNullOnRecycleOptionView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropNullOnRecycleOptionView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ value(\n      @Nullable final OnModelClickListener<TestFieldPropNullOnRecycleOptionViewModel_, TestFieldPropNullOnRecycleOptionView> value) {\n    onMutation();\n    if (value == null) {\n      this.value_OnClickListener = null;\n    }\n    else {\n      this.value_OnClickListener = new WrappedEpoxyModelClickListener<>(value);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (View.OnClickListener) null\n   *\n   * @see TestFieldPropNullOnRecycleOptionView#value\n   */\n  public TestFieldPropNullOnRecycleOptionViewModel_ value(@Nullable View.OnClickListener value) {\n    onMutation();\n    this.value_OnClickListener = value;\n    return this;\n  }\n\n  @Nullable\n  public View.OnClickListener value() {\n    return value_OnClickListener;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(@androidx.annotation.Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence p0,\n      @androidx.annotation.Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ id(\n      @androidx.annotation.Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ spanSizeOverride(\n      @androidx.annotation.Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropNullOnRecycleOptionViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.value_OnClickListener = (View.OnClickListener) null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropNullOnRecycleOptionViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropNullOnRecycleOptionViewModel_ that = (TestFieldPropNullOnRecycleOptionViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_OnClickListener != null ? !value_OnClickListener.equals(that.value_OnClickListener) : that.value_OnClickListener != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_OnClickListener != null ? value_OnClickListener.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropNullOnRecycleOptionViewModel_{\" +\n        \"value_OnClickListener=\" + value_OnClickListener +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestFieldPropTextPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.lang.UnsupportedOperationException;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestFieldPropTextPropViewModel_ extends EpoxyModel<TestFieldPropTextPropView> implements GeneratedModel<TestFieldPropTextPropView>, TestFieldPropTextPropViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData value_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for value\");\n    }\n  }\n\n  @Override\n  protected int getViewType() {\n    return 0;\n  }\n\n  @Override\n  public TestFieldPropTextPropView buildView(ViewGroup parent) {\n    TestFieldPropTextPropView v = new TestFieldPropTextPropView(parent.getContext());\n    v.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT));\n    return v;\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestFieldPropTextPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestFieldPropTextPropView object) {\n    super.bind(object);\n    object.value = value_StringAttributeData.toString(object.getContext());\n  }\n\n  @Override\n  public void bind(final TestFieldPropTextPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestFieldPropTextPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestFieldPropTextPropViewModel_ that = (TestFieldPropTextPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      object.value = value_StringAttributeData.toString(object.getContext());\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestFieldPropTextPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n    object.call();\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropTextPropViewModel_ onBind(\n      OnModelBoundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestFieldPropTextPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestFieldPropTextPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestFieldPropTextPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropTextPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestFieldPropTextPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestFieldPropTextPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestFieldPropTextPropViewModel_, TestFieldPropTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getValue(Context context) {\n    return value_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@NonNull CharSequence value) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (value == null) {\n      throw new IllegalArgumentException(\"value cannot be null\");\n    }\n    value_StringAttributeData.setValue(value);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ value(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestFieldPropTextPropView#value\n   */\n  public TestFieldPropTextPropViewModel_ valueQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    value_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ layout(@LayoutRes int p0) {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported with programmatic views.\");\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    throw new UnsupportedOperationException(\"Layout resources are unsupported for views created programmatically.\");\n  }\n\n  @Override\n  public TestFieldPropTextPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.value_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestFieldPropTextPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestFieldPropTextPropViewModel_ that = (TestFieldPropTextPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((value_StringAttributeData != null ? !value_StringAttributeData.equals(that.value_StringAttributeData) : that.value_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (value_StringAttributeData != null ? value_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestFieldPropTextPropViewModel_{\" +\n        \"value_StringAttributeData=\" + value_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestManyTypesViewModelBuilder.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.String;\nimport java.util.List;\nimport java.util.Map;\nimport kotlin.jvm.functions.Function3;\n\n@EpoxyBuildScope\npublic interface TestManyTypesViewModelBuilder {\n  TestManyTypesViewModelBuilder onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener);\n\n  TestManyTypesViewModelBuilder stringValue(@NonNull String stringValue);\n\n  TestManyTypesViewModelBuilder nullableStringValue(@Nullable String nullableStringValue);\n\n  TestManyTypesViewModelBuilder function(\n      @NonNull Function3<? super Integer, ? super Integer, ? super Integer, Integer> function);\n\n  TestManyTypesViewModelBuilder intValue(int intValue);\n\n  TestManyTypesViewModelBuilder intValueWithAnnotation(@StringRes int intValueWithAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation);\n\n  TestManyTypesViewModelBuilder intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation);\n\n  TestManyTypesViewModelBuilder intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations);\n\n  TestManyTypesViewModelBuilder integerValue(@NonNull Integer integerValue);\n\n  TestManyTypesViewModelBuilder boolValue(boolean boolValue);\n\n  TestManyTypesViewModelBuilder models(@NonNull List<? extends EpoxyModel<?>> models);\n\n  TestManyTypesViewModelBuilder booleanValue(@NonNull Boolean booleanValue);\n\n  TestManyTypesViewModelBuilder arrayValue(@NonNull String[] arrayValue);\n\n  TestManyTypesViewModelBuilder listValue(@NonNull List<String> listValue);\n\n  TestManyTypesViewModelBuilder mapValue(@NonNull Map<Integer, Integer> mapValue);\n\n  TestManyTypesViewModelBuilder clickListener(\n      @NonNull final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener);\n\n  TestManyTypesViewModelBuilder clickListener(@NonNull View.OnClickListener clickListener);\n\n  TestManyTypesViewModelBuilder title(@Nullable CharSequence title);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes);\n\n  TestManyTypesViewModelBuilder title(@StringRes int stringRes, Object... formatArgs);\n\n  TestManyTypesViewModelBuilder titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs);\n\n  TestManyTypesViewModelBuilder id(long p0);\n\n  TestManyTypesViewModelBuilder id(@Nullable Number... p0);\n\n  TestManyTypesViewModelBuilder id(long p0, long p1);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0, @Nullable CharSequence... p1);\n\n  TestManyTypesViewModelBuilder id(@Nullable CharSequence p0, long p1);\n\n  TestManyTypesViewModelBuilder layout(@LayoutRes int p0);\n\n  TestManyTypesViewModelBuilder spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0);\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestManyTypesViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.annotation.Dimension;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.Boolean;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Integer;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport java.util.Map;\nimport kotlin.jvm.functions.Function3;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestManyTypesViewModel_ extends EpoxyModel<TestManyTypesView> implements GeneratedModel<TestManyTypesView>, TestManyTypesViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(17);\n\n  private OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  @NonNull\n  private String stringValue_String;\n\n  @Nullable\n  private String nullableStringValue_String = (String) null;\n\n  /**\n   * Bitset index: 2\n   */\n  @NonNull\n  private Function3<? super Integer, ? super Integer, ? super Integer, Integer> function_Function3;\n\n  private int intValue_Int = 0;\n\n  @StringRes\n  private int intValueWithAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  private int intValueWithRangeAnnotation_Int = 0;\n\n  @Dimension(\n      unit = 0\n  )\n  private int intValueWithDimenTypeAnnotation_Int = 0;\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  private int intWithMultipleAnnotations_Int = 0;\n\n  /**\n   * Bitset index: 8\n   */\n  @NonNull\n  private Integer integerValue_Integer;\n\n  private boolean boolValue_Boolean = false;\n\n  /**\n   * Bitset index: 10\n   */\n  @NonNull\n  private List<? extends EpoxyModel<?>> models_List;\n\n  /**\n   * Bitset index: 11\n   */\n  @NonNull\n  private Boolean booleanValue_Boolean;\n\n  /**\n   * Bitset index: 12\n   */\n  @NonNull\n  private String[] arrayValue_StringArray;\n\n  /**\n   * Bitset index: 13\n   */\n  @NonNull\n  private List<String> listValue_List;\n\n  /**\n   * Bitset index: 14\n   */\n  @NonNull\n  private Map<Integer, Integer> mapValue_Map;\n\n  /**\n   * Bitset index: 15\n   */\n  @NonNull\n  private View.OnClickListener clickListener_OnClickListener;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(14)) {\n    \tthrow new IllegalStateException(\"A value is required for setMapValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(12)) {\n    \tthrow new IllegalStateException(\"A value is required for setArrayValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(15)) {\n    \tthrow new IllegalStateException(\"A value is required for setClickListener\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(11)) {\n    \tthrow new IllegalStateException(\"A value is required for setBooleanValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setStringValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(8)) {\n    \tthrow new IllegalStateException(\"A value is required for setIntegerValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(13)) {\n    \tthrow new IllegalStateException(\"A value is required for setListValue\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setFunction\");\n    }\n    if (!assignedAttributes_epoxyGeneratedModel.get(10)) {\n    \tthrow new IllegalStateException(\"A value is required for setModels\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestManyTypesView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object) {\n    super.bind(object);\n    object.setMapValue(mapValue_Map);\n    object.setArrayValue(arrayValue_StringArray);\n    object.setClickListener(clickListener_OnClickListener);\n    object.setBooleanValue(booleanValue_Boolean);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    object.setStringValue(stringValue_String);\n    object.setNullableStringValue(nullableStringValue_String);\n    object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    object.setIntegerValue(integerValue_Integer);\n    object.setListValue(listValue_List);\n    object.setIntValue(intValue_Int);\n    object.setFunction(function_Function3);\n    object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    object.setBoolValue(boolValue_Boolean);\n    object.setModels(models_List);\n  }\n\n  @Override\n  public void bind(final TestManyTypesView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestManyTypesViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) previousModel;\n    super.bind(object);\n\n    if ((mapValue_Map != null ? !mapValue_Map.equals(that.mapValue_Map) : that.mapValue_Map != null)) {\n      object.setMapValue(mapValue_Map);\n    }\n\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      object.setArrayValue(arrayValue_StringArray);\n    }\n\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      object.setClickListener(clickListener_OnClickListener);\n    }\n\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      object.setBooleanValue(booleanValue_Boolean);\n    }\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      object.setStringValue(stringValue_String);\n    }\n\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      object.setNullableStringValue(nullableStringValue_String);\n    }\n\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      object.setIntValueWithAnnotation(intValueWithAnnotation_Int);\n    }\n\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      object.setIntValueWithDimenTypeAnnotation(intValueWithDimenTypeAnnotation_Int);\n    }\n\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      object.setIntWithMultipleAnnotations(intWithMultipleAnnotations_Int);\n    }\n\n    if ((integerValue_Integer != null ? !integerValue_Integer.equals(that.integerValue_Integer) : that.integerValue_Integer != null)) {\n      object.setIntegerValue(integerValue_Integer);\n    }\n\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      object.setListValue(listValue_List);\n    }\n\n    if ((intValue_Int != that.intValue_Int)) {\n      object.setIntValue(intValue_Int);\n    }\n\n    if (((function_Function3 == null) != (that.function_Function3 == null))) {\n      object.setFunction(function_Function3);\n    }\n\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      object.setIntValueWithRangeAnnotation(intValueWithRangeAnnotation_Int);\n    }\n\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      object.setBoolValue(boolValue_Boolean);\n    }\n\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      object.setModels(models_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestManyTypesView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onBind(\n      OnModelBoundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestManyTypesView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestManyTypesViewModel_ onUnbind(\n      OnModelUnboundListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestManyTypesView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestManyTypesView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestManyTypesViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestManyTypesViewModel_, TestManyTypesView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setStringValue(String)\n   */\n  public TestManyTypesViewModel_ stringValue(@NonNull String stringValue) {\n    if (stringValue == null) {\n      throw new IllegalArgumentException(\"stringValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    onMutation();\n    this.stringValue_String = stringValue;\n    return this;\n  }\n\n  @NonNull\n  public String stringValue() {\n    return stringValue_String;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (String) null\n   *\n   * @see TestManyTypesView#setNullableStringValue(String)\n   */\n  public TestManyTypesViewModel_ nullableStringValue(@Nullable String nullableStringValue) {\n    onMutation();\n    this.nullableStringValue_String = nullableStringValue;\n    return this;\n  }\n\n  @Nullable\n  public String nullableStringValue() {\n    return nullableStringValue_String;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setFunction(Function3<? super Integer, ? super Integer, ? super Integer, Integer>)\n   */\n  public TestManyTypesViewModel_ function(\n      @NonNull Function3<? super Integer, ? super Integer, ? super Integer, Integer> function) {\n    if (function == null) {\n      throw new IllegalArgumentException(\"function cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    onMutation();\n    this.function_Function3 = function;\n    return this;\n  }\n\n  @NonNull\n  public Function3<? super Integer, ? super Integer, ? super Integer, Integer> function() {\n    return function_Function3;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValue(int)\n   */\n  public TestManyTypesViewModel_ intValue(int intValue) {\n    onMutation();\n    this.intValue_Int = intValue;\n    return this;\n  }\n\n  public int intValue() {\n    return intValue_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithAnnotation(@StringRes int intValueWithAnnotation) {\n    onMutation();\n    this.intValueWithAnnotation_Int = intValueWithAnnotation;\n    return this;\n  }\n\n  @StringRes\n  public int intValueWithAnnotation() {\n    return intValueWithAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithRangeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithRangeAnnotation(\n      @IntRange(from = 0, to = 200) int intValueWithRangeAnnotation) {\n    onMutation();\n    this.intValueWithRangeAnnotation_Int = intValueWithRangeAnnotation;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  public int intValueWithRangeAnnotation() {\n    return intValueWithRangeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntValueWithDimenTypeAnnotation(int)\n   */\n  public TestManyTypesViewModel_ intValueWithDimenTypeAnnotation(\n      @Dimension(unit = 0) int intValueWithDimenTypeAnnotation) {\n    onMutation();\n    this.intValueWithDimenTypeAnnotation_Int = intValueWithDimenTypeAnnotation;\n    return this;\n  }\n\n  @Dimension(\n      unit = 0\n  )\n  public int intValueWithDimenTypeAnnotation() {\n    return intValueWithDimenTypeAnnotation_Int;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is 0\n   *\n   * @see TestManyTypesView#setIntWithMultipleAnnotations(int)\n   */\n  public TestManyTypesViewModel_ intWithMultipleAnnotations(\n      @IntRange(from = 0, to = 200) @Dimension(unit = 0) int intWithMultipleAnnotations) {\n    onMutation();\n    this.intWithMultipleAnnotations_Int = intWithMultipleAnnotations;\n    return this;\n  }\n\n  @IntRange(\n      from = 0,\n      to = 200\n  )\n  @Dimension(\n      unit = 0\n  )\n  public int intWithMultipleAnnotations() {\n    return intWithMultipleAnnotations_Int;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setIntegerValue(Integer)\n   */\n  public TestManyTypesViewModel_ integerValue(@NonNull Integer integerValue) {\n    if (integerValue == null) {\n      throw new IllegalArgumentException(\"integerValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(8);\n    onMutation();\n    this.integerValue_Integer = integerValue;\n    return this;\n  }\n\n  @NonNull\n  public Integer integerValue() {\n    return integerValue_Integer;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is false\n   *\n   * @see TestManyTypesView#setBoolValue(boolean)\n   */\n  public TestManyTypesViewModel_ boolValue(boolean boolValue) {\n    onMutation();\n    this.boolValue_Boolean = boolValue;\n    return this;\n  }\n\n  public boolean boolValue() {\n    return boolValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setModels(List<? extends EpoxyModel<?>>)\n   */\n  public TestManyTypesViewModel_ models(@NonNull List<? extends EpoxyModel<?>> models) {\n    if (models == null) {\n      throw new IllegalArgumentException(\"models cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(10);\n    onMutation();\n    this.models_List = models;\n    return this;\n  }\n\n  @NonNull\n  public List<? extends EpoxyModel<?>> models() {\n    return models_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setBooleanValue(Boolean)\n   */\n  public TestManyTypesViewModel_ booleanValue(@NonNull Boolean booleanValue) {\n    if (booleanValue == null) {\n      throw new IllegalArgumentException(\"booleanValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(11);\n    onMutation();\n    this.booleanValue_Boolean = booleanValue;\n    return this;\n  }\n\n  @NonNull\n  public Boolean booleanValue() {\n    return booleanValue_Boolean;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setArrayValue(String[])\n   */\n  public TestManyTypesViewModel_ arrayValue(@NonNull String[] arrayValue) {\n    if (arrayValue == null) {\n      throw new IllegalArgumentException(\"arrayValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(12);\n    onMutation();\n    this.arrayValue_StringArray = arrayValue;\n    return this;\n  }\n\n  @NonNull\n  public String[] arrayValue() {\n    return arrayValue_StringArray;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setListValue(List<String>)\n   */\n  public TestManyTypesViewModel_ listValue(@NonNull List<String> listValue) {\n    if (listValue == null) {\n      throw new IllegalArgumentException(\"listValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(13);\n    onMutation();\n    this.listValue_List = listValue;\n    return this;\n  }\n\n  @NonNull\n  public List<String> listValue() {\n    return listValue_List;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setMapValue(Map<Integer, Integer>)\n   */\n  public TestManyTypesViewModel_ mapValue(@NonNull Map<Integer, Integer> mapValue) {\n    if (mapValue == null) {\n      throw new IllegalArgumentException(\"mapValue cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(14);\n    onMutation();\n    this.mapValue_Map = mapValue;\n    return this;\n  }\n\n  @NonNull\n  public Map<Integer, Integer> mapValue() {\n    return mapValue_Map;\n  }\n\n  /**\n   * Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set\n   */\n  public TestManyTypesViewModel_ clickListener(\n      @NonNull final OnModelClickListener<TestManyTypesViewModel_, TestManyTypesView> clickListener) {\n    assignedAttributes_epoxyGeneratedModel.set(15);\n    onMutation();\n    if (clickListener == null) {\n      this.clickListener_OnClickListener = null;\n    }\n    else {\n      this.clickListener_OnClickListener = new WrappedEpoxyModelClickListener<>(clickListener);\n    }\n    return this;\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestManyTypesView#setClickListener(View.OnClickListener)\n   */\n  public TestManyTypesViewModel_ clickListener(@NonNull View.OnClickListener clickListener) {\n    if (clickListener == null) {\n      throw new IllegalArgumentException(\"clickListener cannot be null\");\n    }\n    assignedAttributes_epoxyGeneratedModel.set(15);\n    onMutation();\n    this.clickListener_OnClickListener = clickListener;\n    return this;\n  }\n\n  @NonNull\n  public View.OnClickListener clickListener() {\n    return clickListener_OnClickListener;\n  }\n\n  @Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestManyTypesView#setTitle(CharSequence)\n   */\n  public TestManyTypesViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestManyTypesViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.stringValue_String = null;\n    this.nullableStringValue_String = (String) null;\n    this.function_Function3 = null;\n    this.intValue_Int = 0;\n    this.intValueWithAnnotation_Int = 0;\n    this.intValueWithRangeAnnotation_Int = 0;\n    this.intValueWithDimenTypeAnnotation_Int = 0;\n    this.intWithMultipleAnnotations_Int = 0;\n    this.integerValue_Integer = null;\n    this.boolValue_Boolean = false;\n    this.models_List = null;\n    this.booleanValue_Boolean = null;\n    this.arrayValue_StringArray = null;\n    this.listValue_List = null;\n    this.mapValue_Map = null;\n    this.clickListener_OnClickListener = null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestManyTypesViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestManyTypesViewModel_ that = (TestManyTypesViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((stringValue_String != null ? !stringValue_String.equals(that.stringValue_String) : that.stringValue_String != null)) {\n      return false;\n    }\n    if ((nullableStringValue_String != null ? !nullableStringValue_String.equals(that.nullableStringValue_String) : that.nullableStringValue_String != null)) {\n      return false;\n    }\n    if (((function_Function3 == null) != (that.function_Function3 == null))) {\n      return false;\n    }\n    if ((intValue_Int != that.intValue_Int)) {\n      return false;\n    }\n    if ((intValueWithAnnotation_Int != that.intValueWithAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithRangeAnnotation_Int != that.intValueWithRangeAnnotation_Int)) {\n      return false;\n    }\n    if ((intValueWithDimenTypeAnnotation_Int != that.intValueWithDimenTypeAnnotation_Int)) {\n      return false;\n    }\n    if ((intWithMultipleAnnotations_Int != that.intWithMultipleAnnotations_Int)) {\n      return false;\n    }\n    if ((integerValue_Integer != null ? !integerValue_Integer.equals(that.integerValue_Integer) : that.integerValue_Integer != null)) {\n      return false;\n    }\n    if ((boolValue_Boolean != that.boolValue_Boolean)) {\n      return false;\n    }\n    if ((models_List != null ? !models_List.equals(that.models_List) : that.models_List != null)) {\n      return false;\n    }\n    if ((booleanValue_Boolean != null ? !booleanValue_Boolean.equals(that.booleanValue_Boolean) : that.booleanValue_Boolean != null)) {\n      return false;\n    }\n    if (!Arrays.equals(arrayValue_StringArray, that.arrayValue_StringArray)) {\n      return false;\n    }\n    if ((listValue_List != null ? !listValue_List.equals(that.listValue_List) : that.listValue_List != null)) {\n      return false;\n    }\n    if ((mapValue_Map != null ? !mapValue_Map.equals(that.mapValue_Map) : that.mapValue_Map != null)) {\n      return false;\n    }\n    if (((clickListener_OnClickListener == null) != (that.clickListener_OnClickListener == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (stringValue_String != null ? stringValue_String.hashCode() : 0);\n    _result = 31 * _result + (nullableStringValue_String != null ? nullableStringValue_String.hashCode() : 0);\n    _result = 31 * _result + (function_Function3 != null ? 1 : 0);\n    _result = 31 * _result + intValue_Int;\n    _result = 31 * _result + intValueWithAnnotation_Int;\n    _result = 31 * _result + intValueWithRangeAnnotation_Int;\n    _result = 31 * _result + intValueWithDimenTypeAnnotation_Int;\n    _result = 31 * _result + intWithMultipleAnnotations_Int;\n    _result = 31 * _result + (integerValue_Integer != null ? integerValue_Integer.hashCode() : 0);\n    _result = 31 * _result + (boolValue_Boolean ? 1 : 0);\n    _result = 31 * _result + (models_List != null ? models_List.hashCode() : 0);\n    _result = 31 * _result + (booleanValue_Boolean != null ? booleanValue_Boolean.hashCode() : 0);\n    _result = 31 * _result + Arrays.hashCode(arrayValue_StringArray);\n    _result = 31 * _result + (listValue_List != null ? listValue_List.hashCode() : 0);\n    _result = 31 * _result + (mapValue_Map != null ? mapValue_Map.hashCode() : 0);\n    _result = 31 * _result + (clickListener_OnClickListener != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestManyTypesViewModel_{\" +\n        \"stringValue_String=\" + stringValue_String +\n        \", nullableStringValue_String=\" + nullableStringValue_String +\n        \", intValue_Int=\" + intValue_Int +\n        \", intValueWithAnnotation_Int=\" + intValueWithAnnotation_Int +\n        \", intValueWithRangeAnnotation_Int=\" + intValueWithRangeAnnotation_Int +\n        \", intValueWithDimenTypeAnnotation_Int=\" + intValueWithDimenTypeAnnotation_Int +\n        \", intWithMultipleAnnotations_Int=\" + intWithMultipleAnnotations_Int +\n        \", integerValue_Integer=\" + integerValue_Integer +\n        \", boolValue_Boolean=\" + boolValue_Boolean +\n        \", models_List=\" + models_List +\n        \", booleanValue_Boolean=\" + booleanValue_Boolean +\n        \", arrayValue_StringArray=\" + arrayValue_StringArray +\n        \", listValue_List=\" + listValue_List +\n        \", mapValue_Map=\" + mapValue_Map +\n        \", clickListener_OnClickListener=\" + clickListener_OnClickListener +\n        \", title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestNullStringOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestNullStringOverloadsViewModel_ extends EpoxyModel<TestNullStringOverloadsView> implements GeneratedModel<TestNullStringOverloadsView>, TestNullStringOverloadsViewModelBuilder {\n  private OnModelBoundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestNullStringOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestNullStringOverloadsView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TestNullStringOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestNullStringOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestNullStringOverloadsViewModel_ that = (TestNullStringOverloadsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestNullStringOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestNullStringOverloadsViewModel_ onBind(\n      OnModelBoundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestNullStringOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestNullStringOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState,\n      final TestNullStringOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestNullStringOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestNullStringOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestNullStringOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestNullStringOverloadsViewModel_, TestNullStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Nullable\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@Nullable CharSequence title) {\n    onMutation();\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is (CharSequence) null\n   *\n   * @see TestNullStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestNullStringOverloadsViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence p0,\n      @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestNullStringOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    this.title_StringAttributeData =  new StringAttributeData((CharSequence) null);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestNullStringOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestNullStringOverloadsViewModel_ that = (TestNullStringOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestNullStringOverloadsViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestStringOverloadsViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestStringOverloadsViewModel_ extends EpoxyModel<TestStringOverloadsView> implements GeneratedModel<TestStringOverloadsView>, TestStringOverloadsViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(3);\n\n  private OnModelBoundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  /**\n   * Bitset index: 1\n   */\n  @Nullable\n  private List<CharSequence> title_List = (List<CharSequence>) null;\n\n  /**\n   * Bitset index: 2\n   */\n  private StringAttributeData titleViaValueShortcut_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(2)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitleViaValueShortcut\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestStringOverloadsView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestStringOverloadsView object) {\n    super.bind(object);\n    object.setTitleViaValueShortcut(titleViaValueShortcut_StringAttributeData.toString(object.getContext()));\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitle(title_List);\n    }\n    else {\n      object.setTitle(title_List);\n    }\n  }\n\n  @Override\n  public void bind(final TestStringOverloadsView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestStringOverloadsViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestStringOverloadsViewModel_ that = (TestStringOverloadsViewModel_) previousModel;\n    super.bind(object);\n\n    if ((titleViaValueShortcut_StringAttributeData != null ? !titleViaValueShortcut_StringAttributeData.equals(that.titleViaValueShortcut_StringAttributeData) : that.titleViaValueShortcut_StringAttributeData != null)) {\n      object.setTitleViaValueShortcut(titleViaValueShortcut_StringAttributeData.toString(object.getContext()));\n    }\n\n    if (assignedAttributes_epoxyGeneratedModel.get(0)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(0) || (title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n        object.setTitle(title_StringAttributeData.toString(object.getContext()));\n      }\n    }\n    else if (assignedAttributes_epoxyGeneratedModel.get(1)) {\n      if (!that.assignedAttributes_epoxyGeneratedModel.get(1) || (title_List != null ? !title_List.equals(that.title_List) : that.title_List != null)) {\n        object.setTitle(title_List);\n      }\n    }\n    // A value was not set so we should use the default value, but we only need to set it if the previous model had a custom value set.\n    else if (that.assignedAttributes_epoxyGeneratedModel.get(0) || that.assignedAttributes_epoxyGeneratedModel.get(1)) {\n      object.setTitle(title_List);\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestStringOverloadsView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestStringOverloadsViewModel_ onBind(\n      OnModelBoundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestStringOverloadsView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestStringOverloadsViewModel_ onUnbind(\n      OnModelUnboundListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestStringOverloadsView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestStringOverloadsViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestStringOverloadsView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestStringOverloadsViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestStringOverloadsViewModel_, TestStringOverloadsView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence titleStringAttributeData(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitle(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  /**\n   * <i>Optional</i>: Default value is (List<CharSequence>) null\n   *\n   * @see TestStringOverloadsView#setTitle(List<CharSequence>)\n   */\n  public TestStringOverloadsViewModel_ title(@Nullable List<CharSequence> title) {\n    assignedAttributes_epoxyGeneratedModel.set(1);\n    assignedAttributes_epoxyGeneratedModel.clear(0);\n    this.title_StringAttributeData =  new StringAttributeData();\n    onMutation();\n    this.title_List = title;\n    return this;\n  }\n\n  @Nullable\n  public List<CharSequence> titleList() {\n    return title_List;\n  }\n\n  public CharSequence getTitleViaValueShortcut(Context context) {\n    return titleViaValueShortcut_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(\n      @NonNull CharSequence titleViaValueShortcut) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    if (titleViaValueShortcut == null) {\n      throw new IllegalArgumentException(\"titleViaValueShortcut cannot be null\");\n    }\n    titleViaValueShortcut_StringAttributeData.setValue(titleViaValueShortcut);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcut(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestStringOverloadsView#setTitleViaValueShortcut(CharSequence)\n   */\n  public TestStringOverloadsViewModel_ titleViaValueShortcutQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(2);\n    titleViaValueShortcut_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestStringOverloadsViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    this.title_List = (List<CharSequence>) null;\n    this.titleViaValueShortcut_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestStringOverloadsViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestStringOverloadsViewModel_ that = (TestStringOverloadsViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    if ((title_List != null ? !title_List.equals(that.title_List) : that.title_List != null)) {\n      return false;\n    }\n    if ((titleViaValueShortcut_StringAttributeData != null ? !titleViaValueShortcut_StringAttributeData.equals(that.titleViaValueShortcut_StringAttributeData) : that.titleViaValueShortcut_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (title_List != null ? title_List.hashCode() : 0);\n    _result = 31 * _result + (titleViaValueShortcut_StringAttributeData != null ? titleViaValueShortcut_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestStringOverloadsViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \", title_List=\" + title_List +\n        \", titleViaValueShortcut_StringAttributeData=\" + titleViaValueShortcut_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TestTextPropViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TestTextPropViewModel_ extends EpoxyModel<TestTextPropView> implements GeneratedModel<TestTextPropView>, TestTextPropViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);\n\n  private OnModelBoundListener<TestTextPropViewModel_, TestTextPropView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TestTextPropViewModel_, TestTextPropView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TestTextPropViewModel_, TestTextPropView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TestTextPropViewModel_, TestTextPropView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData title_StringAttributeData =  new StringAttributeData();\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for setTitle\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TestTextPropView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TestTextPropView object) {\n    super.bind(object);\n    object.setTitle(title_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TestTextPropView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TestTextPropViewModel_)) {\n      bind(object);\n      return;\n    }\n    TestTextPropViewModel_ that = (TestTextPropViewModel_) previousModel;\n    super.bind(object);\n\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      object.setTitle(title_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TestTextPropView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestTextPropViewModel_ onBind(\n      OnModelBoundListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TestTextPropView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TestTextPropViewModel_ onUnbind(\n      OnModelUnboundListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TestTextPropView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestTextPropViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TestTextPropView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TestTextPropViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TestTextPropViewModel_, TestTextPropView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTitle(Context context) {\n    return title_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@NonNull CharSequence title) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (title == null) {\n      throw new IllegalArgumentException(\"title cannot be null\");\n    }\n    title_StringAttributeData.setValue(title);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ title(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TestTextPropView#setTitle(CharSequence)\n   */\n  public TestTextPropViewModel_ titleQuantityRes(@PluralsRes int pluralRes, int quantity,\n      Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    title_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TestTextPropViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TestTextPropViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.title_StringAttributeData =  new StringAttributeData();\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TestTextPropViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TestTextPropViewModel_ that = (TestTextPropViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((title_StringAttributeData != null ? !title_StringAttributeData.equals(that.title_StringAttributeData) : that.title_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (title_StringAttributeData != null ? title_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestTextPropViewModel_{\" +\n        \"title_StringAttributeData=\" + title_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/ksp/TextPropDefaultViewModel_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.content.Context;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport java.lang.CharSequence;\nimport java.lang.IllegalArgumentException;\nimport java.lang.IllegalStateException;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\nimport java.util.BitSet;\n\n/**\n * Generated file. Do not modify!\n */\npublic class TextPropDefaultViewModel_ extends EpoxyModel<TextPropDefaultView> implements GeneratedModel<TextPropDefaultView>, TextPropDefaultViewModelBuilder {\n  private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(2);\n\n  private OnModelBoundListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  /**\n   * Bitset index: 0\n   */\n  private StringAttributeData textWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n\n  private StringAttributeData nullableTextWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n    if (!assignedAttributes_epoxyGeneratedModel.get(0)) {\n    \tthrow new IllegalStateException(\"A value is required for textWithDefault\");\n    }\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final TextPropDefaultView object,\n      final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void bind(final TextPropDefaultView object) {\n    super.bind(object);\n    object.textWithDefault(textWithDefault_StringAttributeData.toString(object.getContext()));\n    object.nullableTextWithDefault(nullableTextWithDefault_StringAttributeData.toString(object.getContext()));\n  }\n\n  @Override\n  public void bind(final TextPropDefaultView object, EpoxyModel previousModel) {\n    if (!(previousModel instanceof TextPropDefaultViewModel_)) {\n      bind(object);\n      return;\n    }\n    TextPropDefaultViewModel_ that = (TextPropDefaultViewModel_) previousModel;\n    super.bind(object);\n\n    if ((textWithDefault_StringAttributeData != null ? !textWithDefault_StringAttributeData.equals(that.textWithDefault_StringAttributeData) : that.textWithDefault_StringAttributeData != null)) {\n      object.textWithDefault(textWithDefault_StringAttributeData.toString(object.getContext()));\n    }\n\n    if ((nullableTextWithDefault_StringAttributeData != null ? !nullableTextWithDefault_StringAttributeData.equals(that.nullableTextWithDefault_StringAttributeData) : that.nullableTextWithDefault_StringAttributeData != null)) {\n      object.nullableTextWithDefault(nullableTextWithDefault_StringAttributeData.toString(object.getContext()));\n    }\n  }\n\n  @Override\n  public void handlePostBind(final TextPropDefaultView object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropDefaultViewModel_ onBind(\n      OnModelBoundListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(TextPropDefaultView object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public TextPropDefaultViewModel_ onUnbind(\n      OnModelUnboundListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final TextPropDefaultView object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropDefaultViewModel_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final TextPropDefaultView object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public TextPropDefaultViewModel_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<TextPropDefaultViewModel_, TextPropDefaultView> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public CharSequence getTextWithDefault(Context context) {\n    return textWithDefault_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@NonNull CharSequence textWithDefault) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    if (textWithDefault == null) {\n      throw new IllegalArgumentException(\"textWithDefault cannot be null\");\n    }\n    textWithDefault_StringAttributeData.setValue(textWithDefault);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@StringRes int stringRes) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefault(@StringRes int stringRes, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * Throws if a value <= 0 is set.\n   * <p>\n   * <i>Required.</i>\n   *\n   * @see TextPropDefaultView#textWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ textWithDefaultQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    assignedAttributes_epoxyGeneratedModel.set(0);\n    textWithDefault_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Nullable\n  public CharSequence getNullableTextWithDefault(Context context) {\n    return nullableTextWithDefault_StringAttributeData.toString(context);\n  }\n\n  /**\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(\n      @Nullable CharSequence nullableTextWithDefault) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(nullableTextWithDefault);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(@StringRes int stringRes) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(stringRes);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefault(@StringRes int stringRes,\n      Object... formatArgs) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(stringRes, formatArgs);\n    return this;\n  }\n\n  /**\n   * If a value of 0 is set then this attribute will revert to its default value.\n   * <p>\n   * <i>Optional</i>: Default value is R.string.string_resource_value\n   *\n   * @see TextPropDefaultView#nullableTextWithDefault(CharSequence)\n   */\n  public TextPropDefaultViewModel_ nullableTextWithDefaultQuantityRes(@PluralsRes int pluralRes,\n      int quantity, Object... formatArgs) {\n    onMutation();\n    nullableTextWithDefault_StringAttributeData.setValue(pluralRes, quantity, formatArgs);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  @LayoutRes\n  protected int getDefaultLayout() {\n    return 1;\n  }\n\n  @Override\n  public TextPropDefaultViewModel_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    assignedAttributes_epoxyGeneratedModel.clear();\n    this.textWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n    this.nullableTextWithDefault_StringAttributeData =  new StringAttributeData(R.string.string_resource_value);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof TextPropDefaultViewModel_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    TextPropDefaultViewModel_ that = (TextPropDefaultViewModel_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((textWithDefault_StringAttributeData != null ? !textWithDefault_StringAttributeData.equals(that.textWithDefault_StringAttributeData) : that.textWithDefault_StringAttributeData != null)) {\n      return false;\n    }\n    if ((nullableTextWithDefault_StringAttributeData != null ? !nullableTextWithDefault_StringAttributeData.equals(that.nullableTextWithDefault_StringAttributeData) : that.nullableTextWithDefault_StringAttributeData != null)) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (textWithDefault_StringAttributeData != null ? textWithDefault_StringAttributeData.hashCode() : 0);\n    _result = 31 * _result + (nullableTextWithDefault_StringAttributeData != null ? nullableTextWithDefault_StringAttributeData.hashCode() : 0);\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"TextPropDefaultViewModel_{\" +\n        \"textWithDefault_StringAttributeData=\" + textWithDefault_StringAttributeData +\n        \", nullableTextWithDefault_StringAttributeData=\" + nullableTextWithDefault_StringAttributeData +\n        \"}\" + super.toString();\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/testModelWithHolderGeneratesNewHolderMethod/AbstractModelWithHolder.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.view.View\n\n@EpoxyModelClass\nabstract class AbstractModelWithHolder : EpoxyModelWithHolder<Holder>() {\n    @EpoxyAttribute\n    var value = 0\n\n    override fun getDefaultLayout(): Int {\n        return 0\n    }\n}\n\nclass Holder : EpoxyHolder() {\n    override fun bindView(itemView: View) {}\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/testModelWithHolderGeneratesNewHolderMethod/AbstractModelWithHolder_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewParent;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AbstractModelWithHolder_ extends AbstractModelWithHolder implements GeneratedModel<Holder>, AbstractModelWithHolderBuilder {\n  private OnModelBoundListener<AbstractModelWithHolder_, Holder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AbstractModelWithHolder_, Holder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, Holder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AbstractModelWithHolder_, Holder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public AbstractModelWithHolder_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Holder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Holder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onBind(\n      OnModelBoundListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Holder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onUnbind(\n      OnModelUnboundListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Holder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Holder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public int value() {\n    return super.getValue();\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected Holder createNewHolder(ViewParent parent) {\n    return new Holder();\n  }\n\n  @Override\n  public AbstractModelWithHolder_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AbstractModelWithHolder_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AbstractModelWithHolder_ that = (AbstractModelWithHolder_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getValue() != that.getValue())) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + getValue();\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AbstractModelWithHolder_{\" +\n        \"value=\" + getValue() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest/src/test/resources/testModelWithHolderGeneratesNewHolderMethod/ksp/AbstractModelWithHolder_.java",
    "content": "package com.airbnb.epoxy;\n\nimport android.view.ViewParent;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.Nullable;\nimport java.lang.CharSequence;\nimport java.lang.Number;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.String;\n\n/**\n * Generated file. Do not modify!\n */\npublic class AbstractModelWithHolder_ extends AbstractModelWithHolder implements GeneratedModel<Holder>, AbstractModelWithHolderBuilder {\n  private OnModelBoundListener<AbstractModelWithHolder_, Holder> onModelBoundListener_epoxyGeneratedModel;\n\n  private OnModelUnboundListener<AbstractModelWithHolder_, Holder> onModelUnboundListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, Holder> onModelVisibilityStateChangedListener_epoxyGeneratedModel;\n\n  private OnModelVisibilityChangedListener<AbstractModelWithHolder_, Holder> onModelVisibilityChangedListener_epoxyGeneratedModel;\n\n  public AbstractModelWithHolder_() {\n    super();\n  }\n\n  @Override\n  public void addTo(EpoxyController controller) {\n    super.addTo(controller);\n    addWithDebugValidation(controller);\n  }\n\n  @Override\n  public void handlePreBind(final EpoxyViewHolder holder, final Holder object, final int position) {\n    validateStateHasNotChangedSinceAdded(\"The model was changed between being added to the controller and being bound.\", position);\n  }\n\n  @Override\n  public void handlePostBind(final Holder object, int position) {\n    if (onModelBoundListener_epoxyGeneratedModel != null) {\n      onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);\n    }\n    validateStateHasNotChangedSinceAdded(\"The model was changed during the bind call.\", position);\n  }\n\n  /**\n   * Register a listener that will be called when this model is bound to a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onBind(\n      OnModelBoundListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelBoundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void unbind(Holder object) {\n    super.unbind(object);\n    if (onModelUnboundListener_epoxyGeneratedModel != null) {\n      onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);\n    }\n  }\n\n  /**\n   * Register a listener that will be called when this model is unbound from a view.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   * <p>\n   * You may clear the listener by setting a null value, or by calling {@link #reset()}\n   */\n  public AbstractModelWithHolder_ onUnbind(\n      OnModelUnboundListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelUnboundListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityStateChanged(int visibilityState, final Holder object) {\n    if (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityStateChangedListener_epoxyGeneratedModel.onVisibilityStateChanged(this, object, visibilityState);\n    }\n    super.onVisibilityStateChanged(visibilityState, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility state has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityStateChanged(\n      OnModelVisibilityStateChangedListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelVisibilityStateChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  @Override\n  public void onVisibilityChanged(float percentVisibleHeight, float percentVisibleWidth,\n      int visibleHeight, int visibleWidth, final Holder object) {\n    if (onModelVisibilityChangedListener_epoxyGeneratedModel != null) {\n      onModelVisibilityChangedListener_epoxyGeneratedModel.onVisibilityChanged(this, object, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth);\n    }\n    super.onVisibilityChanged(percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth, object);\n  }\n\n  /**\n   * Register a listener that will be called when this model visibility has changed.\n   * <p>\n   * The listener will contribute to this model's hashCode state per the {@link\n   * com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.\n   */\n  public AbstractModelWithHolder_ onVisibilityChanged(\n      OnModelVisibilityChangedListener<AbstractModelWithHolder_, Holder> listener) {\n    onMutation();\n    this.onModelVisibilityChangedListener_epoxyGeneratedModel = listener;\n    return this;\n  }\n\n  public AbstractModelWithHolder_ value(int value) {\n    onMutation();\n    super.setValue(value);\n    return this;\n  }\n\n  public int value() {\n    return super.getValue();\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable Number... p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(long p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0) {\n    super.id(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0, @Nullable CharSequence... p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ id(@Nullable CharSequence p0, long p1) {\n    super.id(p0, p1);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ layout(@LayoutRes int p0) {\n    super.layout(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ spanSizeOverride(\n      @Nullable EpoxyModel.SpanSizeOverrideCallback p0) {\n    super.spanSizeOverride(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show() {\n    super.show();\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ show(boolean p0) {\n    super.show(p0);\n    return this;\n  }\n\n  @Override\n  public AbstractModelWithHolder_ hide() {\n    super.hide();\n    return this;\n  }\n\n  @Override\n  protected Holder createNewHolder(ViewParent parent) {\n    return new Holder();\n  }\n\n  @Override\n  public AbstractModelWithHolder_ reset() {\n    onModelBoundListener_epoxyGeneratedModel = null;\n    onModelUnboundListener_epoxyGeneratedModel = null;\n    onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;\n    onModelVisibilityChangedListener_epoxyGeneratedModel = null;\n    super.setValue(0);\n    super.reset();\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (!(o instanceof AbstractModelWithHolder_)) {\n      return false;\n    }\n    if (!super.equals(o)) {\n      return false;\n    }\n    AbstractModelWithHolder_ that = (AbstractModelWithHolder_) o;\n    if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityStateChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityStateChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if (((onModelVisibilityChangedListener_epoxyGeneratedModel == null) != (that.onModelVisibilityChangedListener_epoxyGeneratedModel == null))) {\n      return false;\n    }\n    if ((getValue() != that.getValue())) {\n      return false;\n    }\n    return true;\n  }\n\n  @Override\n  public int hashCode() {\n    int _result = super.hashCode();\n    _result = 31 * _result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityStateChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0);\n    _result = 31 * _result + getValue();\n    return _result;\n  }\n\n  @Override\n  public String toString() {\n    return \"AbstractModelWithHolder_{\" +\n        \"value=\" + getValue() +\n        \"}\" + super.toString();\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest2/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-processortest2/README.md",
    "content": "This module only exists to test that models that are subclassed in a different module still inherit\ntheir superclasses attributes correctly."
  },
  {
    "path": "epoxy-processortest2/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n  namespace 'com.airbnb.epoxy.processortest2'\n\n  defaultConfig {\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n}\n\ndependencies {\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n}\n"
  },
  {
    "path": "epoxy-processortest2/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-processortest2/src/main/java/com/airbnb/epoxy/processortest2/ProcessorTest2Model.java",
    "content": "package com.airbnb.epoxy.processortest2;\n\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyAttribute;\nimport com.airbnb.epoxy.EpoxyModel;\n\npublic class ProcessorTest2Model<T extends View> extends EpoxyModel<T> {\n\n  @EpoxyAttribute protected int processorTest2ValueProtected;\n  @EpoxyAttribute public int processorTest2ValuePublic;\n  @EpoxyAttribute int processorTest2ValuePackagePrivate;\n  @EpoxyAttribute public int someAttributeAlsoWithSetter;\n  @EpoxyAttribute public final int someFinalAttribute = 0;\n\n  @Override\n  protected int getDefaultLayout() {\n    return 0;\n  }\n\n  public ProcessorTest2Model<T> someAttributeAlsoWithSetter(int foo) {\n    someAttributeAlsoWithSetter = foo;\n    return this;\n  }\n}\n"
  },
  {
    "path": "epoxy-processortest2/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy Processor Test 2</string>\n</resources>\n"
  },
  {
    "path": "epoxy-sample/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "epoxy-sample/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n    namespace 'com.airbnb.epoxy.sample'\n\n    defaultConfig {\n        applicationId \"com.airbnb.android.epoxysample\"\n        minSdkVersion rootProject.PARIS_MIN_SDK_VERSION\n        compileSdk rootProject.COMPILE_SDK_VERSION\n        targetSdkVersion rootProject.TARGET_SDK_VERSION\n        vectorDrawables.useSupportLibrary = true\n        versionCode 1\n        versionName \"1.0\"\n    }\n\n    dataBinding {\n        enabled = true\n    }\n}\n\nkotlin {\n  jvmToolchain(17)\n}\n\nkapt {\n    correctErrorTypes = true\n}\n\nproject.android.buildTypes.all { buildType ->\n    buildType.javaCompileOptions.annotationProcessorOptions.arguments =\n            [\n                    validateEpoxyModelUsage     : String.valueOf(buildType.name == 'debug'),\n                    requireHashCodeInEpoxyModels: \"true\",\n                    requireAbstractEpoxyModels  : \"true\",\n                    implicitlyAddAutoModels     : \"true\",\n                    logEpoxyTimings     : \"false\",\n                    enableParallelEpoxyProcessing     : \"false\",\n            ]\n}\n\ndependencies {\n    implementation project(':epoxy-databinding')\n    implementation project(':epoxy-adapter')\n    implementation project(':epoxy-annotations')\n    kapt project(':epoxy-processor')\n\n    implementation rootProject.deps.paris\n    kapt rootProject.deps.parisProcessor\n\n    implementation rootProject.deps.androidCardView\n    implementation rootProject.deps.androidRecyclerView\n    implementation rootProject.deps.androidAppcompat\n    implementation rootProject.deps.versionedParcelable\n    implementation rootProject.deps.lottie\n\n    testImplementation rootProject.deps.junit\n}\n"
  },
  {
    "path": "epoxy-sample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/eli_hart/tools/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "epoxy-sample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <application\n        android:appComponentFactory=\"androidx.core.app.CoreComponentFactory\"\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/Theme.AppCompat.Light\"\n        tools:replace=\"android:appComponentFactory\"\n        tools:targetApi=\"28\">\n        <activity\n            android:name=\".MainActivity\"\n            android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\">\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "epoxy-sample/src/main/assets/exploding_heart.json",
    "content": "{\"v\":\"4.5.7\",\"fr\":25,\"ip\":0,\"op\":40,\"w\":1920,\"h\":1080,\"ddd\":0,\"assets\":[{\"id\":\"comp_0\",\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":4,\"nm\":\"Shape Layer 4\",\"parent\":3,\"td\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100},\"r\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[0,0,0]},\"a\":{\"a\":0,\"k\":[0,0,0]},\"s\":{\"a\":0,\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.125,0.75],[-3.375,-2.75],[-0.25,4]],\"o\":[[-3.125,-0.75],[3.375,2.75],[0.25,-4]],\"v\":[[13.75,-112],[9.25,-104.125],[18.25,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.093,-0.022],[0.1,0.082],[0.007,-0.119]],\"o\":[[0.093,0.022],[-0.1,-0.082],[-0.007,0.119]],\"v\":[[12.141,-106.916],[12.275,-107.15],[12.007,-107.057]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 89\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5.875,0.625],[0.375,-4],[-6.875,8.125]],\"o\":[[-5.875,-0.625],[-0.375,4],[6.875,-8.125]],\"v\":[[23.5,-128.375],[13.375,-120.75],[30.375,-116.75]],\"c\":true}],\"e\":[{\"i\":[[-0.121,-0.013],[-0.008,0.082],[0.142,-0.168]],\"o\":[[0.121,0.013],[0.008,-0.082],[-0.142,0.168]],\"v\":[[25.159,-118.615],[25.367,-118.773],[25.017,-118.855]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 88\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.25],[-4.25,-0.25]],\"o\":[[-4,0.25],[4.25,0.25]],\"v\":[[218,-136.75],[217.75,-132]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[217.75,-134.375],[217.75,-134.375]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 61\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[6.75,-0.25],[-1.25,-8.5],[-5.25,4]],\"o\":[[-6.75,0.25],[1.25,8.5],[5.25,-4]],\"v\":[[149.75,-94.75],[140.25,-85.25],[161.75,-81.5]],\"c\":true}],\"e\":[{\"i\":[[-0.06,0.002],[0.011,0.076],[0.047,-0.036]],\"o\":[[0.06,-0.002],[-0.011,-0.076],[-0.047,0.036]],\"v\":[[153.029,-85.796],[153.114,-85.881],[152.922,-85.914]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 62\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.25,1],[-1.25,-4],[4.75,-1.75],[-4,-4.25],[-1.25,5],[-2.386,2.936]],\"o\":[[-3.25,-1],[1.25,4],[-4.75,1.75],[4,4.25],[1.25,-5],[3.25,-4]],\"v\":[[219.75,-128],[213.75,-121],[212.25,-112.5],[209.5,-100.5],[223.25,-109.25],[222.25,-121.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.625,1.125],[2.25,0],[2.125,0.5],[0.75,-6.375],[-4.25,0],[0,2.125],[0,0],[-1.25,0],[0,0],[-1.25,-6.25],[-2.625,7.625]],\"o\":[[-3.625,-1.125],[-2.25,0],[-2.125,-0.5],[-0.75,6.375],[4.25,0],[0,-2.125],[0,0],[1.25,0],[0,0],[1.25,6.25],[2.625,-7.625]],\"v\":[[-136.75,-94.375],[-142.5,-90.5],[-148.125,-93.375],[-155.625,-85.25],[-150.125,-76.5],[-145,-80.25],[-144.75,-84.375],[-142.75,-82.875],[-139.625,-84.25],[-144.125,-71.625],[-130.25,-79.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.625,-0.75],[-0.25,-2.875],[3.375,0],[0,-2.5],[2.875,-2.375],[-5.25,-9],[0,0],[-0.25,-1.875],[0,0],[2.875,-0.75],[0,0],[4,-4.875],[-10.625,-4.125],[-1.375,3.875],[0,0],[0,0],[0,-4],[0,0],[-8.125,-5.5],[0,0],[-7.25,3.625],[0,0],[-1.625,0.5],[0,0],[-1.125,-3],[-2.75,5.125],[0,0],[-0.625,0.75],[0,0],[-2.25,-0.5],[0,0],[-4.75,1.125],[1.375,6.75],[4.375,-1.625],[0,0],[1,0.375],[0,0],[0.375,3.25],[8.25,2.625],[6.125,-2.5],[0,0],[1.875,0.625],[0,0],[1,2.875],[0,0],[-1.875,1.375],[-0.125,3.25],[4.75,0],[0,0],[0.5,2.125],[0,0],[-1.625,0.5],[-2.375,4.75],[0,0],[0.25,2.875],[-0.375,1],[0,0],[-1.625,1.375],[3.125,2.25],[0,0],[-0.375,2.5],[4.5,0],[1,2.25],[-1.75,1.125],[-4,-0.5],[1.375,4]],\"o\":[[-6.625,0.75],[0.25,2.875],[-3.375,0],[0,2.5],[-2.875,2.375],[5.25,9],[0,0],[0.25,1.875],[0,0],[-2.875,0.75],[0,0],[-4,4.875],[10.625,4.125],[1.375,-3.875],[0,0],[0,0],[0,4],[0,0],[8.125,5.5],[0,0],[7.25,-3.625],[0,0],[1.625,-0.5],[0,0],[1.125,3],[2.75,-5.125],[0,0],[0.625,-0.75],[0,0],[2.25,0.5],[0,0],[4.75,-1.125],[-1.375,-6.75],[-4.375,1.625],[0,0],[-1,-0.375],[0,0],[-0.375,-3.25],[-8.25,-2.625],[-6.125,2.5],[0,0],[-1.875,-0.625],[0,0],[-1,-2.875],[0,0],[1.875,-1.375],[0.125,-3.25],[-4.75,0],[0,0],[-0.5,-2.125],[0,0],[1.625,-0.5],[2.375,-4.75],[0,0],[-0.25,-2.875],[0.375,-1],[0,0],[1.625,-1.375],[-3.125,-2.25],[0,0],[0.375,-2.5],[-4.5,0],[-1,-2.25],[1.75,-1.125],[4,0.5],[-1.375,-4]],\"v\":[[-178.75,-127],[-187.125,-115.5],[-190.625,-108.375],[-197.25,-100.75],[-200.875,-92.25],[-202.375,-75],[-188.75,-71],[-189.625,-67],[-188,-62.875],[-193.25,-61.75],[-197.5,-56.125],[-210.75,-52.625],[-204.625,-30.25],[-186.75,-36.625],[-179.625,-39.875],[-176.75,-37],[-181.625,-31.375],[-177.75,-26.375],[-176.5,-15.125],[-162.125,-15.5],[-152.125,-11.75],[-152,-26],[-147.625,-23.5],[-143,-27],[-143.125,-21.125],[-135.25,-18.25],[-137.625,-26],[-135,-27.375],[-132.625,-30.375],[-129,-25.25],[-126.5,-27.125],[-117.5,-16.875],[-111.625,-36.125],[-125.125,-44.25],[-127.125,-34.5],[-129.375,-36.25],[-131.625,-36.75],[-130.375,-42.875],[-140.75,-51.125],[-158.875,-50.25],[-163,-39],[-167,-40.625],[-171.625,-40.625],[-171.875,-45.875],[-177.375,-50.5],[-172.25,-50.875],[-169,-58.25],[-175.5,-64.5],[-182.125,-59.625],[-181.25,-63.125],[-183,-66.5],[-178.75,-65.875],[-171.5,-70.75],[-171.125,-80],[-168.375,-85],[-171.625,-90.125],[-171.75,-92.625],[-165.75,-92],[-166.375,-96.75],[-173.75,-96.875],[-171.125,-101],[-177.75,-106.5],[-186.125,-110],[-183.25,-114.75],[-173.75,-116.25],[-167.625,-123.875]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 63\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.25,1.188],[-1.25,-6.188],[-2.625,2.75]],\"o\":[[-7.25,-1.188],[1.25,6.188],[2.625,-2.75]],\"v\":[[201.125,-142.25],[193.062,-136.25],[208.312,-131.438]],\"c\":true}],\"e\":[{\"i\":[[-0.095,-0.016],[0.016,0.081],[0.034,-0.036]],\"o\":[[0.095,0.016],[-0.016,-0.081],[-0.034,0.036]],\"v\":[[201.378,-135.982],[201.484,-136.06],[201.284,-136.123]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 51\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.875,1.188],[-1.875,-2.688]],\"o\":[[-2.875,-1.188],[1.875,2.688]],\"v\":[[173.562,-155.062],[170.938,-151.438]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[172.75,-152.5],[172.75,-152.5]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 52\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.688,0.875],[-1.5,-6.312],[-2.562,2.5]],\"o\":[[-7.688,-0.875],[1.5,6.312],[2.562,-2.5]],\"v\":[[159.062,-160.125],[148.938,-152.875],[164.562,-151.812]],\"c\":true}],\"e\":[{\"i\":[[-0.024,-0.003],[0.005,0.02],[0.008,-0.008]],\"o\":[[0.024,0.003],[-0.005,-0.02],[-0.008,0.008]],\"v\":[[157.276,-153.761],[157.308,-153.784],[157.258,-153.788]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 53\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.625,0.062],[1.212,-1.167],[2.188,-0.688],[-1.5,-4.375],[-2.875,1.938],[0,2.375]],\"o\":[[-1.625,-0.062],[-1.688,1.625],[-2.188,0.688],[1.5,4.375],[2.875,-1.938],[0,-2.375]],\"v\":[[173.75,-77.062],[171.25,-73.375],[166.375,-72.875],[162.75,-65],[174.125,-64.25],[176.625,-72.312]],\"c\":true}],\"e\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}],\"e\":[{\"i\":[[-0.038,-0.04],[-0.095,0],[-0.023,0.068],[0.098,0.095],[0.087,-0.059],[0,-0.072]],\"o\":[[0.034,0.036],[0.049,0],[0.022,-0.066],[-0.101,-0.097],[-0.087,0.059],[0,0.072]],\"v\":[[170.572,-68.07],[170.758,-68.019],[170.943,-68.159],[170.902,-68.428],[170.595,-68.451],[170.5,-68.244]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 54\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3,0.125],[-3.812,-5.375],[-0.562,2.688]],\"o\":[[-2.788,-0.116],[3.812,5.375],[0.562,-2.688]],\"v\":[[159.688,-49.25],[155.625,-42.188],[167.062,-44.438]],\"c\":true}],\"e\":[{\"i\":[[-0.083,-0.003],[0.105,0.149],[0.016,-0.074]],\"o\":[[0.077,0.003],[-0.105,-0.149],[-0.016,0.074]],\"v\":[[159.72,-42.919],[159.832,-43.114],[159.516,-43.052]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 55\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.812,0.688],[-2.688,-1.938]],\"o\":[[-1.812,-0.688],[2.688,1.938]],\"v\":[[168.375,-53.875],[167.312,-49.5]],\"c\":true}],\"e\":[{\"i\":[[0.061,0.023],[-0.091,-0.065]],\"o\":[[-0.061,-0.023],[0.091,0.065]],\"v\":[[167.439,-51.157],[167.403,-51.01]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 56\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.5,0.5],[-1.625,-5],[-1.75,4.625]],\"o\":[[-3.5,-0.5],[1.625,5],[1.75,-4.625]],\"v\":[[-39.5,-143.5],[-46.75,-133.25],[-34.5,-134.125]],\"c\":true}],\"e\":[{\"i\":[[0.14,0.02],[-0.065,-0.2],[-0.07,0.185]],\"o\":[[-0.14,-0.02],[0.065,0.2],[0.07,-0.185]],\"v\":[[-40.52,-136.42],[-40.81,-136.01],[-40.32,-136.045]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 57\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.638,-0.147],[-0.879,-2.418],[-0.879,1.759]],\"o\":[[-2.638,0.147],[0.879,2.418],[0.879,-1.759]],\"v\":[[-74.793,-156.267],[-77.871,-151.504],[-71.129,-152.31]],\"c\":true}],\"e\":[{\"i\":[[-0.18,0.01],[0.06,0.165],[0.06,-0.12]],\"o\":[[0.18,-0.01],[-0.06,-0.165],[-0.06,0.12]],\"v\":[[-74.48,-152.51],[-74.27,-152.835],[-74.73,-152.78]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 58\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,0.75],[-2,-3.125],[-0.5,2.375]],\"o\":[[-3.875,-0.75],[2,3.125],[0.5,-2.375]],\"v\":[[-160.125,-91],[-164.25,-84.75],[-156.5,-85.875]],\"c\":true}],\"e\":[{\"i\":[[0.526,0.102],[-0.272,-0.424],[-0.068,0.323]],\"o\":[[-0.526,-0.102],[0.272,0.424],[0.068,-0.323]],\"v\":[[-160.989,-87.273],[-161.549,-86.424],[-160.497,-86.577]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 59\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5,0.75],[-6.875,-6.125],[-1.25,3.875]],\"o\":[[-5,-0.75],[6.875,6.125],[1.25,-3.875]],\"v\":[[-153,-135.375],[-157,-126.875],[-142.5,-128.625]],\"c\":true}],\"e\":[{\"i\":[[-0.304,-0.046],[0.418,0.372],[0.076,-0.235]],\"o\":[[0.304,0.046],[-0.418,-0.372],[-0.076,0.235]],\"v\":[[-152.536,-128.016],[-152.293,-128.532],[-153.174,-128.426]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 60\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.75,-4.5],[-9.375,-3.625],[-3.125,2.375],[1.156,-5.286],[4.256,-4.745],[-5.106,-1.885],[2.75,7.875],[0.572,6.865]],\"o\":[[-8.75,4.5],[9.375,3.625],[2.994,-2.275],[-0.875,4],[-3.139,3.5],[8.125,3],[-2.75,-7.875],[-0.875,-10.5]],\"v\":[[142.375,-96.125],[143.75,-76.875],[160.75,-77.625],[169.5,-75.625],[163.494,-72.88],[164.5,-60.625],[177.375,-75],[167.75,-84]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.25,0],[0,0],[3.75,1.375],[8,-3.5],[0,0],[1.5,-1],[0,0],[3.75,-3.625],[0.5,-14.875],[0,0],[2.75,-1.75],[0,0],[5.5,-7],[-16.125,-2.875],[0,0],[-0.25,-2.375],[0,0],[-7.125,-3],[0,0],[-7.25,2.75],[0,0],[-5.125,1.5],[0,0],[-2,-0.5],[0,0],[-6,-0.75],[2.5,14.875],[0,0],[14.75,-1.75],[0,0],[0.75,2.125],[0,0],[-1.25,4.25],[0,0],[-1.75,4.25],[0,0],[-1.625,0],[0,0],[-2.125,-2.5],[0,0],[-2.75,0],[-3.375,4.625],[5.5,5.125],[0,0],[1.625,-0.25],[1.125,-1.75],[0,0],[1.875,2.375],[0,0],[2.625,2.75],[4.125,-0.625],[0,0],[-0.75,1.125],[0,0],[-2.375,-0.375],[-2.625,2.375],[0.625,1.75],[0,0],[-4.75,0.125],[-0.25,5.5]],\"o\":[[-8.25,0],[0,0],[-3.75,-1.375],[-8,3.5],[0,0],[-1.5,1],[0,0],[-3.75,3.625],[-0.5,14.875],[0,0],[-2.75,1.75],[0,0],[-5.5,7],[16.125,2.875],[0,0],[0.25,2.375],[0,0],[7.125,3],[0,0],[7.25,-2.75],[0,0],[5.125,-1.5],[0,0],[2,0.5],[0,0],[6,0.75],[-2.5,-14.875],[0,0],[-14.75,1.75],[0,0],[-0.75,-2.125],[0,0],[1.25,-4.25],[0,0],[1.75,-4.25],[0,0],[1.625,0],[0,0],[2.125,2.5],[0,0],[2.75,0],[3.375,-4.625],[-5.5,-5.125],[0,0],[-1.625,0.25],[-1.125,1.75],[0,0],[-1.875,-2.375],[0,0],[-2.625,-2.75],[-4.125,0.625],[0,0],[0.75,-1.125],[0,0],[2.375,0.375],[2.625,-2.375],[-0.625,-1.75],[0,0],[4.75,-0.125],[0.25,-5.5]],\"v\":[[-156.875,-136.875],[-163.125,-128.875],[-166.375,-126.5],[-182.625,-128.625],[-189,-113.125],[-191.875,-112.75],[-190.875,-110.125],[-197.125,-106.875],[-206,-80.375],[-189.875,-63.375],[-196,-63.125],[-198.75,-59],[-213.5,-53.875],[-203.375,-26.5],[-183.125,-35.875],[-184,-30.5],[-182,-25],[-177.75,-11.625],[-163.875,-11.5],[-150.875,-8.875],[-144.875,-18.875],[-136.25,-15.5],[-132.625,-26.5],[-129.875,-22.375],[-126.5,-22.875],[-119.75,-15.875],[-109.25,-33.625],[-127,-46.75],[-150.625,-54.75],[-165.5,-43.125],[-168.25,-46.625],[-171.625,-48.625],[-166,-56.125],[-168.75,-64.875],[-163.75,-71.25],[-166.375,-80.625],[-161.75,-80.5],[-158.5,-82.875],[-155.625,-73.5],[-147.5,-71.25],[-141.875,-66.625],[-131.5,-73.375],[-133.125,-94.125],[-142.875,-95.5],[-146.375,-98.25],[-153.375,-95.125],[-160.625,-93.125],[-162.125,-98.625],[-168.75,-99],[-166.875,-106.25],[-178.5,-108.875],[-184.125,-111.375],[-179.5,-112.5],[-177.625,-115.25],[-172.875,-113.25],[-165,-114.25],[-161.125,-123.375],[-160.125,-126.5],[-150.875,-123.375],[-140.125,-129]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.562,5.875],[1.562,-4.125],[2.188,-1.562],[-2.312,-2],[-3.5,2.688]],\"o\":[[-3.562,-5.875],[-1.562,4.125],[-2.188,1.562],[1.731,1.497],[3.5,-2.688]],\"v\":[[-33.688,-142.125],[-45.938,-140.688],[-51.562,-135.688],[-50.375,-129.562],[-37.25,-129.438]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.375,0.5],[-2.312,-3.25],[1.438,-4.312],[-6.438,-1.875],[-1.75,1.375],[2.062,2.25],[0.75,2.188],[1.312,1.062],[0,0],[-0.438,6.375]],\"o\":[[-4.375,-0.5],[2.312,3.25],[-1.438,4.312],[6.438,1.875],[1.75,-1.375],[-2.062,-2.25],[-0.75,-2.188],[-1.312,-1.062],[0,0],[0.438,-6.375]],\"v\":[[-74.688,-160],[-83.312,-150],[-81.938,-142.625],[-76.062,-127.5],[-61.812,-128.312],[-61.188,-133.625],[-67,-137.75],[-68.812,-144.188],[-75.938,-145.812],[-66.562,-153.812]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.25,0.875],[1.375,-4],[0,0],[0,-7.375],[-2.5,3.5],[0,0],[-2.5,8.125]],\"o\":[[-5.25,-0.875],[-1.375,4],[0,0],[0,7.375],[2.5,-3.5],[0,0],[2.5,-8.125]],\"v\":[[22,-130],[12.5,-123.75],[13.875,-115.75],[5.125,-105.125],[20,-101.125],[21.625,-110.75],[33,-118.5]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.875,1.75],[-5.5,-6],[-1.875,0.375],[0,0],[-0.5,-3.25],[0,0],[0,-13.75],[-1.375,4.5],[1.5,4.5],[-1.125,3.25],[3.75,3.75],[0,0]],\"o\":[[-7.875,-1.75],[5.5,6],[1.875,-0.375],[0,0],[0.5,3.25],[0,0],[0,13.75],[1.375,-4.5],[-1.5,-4.5],[1.125,-3.25],[-3.75,-3.75],[0,0]],\"v\":[[200.875,-143.625],[191.75,-133.625],[210.625,-128.75],[214.875,-129.625],[210.625,-122.375],[213.125,-116.75],[203.125,-103.875],[223.5,-103.875],[225,-116.5],[224.875,-126],[220.25,-137.375],[211.5,-137.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3,1.375],[-1,-7.375],[-3.125,0.875],[-2.25,-1.5],[0.125,4.125],[4.125,1]],\"o\":[[-3,-1.375],[1,7.375],[3.125,-0.875],[2.25,1.5],[-0.125,-4.125],[-4.125,-1]],\"v\":[[157,-162.875],[145.75,-154.125],[159.125,-148.75],[168.625,-148],[180.25,-151.75],[167.25,-160.75]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.375,0.875],[-0.625,-3],[1,1.75],[1.375,-6.875],[-6.125,2.375],[-2.75,1.125]],\"o\":[[-2.375,-0.875],[0.625,3],[-1,-1.75],[-1.375,6.875],[6.125,-2.375],[2.343,-0.958]],\"v\":[[169.25,-55.5],[166,-51.75],[162.25,-49.875],[152.75,-45.875],[164.75,-40.25],[169.875,-48.75]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 50\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[8.75,-0.625],[-7.375,-13.5],[-1.25,4.75]],\"o\":[[-8.75,0.625],[7.375,13.5],[1.25,-4.75]],\"v\":[[67.875,-134.75],[59.875,-116.375],[83.375,-117.75]],\"c\":true}],\"e\":[{\"i\":[[-0.034,0.002],[0.029,0.053],[0.005,-0.018]],\"o\":[[0.034,-0.002],[-0.029,-0.053],[-0.005,0.018]],\"v\":[[68.565,-119.064],[68.596,-119.136],[68.505,-119.13]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 41\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,1.125],[-2,-11.25],[-3.875,7]],\"o\":[[-6.75,-1.125],[2,11.25],[3.875,-7]],\"v\":[[196.25,-47.625],[186.125,-30.125],[205.125,-28.5]],\"c\":true}],\"e\":[{\"i\":[[0.237,0.04],[-0.07,-0.396],[-0.136,0.246]],\"o\":[[-0.237,-0.04],[0.07,0.396],[0.136,-0.246]],\"v\":[[196.552,-34.298],[196.195,-33.683],[196.864,-33.626]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 42\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.966,1.57],[0.343,-4.457],[-2.555,0.983]],\"o\":[[-2.966,-1.57],[-0.349,4.536],[4.536,-1.745]],\"v\":[[189.772,-1.472],[181.224,4.896],[188.464,10.217]],\"c\":true}],\"e\":[{\"i\":[[-0.214,-0.113],[-0.025,0.322],[0.184,-0.071]],\"o\":[[0.214,0.113],[0.025,-0.327],[-0.327,0.126]],\"v\":[[186.733,4.48],[187.35,4.02],[186.827,3.636]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 43\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.625,0.375],[-6.125,-6],[-1.25,4.375]],\"o\":[[-6.625,-0.375],[6.125,6],[1.25,-4.375]],\"v\":[[103.625,-133.75],[98.25,-121.5],[114.75,-125]],\"c\":true}],\"e\":[{\"i\":[[0.222,0.013],[-0.206,-0.201],[-0.042,0.147]],\"o\":[[-0.222,-0.013],[0.206,0.201],[0.042,-0.147]],\"v\":[[104.048,-125.112],[103.867,-124.701],[104.421,-124.819]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 44\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,0.625],[-3.875,-8.375],[-2.375,6.375]],\"o\":[[-6.75,-0.625],[3.875,8.375],[2.375,-6.375]],\"v\":[[211.625,-85.875],[201,-73.625],[220.375,-75.625]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.003],[-0.019,-0.041],[-0.012,0.031]],\"o\":[[-0.033,-0.003],[0.019,0.041],[0.012,-0.031]],\"v\":[[209.946,-75.924],[209.894,-75.864],[209.988,-75.874]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 45\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.25,0.625],[-3.375,-1.25]],\"o\":[[-3.25,-0.625],[3.375,1.25]],\"v\":[[-193,-116.125],[-194.625,-111.375]],\"c\":true}],\"e\":[{\"i\":[[-0.061,-0.012],[0.064,0.024]],\"o\":[[0.061,0.012],[-0.064,-0.024]],\"v\":[[-193.892,-113.387],[-193.861,-113.476]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 46\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.5,0.375],[-4.375,-3.875],[-0.125,3]],\"o\":[[-3.5,-0.375],[4.375,3.875],[0.125,-3]],\"v\":[[-60.625,-146.5],[-63.25,-139],[-55.25,-142.25]],\"c\":true}],\"e\":[{\"i\":[[0.298,0.032],[-0.372,-0.33],[-0.011,0.255]],\"o\":[[-0.298,-0.032],[0.372,0.33],[0.011,-0.255]],\"v\":[[-61.311,-141.468],[-61.535,-140.83],[-60.854,-141.106]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 47\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[4.462,1.05],[-3.413,-4.375],[-1.575,3.413]],\"o\":[[-4.463,-1.05],[3.412,4.375],[1.575,-3.412]],\"v\":[[1.113,-129.537],[-4.837,-120.788],[5.925,-120.613]],\"c\":true}],\"e\":[{\"i\":[[-0.071,-0.017],[0.054,0.069],[0.025,-0.054]],\"o\":[[0.071,0.017],[-0.054,-0.069],[-0.025,0.054]],\"v\":[[-0.399,-123.404],[-0.304,-123.543],[-0.475,-123.546]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 48\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.375,0.375],[-3.375,-4.125],[0,2.625]],\"o\":[[-2.375,-0.375],[3.375,4.125],[0,-2.625]],\"v\":[[135.875,-163.625],[132.125,-156.5],[141.5,-158.875]],\"c\":true}],\"e\":[{\"i\":[[0.077,0.012],[-0.109,-0.133],[0,0.085]],\"o\":[[-0.077,-0.012],[0.109,0.133],[0,-0.085]],\"v\":[[135.149,-158.363],[135.028,-158.133],[135.331,-158.21]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 49\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.07,-0.047],[-3.875,-7.25],[0,0],[-0.25,-4],[-5.875,-1.875],[0,2.75],[-3.25,1.25],[5.75,7.5],[5.333,-2.828],[0,0],[2.959,3.893]],\"o\":[[-8.25,0.125],[3.875,7.25],[0,0],[0.25,4],[5.875,1.875],[0,-2.75],[3.25,-1.25],[-2.966,-3.868],[-5.007,2.656],[0,0],[-1.754,-2.308]],\"v\":[[-1.25,-134.125],[-8.75,-118.75],[5.375,-113.5],[2.625,-104.875],[12.625,-92.75],[23.625,-105.625],[30.375,-111.5],[33.875,-127.875],[16.728,-131.431],[10.125,-120.875],[8.81,-131.165]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,1.375],[0.625,-3.5],[3.625,2.5],[7.5,-0.375],[-3.75,-9],[-9,1.125],[-5.875,-0.75],[-12.625,5.5]],\"o\":[[-10.25,-1.375],[-0.625,3.5],[-3.625,-2.5],[-7.5,0.375],[3.75,9],[9,-1.125],[5.875,0.75],[12.625,-5.5]],\"v\":[[104.875,-137.125],[93,-131.875],[82.875,-127.75],[68.75,-136.625],[55.375,-118.25],[76.875,-109.75],[90.125,-122],[112.5,-117.625]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.125,0.75],[-1.25,-11.375],[-3.25,-2.375],[1,-0.5],[3.5,-14.25],[-10.25,4],[0.625,3.75],[-2.125,4.25],[-2.125,4.5],[0.625,10]],\"o\":[[-5.125,-0.75],[1.25,11.375],[3.25,2.375],[-1,0.5],[-3.5,14.25],[10.25,-4],[-0.625,-3.75],[2.125,-4.25],[2.125,-4.5],[-0.625,-10]],\"v\":[[195.375,-51.125],[186.5,-34.25],[191.625,-20.25],[195.25,-14.75],[177,5.625],[187.75,17.625],[197.5,0.625],[194.125,-9.875],[201,-18],[205.375,-37.75]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.891,-8.168],[-9.875,-6.125],[0,0],[-1.625,-4.75],[0,0],[1,-1.625],[0,0],[7.125,-5.25],[-10.375,-0.375],[-2.875,5],[0,0],[-1.5,5.375],[8.735,11.767]],\"o\":[[-10,7.5],[9.875,6.125],[0,0],[1.625,4.75],[0,0],[-1,1.625],[0,0],[-5.73,4.222],[10.375,0.375],[2.875,-5],[0,0],[1.5,-5.375],[-9,-12.125]],\"v\":[[133.875,-97.5],[136.75,-75.875],[160,-72],[158.125,-61.125],[166.125,-57.375],[164,-54.875],[164,-51.625],[152.75,-52.125],[157.625,-36.375],[173.25,-47],[170.125,-58.25],[178.75,-64.125],[173,-84.375]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[13.632,3.84],[0,0],[8.75,1.375],[-6.25,-4],[-2.625,-2],[-12,-1.125],[-3.75,1.625],[0.375,-2.5],[-9.625,-3.125],[-1.875,-2.875],[1.875,-11.875],[1.875,-2.875],[-6.875,-5.625],[-1.75,8],[3.5,0.625],[-2.75,0.75],[-1.5,24.5],[6.125,1.375],[1.25,5.875]],\"o\":[[-17.75,-5],[0,0],[-8.75,-1.375],[6.25,4],[2.625,2],[12,1.125],[3.75,-1.625],[-0.375,2.5],[9.625,3.125],[1.875,2.875],[-1.875,11.875],[-1.875,2.875],[6.875,5.625],[1.75,-8],[-3.5,-0.625],[2.75,-0.75],[1.5,-24.5],[-6.125,-1.375],[-1.25,-5.875]],\"v\":[[164.25,-163.375],[141.75,-158.125],[134.625,-163.625],[133.5,-156.125],[141.25,-153.75],[157.625,-145.375],[180,-145.625],[185.625,-140.125],[194.75,-129],[209.375,-125.5],[199.75,-106.375],[203.625,-88.5],[201.625,-69.875],[221.125,-75.5],[211.5,-88.875],[210.625,-94.5],[228.375,-119.75],[199.625,-145.125],[183.5,-151.125]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[12.125,1.25],[0,0],[6.875,-5.375],[0,0],[3,-1],[0,0],[6.125,-21.125],[0,0],[3,-8.875],[-12.25,-6.25],[0,0],[0,-2.875],[-8.625,-4.75],[0,0],[-13,0.5],[0,0],[-5.75,0],[0,0],[-6.125,-0.625],[0.5,12.25],[13.625,7.375],[0,0],[0.875,2.875],[0,0],[-4.25,-1.125],[-3.75,0.875],[-2.5,9],[5.375,8.75],[1.75,-3.625],[0,0],[1.75,3.625],[0,0],[-4.5,3.5],[0,0],[-2,-0.5],[-3.125,6.5]],\"o\":[[-12.125,-1.25],[0,0],[-6.875,5.375],[0,0],[-3,1],[0,0],[-6.125,21.125],[0,0],[-3,8.875],[12.25,6.25],[0,0],[0,2.875],[8.625,4.75],[0,0],[13,-0.5],[0,0],[5.75,0],[0,0],[6.125,0.625],[-0.5,-12.25],[-13.625,-7.375],[0,0],[-0.875,-2.875],[0,0],[4.25,1.125],[3.75,-0.875],[2.5,-9],[-5.375,-8.75],[-1.75,3.625],[0,0],[-1.75,-3.625],[0,0],[4.5,-3.5],[0,0],[2,0.5],[3.125,-6.5]],\"v\":[[-153,-138.25],[-168.25,-132.75],[-185.25,-129.625],[-190,-114.875],[-194.75,-116.375],[-196,-112.625],[-211.25,-93.125],[-200.625,-63.375],[-218.375,-54.375],[-207.625,-23.625],[-184.375,-28.125],[-189.5,-19.5],[-181.625,-9.375],[-167.875,-6.5],[-154.625,-3.25],[-143.25,-14.625],[-137.125,-11.375],[-129.625,-15],[-121.75,-9],[-107.875,-28.125],[-130.625,-56.25],[-162.375,-53.875],[-158.25,-61.75],[-159.125,-71],[-150.25,-65.875],[-137,-65.25],[-127.375,-76.875],[-131.125,-100.875],[-147.875,-103.375],[-158.875,-95.625],[-159.75,-104.5],[-170.625,-110.5],[-161.875,-112.625],[-160,-124.125],[-153.375,-120.625],[-138.625,-126.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.5,2.75],[-1.5,-15.5],[-9.25,-0.375],[-1,1.375],[-6.25,0],[-1,4.5],[5.75,0.875],[1.875,-3.875],[0.5,2.25],[3.375,1.75],[0.75,-2],[0,0],[1.875,1.25],[0,0],[-2,3.875]],\"o\":[[-6.5,-2.75],[1.5,15.5],[9.25,0.375],[1,-1.375],[6.25,0],[1,-4.5],[-5.75,-0.875],[-1.875,3.875],[-0.5,-2.25],[-3.375,-1.75],[-0.75,2],[0,0],[-1.875,-1.25],[0,0],[2,-3.875]],\"v\":[[-72,-161.625],[-86.75,-140.75],[-69.25,-125.625],[-54.625,-131.875],[-47.125,-125.375],[-29.5,-135.625],[-38.75,-148.375],[-50.25,-140.625],[-55.375,-139.625],[-56.375,-146.25],[-65.5,-146.375],[-66.125,-140.875],[-69.125,-145.875],[-74.375,-147.125],[-64.875,-150.375]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 40\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.25,3],[-4,-4.25]],\"o\":[[-6.25,-3],[4,4.25]],\"v\":[[118.75,-151.25],[115,-144]],\"c\":true}],\"e\":[{\"i\":[[0.431,0.207],[-0.276,-0.293]],\"o\":[[-0.431,-0.207],[0.276,0.293]],\"v\":[[118.052,-147.293],[117.793,-146.793]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 29\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,0.75],[-3.5,-4.75],[-4.5,6.5]],\"o\":[[-5.75,-0.75],[3.5,4.75],[4.5,-6.5]],\"v\":[[138,-25.75],[132.5,-13],[144,-16.75]],\"c\":true}],\"e\":[{\"i\":[[-0.442,-0.058],[0.269,0.365],[0.346,-0.5]],\"o\":[[0.442,0.058],[-0.269,-0.365],[-0.346,0.5]],\"v\":[[138.808,-16.731],[139.231,-17.712],[138.346,-17.423]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 30\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.75,-2.25],[-8,-4.5],[0,6]],\"o\":[[-4.75,2.25],[8,4.5],[0,-6]],\"v\":[[92.25,65.25],[88.75,79.25],[106.75,69]],\"c\":true}],\"e\":[{\"i\":[[0.057,-0.027],[-0.096,-0.054],[0,0.072]],\"o\":[[-0.057,0.027],[0.096,0.054],[0,-0.072]],\"v\":[[93.732,73.277],[93.69,73.446],[93.907,73.322]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 31\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.5,1.25],[-6.75,-3.25]],\"o\":[[-6.5,-1.25],[6.75,3.25]],\"v\":[[-89,-175],[-90.75,-166]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-90,-169.5],[-90,-169.5]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 32\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[15,1],[-2.5,-10.75],[-4,5.25]],\"o\":[[-15,-1],[2.5,10.75],[4,-5.25]],\"v\":[[-111,-164.5],[-126.75,-146.5],[-100.25,-147]],\"c\":true}],\"e\":[{\"i\":[[-1.241,-0.083],[0.207,0.889],[0.331,-0.434]],\"o\":[[1.241,0.083],[-0.207,-0.889],[-0.331,0.434]],\"v\":[[-112.759,-149.477],[-111.457,-150.966],[-113.648,-150.925]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 33\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,-1.75],[-15.5,-8.5],[5.75,4.5]],\"o\":[[-5.75,1.75],[15.5,8.5],[-5.75,-4.5]],\"v\":[[129.5,37.25],[129,63],[147,42.75]],\"c\":true}],\"e\":[{\"i\":[[-0.037,0.011],[0.099,0.054],[-0.037,-0.029]],\"o\":[[0.037,-0.011],[-0.099,-0.054],[0.037,0.029]],\"v\":[[133.148,53.604],[133.151,53.439],[133.037,53.568]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 34\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[7.75,2.5],[-5.25,-4.5],[-0.25,5.5]],\"o\":[[-7.75,-2.5],[5.25,4.5],[0.25,-5.5]],\"v\":[[162.75,15.25],[154.25,31],[168.5,26]],\"c\":true}],\"e\":[{\"i\":[[-0.901,-0.291],[0.61,0.523],[0.029,-0.64]],\"o\":[[0.901,0.291],[-0.61,-0.523],[-0.029,0.64]],\"v\":[[159.401,25.157],[160.39,23.326],[158.733,23.907]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 35\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.25,2.5],[-2.625,-2.625]],\"o\":[[-3.898,-1.856],[2.625,2.625]],\"v\":[[-154.5,5.25],[-157.75,12.375]],\"c\":true}],\"e\":[{\"i\":[[-0.177,-0.084],[0.088,0.088]],\"o\":[[0.131,0.063],[-0.088,-0.088]],\"v\":[[-154.823,9.33],[-154.713,9.09]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 36\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.25],[-4.25,-7],[-0.125,7.5]],\"o\":[[-4.125,-1.25],[4.25,7],[0.125,-7.5]],\"v\":[[-147.5,25.5],[-150.5,40.875],[-132.875,46.5]],\"c\":true}],\"e\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":29,\"s\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}],\"e\":[{\"i\":[[-0.109,-0.033],[0.112,0.184],[0.003,-0.197]],\"o\":[[0.109,0.033],[-0.112,-0.184],[-0.003,0.197]],\"v\":[[-147.757,38.288],[-147.612,37.988],[-147.997,38.012]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 37\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.625],[-5.375,-9.5],[-3.625,10.125]],\"o\":[[-4.125,-1.625],[5.375,9.5],[3.625,-10.125]],\"v\":[[-101.25,-11.75],[-109.75,5.75],[-95.5,2.375]],\"c\":true}],\"e\":[{\"i\":[[0.177,0.07],[-0.231,-0.409],[-0.156,0.435]],\"o\":[[-0.177,-0.07],[0.231,0.409],[0.156,-0.435]],\"v\":[[-103.403,0.392],[-103.769,1.144],[-103.156,0.999]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 38\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.5,4.25],[-3.75,-9],[-2.75,-6.75],[-4.25,3.75],[0,0],[-2,10.25],[10.75,-2]],\"o\":[[-4.108,-1.838],[3.75,9],[2.75,6.75],[4.25,-3.75],[0,0],[2,-10.25],[-10.75,2]],\"v\":[[-3.25,-137.75],[-13.75,-121.75],[1.75,-100.5],[18,-91.5],[29,-107.5],[39,-118.5],[17.75,-135.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[22.75,-5.5],[0,0],[10.5,-18.5],[0,0],[-13,-24.25],[0,0],[-8,-6.75],[0,0],[-8,-0.25],[-9,0],[-6.25,-7.5],[-0.75,24.25],[0,0],[-3.75,9],[13.75,7.25],[4.75,3.5],[0,0],[-3.25,3.5],[0,0],[-3.25,8.75]],\"o\":[[-22.75,5.5],[0,0],[-10.5,18.5],[0,0],[13,24.25],[0,0],[8,6.75],[0,0],[8,0.25],[9,0],[6.25,7.5],[0.75,-24.25],[0,0],[3.75,-9],[-13.75,-7.25],[-4.75,-3.5],[0,0],[3.25,-3.5],[0,0],[3.25,-8.75]],\"v\":[[-169.75,-138.25],[-197.25,-118.5],[-212.5,-103.5],[-213.5,-68.75],[-219,-29.75],[-191.5,-20],[-188,-8],[-170,-3.25],[-158.75,2.75],[-137.75,-5.5],[-127.25,-5],[-105.25,-26],[-135.25,-61.25],[-126,-71.75],[-135,-105.75],[-154.5,-105.25],[-166.25,-107],[-157,-110.5],[-154,-118.25],[-134.75,-129.25]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10,5.75],[4,-7.5],[-13.5,-6.25],[-6.25,-2],[-7.75,3.25],[5.5,7],[4.25,-4.75],[0,0],[0,1.75],[0,0]],\"o\":[[-10,-5.75],[-4,7.5],[13.5,6.25],[6.25,2],[7.75,-3.25],[-5.5,-7],[-4.25,4.75],[0,0],[0,-1.75],[0,0]],\"v\":[[-68,-162.75],[-87,-154],[-79.5,-124.75],[-52.75,-123],[-32.25,-128.25],[-31,-147.25],[-48.75,-147.5],[-54.25,-139.75],[-54,-146],[-62.75,-151]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.75,3.5],[-1.25,-13.5],[0,0],[4.5,-9.75],[-5,-2.75],[-4.5,10.75],[-4,6],[0.5,8.5]],\"o\":[[-5.75,-3.5],[1.25,13.5],[0,0],[-1.977,4.283],[5,2.75],[4.5,-10.75],[4,-6],[-0.5,-8.5]],\"v\":[[199.5,-52.75],[182.25,-35.75],[190.75,-18],[174.75,2],[174.75,22.25],[199.25,8.25],[200.75,-12.5],[208,-33.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[16.25,6.75],[8.5,-13.25],[-7.5,-1],[0,0],[-2.5,-3.25],[0,0],[2.75,-9.25],[-10.75,3],[-2.75,14.25]],\"o\":[[-16.25,-6.75],[-8.5,13.25],[7.5,1],[0,0],[2.5,3.25],[0,0],[-2.75,9.25],[10.75,-3],[2.75,-14.25]],\"v\":[[163.25,-98.75],[124,-91.5],[139,-69.75],[152.75,-68],[152.5,-60.25],[159.25,-56.5],[144.5,-48.25],[158.75,-34.25],[180.5,-58]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[18,5.5],[0,0],[5.75,0.25],[-7.25,-7.5],[-9,-1.5],[0,0],[-6.75,-1.75],[0,0],[0,-10.5],[-17.75,8],[0,0],[6.5,27.25],[0,0]],\"o\":[[-18,-5.5],[0,0],[-5.75,-0.25],[7.25,7.5],[9,1.5],[0,0],[6.75,1.75],[0,0],[0,10.5],[17.75,-8],[0,0],[-6.5,-27.25],[0,0]],\"v\":[[164.75,-171.5],[142.5,-162.75],[132.75,-168],[129.5,-153.5],[155,-140.75],[180.25,-137.5],[194.25,-126],[204.25,-122.5],[193,-85.5],[215,-65.5],[219,-91.25],[232.25,-129.25],[186.25,-152.25]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.75,1.75],[0,0],[7.5,0.75],[3,-12.25],[-16.75,1.75],[-7.606,-2.48],[1.25,11.75]],\"o\":[[-17.527,-2.61],[0,0],[-5.855,-0.586],[-3.154,12.879],[16.75,-1.75],[11.5,3.75],[-0.954,-8.963]],\"v\":[[103.5,-145.75],[86.5,-129.75],[71.25,-138],[51.75,-125],[75,-107],[95.5,-115.25],[120,-128.25]],\"c\":true}},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 39\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.125,0.5],[-5.125,-1.625]],\"o\":[[-8.125,-0.5],[6.076,1.926]],\"v\":[[-91.625,-69.375],[-94.25,-62.5]],\"c\":true}],\"e\":[{\"i\":[[-0.375,-0.023],[0.237,0.075]],\"o\":[[0.375,0.023],[-0.28,-0.089]],\"v\":[[-91.625,-65.033],[-91.504,-65.35]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 27\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.25,-0.25],[-2.75,-10.5],[-2.125,6.25]],\"o\":[[-8.25,0.25],[2.75,10.5],[2.125,-6.25]],\"v\":[[-87.875,-94.125],[-98.25,-78.125],[-76.25,-80.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-87.562,-81],[-87.562,-81],[-87.562,-81]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 28\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.375],[-3.5,-5.125],[-0.625,4.5]],\"o\":[[-4,0.375],[3.5,5.125],[0.625,-4.5]],\"v\":[[-3.25,137.625],[-8.125,148],[4.125,143.25]],\"c\":true}],\"e\":[{\"i\":[[-0.092,0.009],[0.08,0.117],[0.014,-0.103]],\"o\":[[0.092,-0.009],[-0.08,-0.117],[-0.014,0.103]],\"v\":[[-3.442,145.361],[-3.33,145.123],[-3.611,145.232]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 26\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.506,2.794],[2.343,-6.218],[-5.137,0.09],[-0.541,3.424]],\"o\":[[-4.506,-2.794],[-2.343,6.218],[5.137,-0.09],[0.541,-3.424]],\"v\":[[-25.506,127.416],[-38.032,130.119],[-29.471,141.384],[-21.631,137.509]],\"c\":true}],\"e\":[{\"i\":[[-0.029,-0.018],[-0.015,0.04],[0.033,-0.001],[0.003,-0.022]],\"o\":[[0.029,0.018],[0.015,-0.04],[-0.033,0.001],[-0.003,0.022]],\"v\":[[-30.721,132.722],[-30.64,132.704],[-30.695,132.631],[-30.746,132.656]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 24\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.75,-1.625],[3.625,2],[-1,-3.625],[-1.212,0.387],[-1.56,-1.97],[-4.625,5.875],[1.75,2]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.343,1.244],[2.318,-0.74],[2.375,3],[4.625,-5.875],[-1.75,-2]],\"v\":[[-6.25,134.625],[-15.875,144.875],[-21,149.25],[-18.483,150.129],[-11.375,149.125],[5.125,147.625],[5,134.875]],\"c\":true}],\"e\":[{\"i\":[[4.75,-1.625],[3.625,2],[-0.625,-2.625],[-1.142,0.534],[-2.013,-0.633],[-5.5,-0.625],[0.923,5.539]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.177,0.742],[1.405,-0.656],[4.375,1.375],[3.107,0.353],[-0.75,-4.5]],\"v\":[[-5.125,140.125],[-13.375,145.375],[-19.125,147.375],[-16.356,148.417],[-12,146.375],[-3,150.75],[3.75,144.375]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 25\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.125,0.625],[-2.5,-2.5]],\"o\":[[-2.125,-0.625],[2.5,2.5]],\"v\":[[-79.625,43.625],[-81.125,46.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-80.562,46.125],[-80.562,46.125]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":23,\"s\":[0,0],\"h\":1}],\"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 14\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,2.25],[-2.25,-1.75]],\"o\":[[-4.25,-2.25],[2.25,1.75]],\"v\":[[-45.75,26.5],[-48.25,32]],\"c\":true}],\"e\":[{\"i\":[[0.236,0.125],[-0.125,-0.097]],\"o\":[[-0.236,-0.125],[0.125,0.097]],\"v\":[[-45.986,28.861],[-46.125,29.167]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 13\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3,-1.25],[-3,-5],[-7.75,1.75],[2,4.75]],\"o\":[[-3,1.25],[3,5],[7.75,-1.75],[-2,-4.75]],\"v\":[[-46.5,-2.25],[-52.5,8.25],[-39.75,18],[-31.5,2.5]],\"c\":true}],\"e\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}],\"e\":[{\"i\":[[-0.024,0.007],[0.005,0.025],[0.034,-0.008],[-0.009,-0.021]],\"o\":[[0.022,-0.007],[-0.004,-0.022],[-0.034,0.008],[0.009,0.021]],\"v\":[[-41.551,8.163],[-41.524,8.107],[-41.583,8.074],[-41.616,8.143]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 12\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,3],[0,-5.75],[-2.75,2.5]],\"o\":[[-4.25,-3],[0,5.75],[2.75,-2.5]],\"v\":[[121.75,-3.75],[113.5,0.75],[127.75,4.5]],\"c\":true}],\"e\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.023],[0,-0.044],[-0.021,0.019]],\"o\":[[-0.033,-0.023],[0,0.044],[0.021,-0.019]],\"v\":[[120.96,-0.289],[120.88,-0.242],[120.974,-0.207]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 11\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.5,-3.75],[0,0],[-4.5,-10.75],[-4,6.75],[7,7.5]],\"o\":[[-4.5,3.75],[0,0],[4.5,10.75],[4,-6.75],[-7,-7.5]],\"v\":[[75,14],[73.5,24],[70,39.25],[96.5,37.5],[94.75,14.5]],\"c\":true}],\"e\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}],\"e\":[{\"i\":[[0.032,-0.026],[0,0],[-0.032,-0.06],[-0.028,0.048],[0.049,0.053]],\"o\":[[-0.032,0.026],[0,0],[0.039,0.072],[0.028,-0.048],[-0.049,-0.053]],\"v\":[[87.186,24.88],[87.145,24.941],[87.158,25.053],[87.337,25.046],[87.325,24.884]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 10\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,1.25],[0,-5.75],[-5.75,8.5]],\"o\":[[-4.25,-1.25],[0,5.75],[5.75,-8.5]],\"v\":[[55.25,97.75],[44.25,114],[57.25,114]],\"c\":true}],\"e\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[53.375,111.25],[53.375,111.25],[53.375,111.25]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 15\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,-3.5],[-2.75,-8.75],[-8.25,-0.25],[4.75,14.75]],\"o\":[[-4.25,3.5],[2.75,8.75],[8.25,0.25],[-4.75,-14.75]],\"v\":[[-38.75,60],[-44.25,76.25],[-23.25,92.75],[-6.5,67]],\"c\":true}],\"e\":[{\"i\":[[0.07,-0.058],[-0.046,-0.145],[-0.137,-0.004],[0.079,0.244]],\"o\":[[-0.07,0.058],[0.046,0.145],[0.137,0.004],[-0.079,-0.244]],\"v\":[[-24.613,72.416],[-24.704,72.685],[-24.356,72.959],[-24.079,72.532]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 16\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[10,-2.5],[-7.25,-12.5],[-2.25,7]],\"o\":[[-10,2.5],[7.25,12.5],[2.25,-7]],\"v\":[[-78.25,74.5],[-88.75,93],[-67,89.75]],\"c\":true}],\"e\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}],\"e\":[{\"i\":[[-0.08,0.016],[0.058,0.078],[0.018,-0.044]],\"o\":[[0.08,-0.016],[-0.058,-0.078],[-0.018,0.044]],\"v\":[[-98.362,72.463],[-98.308,72.349],[-98.482,72.37]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 17\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.5,3],[-3.5,-5]],\"o\":[[-2.5,-3],[3.5,5]],\"v\":[[-119.5,57],[-124,63.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-122.25,61.125],[-122.25,61.125]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 18\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[9.5,-2.75],[2.5,-5],[0,0],[-7.25,-6.75],[-2,3.5],[0,0],[4,11]],\"o\":[[-9.5,2.75],[-2.5,5],[0,0],[7.25,6.75],[2,-3.5],[0,0],[-4,-11]],\"v\":[[-88.25,-97.75],[-104.5,-86.75],[-104.25,-71.5],[-104,-54],[-77,-59.5],[-76,-71.75],[-65.75,-92.5]],\"c\":true}],\"e\":[{\"i\":[[7.293,-2.111],[1.244,-4.107],[0,0],[-5.566,-5.182],[-1.293,4.188],[0,0],[3.071,8.444]],\"o\":[[-7.293,2.111],[-2.682,8.857],[0,0],[5.566,5.182],[2.519,-8.159],[0,0],[-3.071,-8.444]],\"v\":[[-90.843,-93.802],[-100.568,-86.607],[-95.626,-73.15],[-94.684,-64.466],[-82.707,-65.938],[-86.189,-72.842],[-76.821,-86.021]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 19\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3.967,1.543],[1.763,-7.714],[-2.94,1.96],[-6.391,2.204],[1.543,3.526],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-1.763,7.714],[6.612,-4.408],[2.668,-0.92],[-1.543,-3.526],[-0.441,-6.391]],\"v\":[[-11,-75.637],[-25.987,-66.38],[-13.645,-56.021],[-2.184,-52.275],[4.207,-59.107],[-5.049,-66.16]],\"c\":true}],\"e\":[{\"i\":[[3.967,1.543],[2.081,-7.714],[-4.12,1.96],[-6.467,-1.97],[2.293,4.357],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-2.081,7.714],[7.176,-3.414],[4.184,1.275],[-1.792,-3.406],[-0.441,-6.391]],\"v\":[[-9,-74.887],[-20.737,-69.38],[-10.395,-61.021],[-3.684,-56.025],[0.957,-62.107],[-4.549,-65.16]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 20\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[5.342,-0.929],[0.697,-7.896],[-9.754,4.645],[1.858,4.877]],\"o\":[[-5.342,0.929],[-0.697,7.896],[9.754,-4.645],[-1.858,-4.877]],\"v\":[[-151.777,-175.317],[-171.053,-161.846],[-149.686,-159.291],[-134.358,-173.923]],\"c\":true}],\"e\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}],\"e\":[{\"i\":[[0.034,-0.006],[0.004,-0.051],[-0.063,0.03],[0.012,0.031]],\"o\":[[-0.034,0.006],[-0.004,0.051],[0.063,-0.03],[-0.012,-0.031]],\"v\":[[-151.107,-165.155],[-151.177,-165.071],[-151.063,-165.011],[-151.017,-165.113]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 21\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4,-1.5],[-3,-8.25],[-4,-4.25],[0,0],[-4.25,-1.5],[0,0],[-12.5,8.75],[1.75,4],[15.25,-3.5],[0,0],[0,2.75],[0,0],[2.75,4.25]],\"o\":[[-4.521,1.695],[3,8.25],[4,4.25],[0,0],[4.25,1.5],[0,0],[12.5,-8.75],[-1.75,-4],[-15.25,3.5],[0,0],[0,-2.75],[0,0],[-2.75,-4.25]],\"v\":[[-46,102.5],[-47,128.25],[-35.5,146.25],[-26,150.5],[-15,160.5],[-5.75,156.75],[17.25,151.5],[34.75,132],[13,122.25],[-7.25,130.75],[-13.75,125.25],[-19.25,118.75],[-29.75,108.25]],\"c\":true}],\"e\":[{\"i\":[[1.993,-1.84],[-1.905,-5.238],[-3.64,-0.695],[0,0],[-2.699,-0.952],[0,0],[-9.612,4.283],[0.773,2.662],[9.683,-2.222],[0,0],[0.478,1.68],[0,0],[5.489,2.259]],\"o\":[[-3.975,3.671],[1.905,5.238],[3.728,0.712],[0,0],[2.699,0.952],[0,0],[8.85,-3.944],[-1.501,-5.17],[-9.683,2.222],[0,0],[-1.685,-5.922],[0,0],[-2.972,-1.223]],\"v\":[[-39.001,120.963],[-41.876,136.567],[-30.654,145.384],[-24.249,146.403],[-21.183,152.192],[-13.817,149.998],[0.041,151.703],[8.727,139.881],[-4.524,133.503],[-14.769,142.26],[-16.097,133.355],[-19.963,125.496],[-27.75,120.322]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 22\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[15,-6],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[3.5,1.75],[4.25,2.75],[0,0],[-1.5,14],[0,0],[3.5,17.25],[0,0],[-7,3.25],[0,0],[-3.5,0],[0,0],[-7.75,-0.75],[0,0],[-7.75,-5],[0,0],[-9,-1.5],[0.75,-2.5],[-6,1.75],[-8.25,0.75],[0,0],[-10.75,8.5],[0,0],[-2.25,3],[-3.5,-4.25],[-8,2.25],[-9,-4.5],[0,0],[13.75,3.5],[6.75,-10.75],[-9.25,-8.25],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-3.5,7.25],[0,0],[2.75,-8.25],[12.25,-5.25],[0,0],[6.5,-5],[4,-1.5],[4.5,-9.25],[-5.25,-1.25],[-4,5.5],[0,0],[-4.25,5.25],[0,0],[-24.5,19.75],[0,6.75],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[3.75,-1],[0,0],[7.25,1],[0,0],[3,-6],[0,0],[5,-1.25],[0,0],[5,1.25],[0,0],[7.25,4],[0,0],[4.75,4.5],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-15,6],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[-3.5,-1.75],[-4.25,-2.75],[0,0],[1.5,-14],[0,0],[-3.5,-17.25],[0,0],[7,-3.25],[0,0],[3.5,0],[0,0],[7.75,0.75],[0,0],[7.75,5],[0,0],[9,1.5],[-0.75,2.5],[6,-1.75],[8.25,-0.75],[0,0],[10.75,-8.5],[0,0],[2.25,-3],[3.5,4.25],[8,-2.25],[9,4.5],[0,0],[-13.75,-3.5],[-6.75,10.75],[9.25,8.25],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[3.5,-7.25],[0,0],[-2.75,8.25],[-12.25,5.25],[0,0],[-6.5,5],[-4,1.5],[-4.5,9.25],[5.25,1.25],[4,-5.5],[0,0],[4.25,-5.25],[0,0],[24.5,-19.75],[0,-6.75],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-3.75,1],[0,0],[-7.25,-1],[0,0],[-3,6],[0,0],[-5,1.25],[0,0],[-5,-1.25],[0,0],[-7.25,-4],[0,0],[-4.75,-4.5],[0,0]],\"v\":[[-71.75,-184],[-104.5,-167],[-132.75,-157],[-141.75,-147.5],[-191,-134],[-209.5,-120.75],[-230.25,-101],[-231.25,-77.75],[-234.5,-26.5],[-200.25,11.5],[-171.25,22.25],[-154.25,27.25],[-150.25,49],[-124.5,54.75],[-142,32.25],[-123.75,32.5],[-100,41.5],[-100,33.25],[-111.5,22],[-116.25,14.75],[-105,-11.5],[-113.5,-43.75],[-112,-88.5],[-126.5,-111.75],[-114.25,-118],[-109.25,-131.75],[-101.5,-134.5],[-96.25,-137.75],[-75,-130],[-54,-125.5],[-47.5,-110.25],[-30.5,-105.75],[-17.25,-93.75],[-4.5,-84.5],[10.5,-85],[34.25,-85],[51.75,-89.75],[71,-92.5],[87,-106.25],[107.5,-111.25],[120.25,-110.5],[141,-104.5],[164.5,-106.5],[174.75,-87.75],[157.5,-99.75],[112.5,-94],[114.25,-62],[134.5,-48.5],[129,-36],[123.25,-19.25],[130.75,-5.5],[146.75,-18.75],[162.5,-33.5],[169.5,-45.75],[176.25,-22.75],[149.5,-4.25],[127.75,20.75],[110,31.5],[90,51.25],[70,73.75],[66,92],[108,69.25],[116,51],[136.5,46.75],[140,31.75],[182.75,18.5],[204.75,-20.25],[204.75,-46],[222.25,-67.75],[230,-86],[239.25,-114.5],[218.75,-141],[199.25,-148.5],[171.5,-176.75],[145.25,-176.75],[130,-176.75],[120.25,-165.25],[100.25,-163.75],[87.75,-159.75],[66,-157.25],[67.25,-142.25],[44.5,-126.75],[28,-126],[15.5,-131.5],[3.75,-132.75],[-4.25,-139.75],[-10.75,-139.75],[-23,-156.5],[-41.75,-163.75]],\"c\":true}],\"e\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[23.666,-4.733],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[-5.753,-0.846],[-3.456,-2.925],[0,0],[1.106,18.528],[0,0],[3.5,17.25],[0,0],[-3.451,6.903],[3.486,4.183],[-8.825,5.711],[0,0],[-16.259,-12.646],[0,0],[-8,1.75],[0,0],[-6.965,-5.894],[-3.973,-8.513],[-6,-2],[-5.96,5.754],[0,0],[-13.621,1.513],[0,0],[-10.021,4.432],[0.095,5.505],[-4.5,0],[-42.5,-3],[0,0],[13.324,4.877],[6.75,-10.75],[-33.25,-3.5],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-11,4],[0,0],[-3.25,-10.25],[12.25,-5.25],[0,0],[11.302,-9.247],[4,-1.5],[4.5,-9.25],[-9.5,-6],[-4.5,16.75],[0,0],[-10.5,11.25],[0,0],[-24.5,19.75],[2.75,9.25],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[11.616,-4.937],[0,0],[7.25,1],[0,0],[5.447,-3.915],[0,0],[11.597,-4.481],[0,0],[10.556,4.59],[0,0],[9.25,-0.75],[0,0],[15.169,11.507],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-35,7],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[8.5,1.25],[6.5,5.5],[9.25,-0.25],[-2,-33.5],[0,0],[-3.5,-17.25],[0,0],[4.75,-9.5],[0,0],[8.5,-5.5],[0,0],[4.5,3.5],[0,0],[9.01,-1.971],[0,0],[9.75,8.25],[3.5,7.5],[5.929,1.976],[7.25,-7],[0,0],[13.5,-1.5],[0,0],[13,-5.75],[-0.25,-14.5],[8.31,0],[38.666,2.729],[0,0],[-28,-10.25],[-6.75,10.75],[12.326,1.298],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[7.566,-2.751],[0,0],[2.628,8.29],[-12.25,5.25],[0,0],[-11,9],[-4,1.5],[-4.5,9.25],[4.563,2.882],[0.598,-2.226],[0,0],[11.75,-12.589],[0,0],[24.5,-19.75],[-5.632,-18.945],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-10,4.25],[0,0],[-7.25,-1],[0,0],[-8,5.75],[0,0],[-11,4.25],[0,0],[-11.5,-5],[0,0],[-8.253,0.669],[0,0],[-14.5,-11],[0,0]],\"v\":[[-83.75,-180],[-106.5,-171],[-126.25,-164],[-135.25,-146.5],[-164.5,-144.5],[-202,-120.75],[-220.75,-106],[-216.75,-74.25],[-227.5,-34],[-194.25,-8],[-173.75,2.75],[-154.25,21.25],[-148.75,44],[-131,50.75],[-148,20.25],[-149.75,2],[-140,1.5],[-132.5,5.25],[-122.5,5],[-104.25,14.25],[-91,-8.5],[-123.5,-62.25],[-121.5,-95.5],[-144,-115.75],[-131.75,-121.5],[-126.25,-136.75],[-105.5,-137.5],[-91.75,-152.25],[-83.5,-123.5],[-68,-117.5],[-47.5,-118.25],[-20.5,-132.25],[-12.25,-114.25],[-1,-97],[14,-83],[29.75,-101.5],[45.75,-114.25],[71,-101],[93.5,-105.25],[114,-111.25],[122.25,-128.5],[127.5,-147.5],[173.5,-133],[185.25,-81.25],[164.5,-102.25],[118,-91],[145.25,-64.5],[142.5,-51.5],[139,-35.5],[130.75,-23.25],[137.25,-11.5],[145.75,-28.25],[169,-33.5],[181,-56.25],[179.25,-25.25],[168,3.75],[145.75,30.25],[127,39.5],[114.5,60.75],[84.5,62.75],[85.5,84],[113.5,68.25],[115,68],[142.5,57.75],[149,34.75],[191.75,18.5],[210.75,-34.75],[199.25,-56],[224.25,-60.75],[225.5,-92.5],[236.75,-118],[220.25,-147],[188.75,-156.5],[169,-173.75],[140.25,-167.75],[127,-169.75],[121.25,-157.25],[106.75,-156.75],[106.25,-156.75],[88.5,-152.75],[83.25,-137.75],[59.5,-139.25],[46.5,-119],[31.5,-134],[12.75,-138.75],[-4.25,-139.75],[-18.25,-134.75],[-30.5,-154],[-51.75,-154.25]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 23\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.75,2.5],[2.75,-6.625],[-6.375,0],[-2.875,6.25]],\"o\":[[-3.75,-2.5],[-2.75,6.625],[6.375,0],[2.875,-6.25]],\"v\":[[61.125,-3.375],[45.375,4.375],[45.875,20.625],[61.375,9.375]],\"c\":true}],\"e\":[{\"i\":[[0.499,0.333],[0.366,-0.881],[-0.848,0],[-0.382,0.831]],\"o\":[[-0.499,-0.333],[-0.366,0.881],[0.848,0],[0.382,-0.831]],\"v\":[[49.836,-0.797],[47.741,-0.199],[48.339,1.63],[50.368,0.799]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":15,\"s\":[0,0],\"h\":1},{\"t\":16,\"s\":[100,100],\"h\":1},{\"t\":20,\"s\":[0,0],\"h\":1}],\"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 9\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[18.934,5.164],[12.016,-5.06],[0,0],[7.451,1.765],[5.645,-0.226],[8.945,-6.665],[0,0],[3.262,5.811],[4.317,4.176],[8.725,3.611],[3.199,1.087],[3.063,0.78],[3.171,0.415],[1.81,-0.109],[0,0],[1.157,0.458],[3.871,0.977],[29.142,-11.922],[4.627,-7.197],[0.375,-1.333],[0,0],[13,-29.5],[0,0],[-23,-39],[0,0],[-16,-9],[-7.135,-0.67],[-1.267,-0.023],[0,0],[-0.432,-0.986],[-0.407,-0.855],[-0.265,-0.527],[-0.148,-0.286],[-1.643,-2.364],[-1.437,-1.437],[-3.036,-1.535],[-0.155,-0.076],[-0.051,-0.025],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-30,23],[0,0],[-20,9.5],[0,0],[-7,12],[-0.795,3.115],[-0.216,2.726],[0.096,1.897],[0,0],[-29.425,54.272],[0,0],[-3.315,6.41],[4.925,18.605],[0,0],[6.451,10.777]],\"o\":[[-22.018,-6.005],[-8.995,3.788],[0,0],[-4.31,-1.021],[-8.324,0.333],[-25.5,19],[0,0],[-2.036,-3.627],[-4.834,-4.676],[-3.662,-1.515],[-3.671,-1.247],[-4.464,-1.138],[-4.901,-0.642],[-1.06,0.064],[0,0],[-1.686,-0.668],[-12.803,-3.233],[-26.494,10.838],[-1.791,2.785],[-0.265,0.943],[0,0],[-13,29.5],[0,0],[23,39],[0,0],[9.867,5.55],[2.536,0.238],[0.949,0.017],[0,0],[0.264,0.602],[0.224,0.471],[0.137,0.273],[1.119,2.164],[1.214,1.747],[5.421,5.421],[0.248,0.125],[0.075,0.037],[0.045,0.022],[0,0],[0,0],[8,12],[0,0],[12.5,5],[0,0],[30,-23],[0,0],[20,-9.5],[0,0],[1.684,-2.887],[0.783,-3.067],[0.263,-3.309],[-0.078,-1.551],[0,0],[22.5,-41.5],[0,0],[4.007,-7.746],[-9,-34],[0,0],[-6.242,-10.429]],\"v\":[[164.5,-192],[111.719,-188.32],[97.5,-180.5],[85.228,-184.887],[70.084,-186.417],[43.5,-177],[18,-143.5],[13.904,-153.572],[4.567,-165.607],[-15.5,-178.5],[-25.791,-182.386],[-35.892,-185.402],[-47.344,-187.652],[-57.41,-188.155],[-59,-188],[-60.761,-188.751],[-69.176,-191.415],[-135,-185.5],[-177.205,-156.264],[-180.194,-149.959],[-180.5,-148.5],[-230.5,-120],[-236,-60.5],[-227,9],[-170.5,50],[-138,87],[-109.8,95.157],[-103.974,95.496],[-102.5,95.5],[-101.838,97.075],[-100.828,99.282],[-100.095,100.783],[-99.667,101.622],[-95.49,108.635],[-91.5,113.5],[-73.449,125.529],[-72.842,125.833],[-72.654,125.925],[-72.548,125.977],[-72.5,126],[-70,157],[-44,176.5],[-28.5,196.5],[-1.5,193.5],[47.5,178.5],[72,132.5],[116.5,127],[132.5,101],[170.5,81],[174.143,71.85],[175.569,63.021],[175.689,54.963],[175.5,52.5],[245.5,6],[237.5,-64.5],[244.608,-73.882],[247,-113],[208.5,-144.5],[200.629,-164.834]],\"c\":true}],\"e\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}],\"e\":[{\"i\":[[8.864,2.813],[7.079,-1.354],[0,0],[13.094,-1.21],[-0.018,-0.843],[5.661,-2.668],[0,0],[17.71,1.266],[12.336,3.848],[0.25,0.75],[9.83,8.017],[0.562,0.657],[25.725,4.726],[9.831,-6.216],[0,0],[-3.032,3.853],[0.747,8.445],[15.471,-6.395],[-7.536,-6.601],[-7.961,-1.468],[0,0],[21.655,-23.881],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.08,3.361],[7.074,6.982],[0,0],[-14.244,-1.531],[-5.859,-7.626],[1.287,-2.776],[3.373,-0.392],[0.886,-6.879],[-1.961,-1.267],[-3.784,12.826],[-2.09,4.283],[-1.499,-0.451],[-0.354,-4.451],[0,0],[-12.5,-20.75],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-6.505,6.505],[0,0],[-20.995,16.055],[-8.207,7.28],[-0.548,0.003],[-6.236,1.925],[0,0],[-27.024,42.787],[0,0],[-9.085,17.825],[3.883,14.669],[0,0],[8.143,11.01]],\"o\":[[-13.759,-4.366],[-19.726,3.772],[0,0],[-8.945,0.827],[-0.018,-0.593],[-21.75,10.25],[0,0],[0.019,-0.088],[-13.81,-4.307],[0,-0.25],[-11.414,-9.308],[-0.688,-0.593],[-15.588,-2.864],[-11.425,7.224],[0,0],[3.287,-4.177],[-0.537,-6.071],[-17.147,7.088],[5.403,4.732],[6.094,1.124],[0,0],[-26.75,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[1.698,-2.743],[-5.053,-4.987],[0,0],[12.035,1.294],[4.522,5.885],[-0.856,1.846],[-10.422,1.211],[-1.075,8.345],[12,7.75],[0.432,-1.463],[1.255,-2.571],[3.219,0.968],[0.518,6.518],[0,0],[8.593,14.264],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[6.5,-6.5],[0,0],[6.447,-4.93],[7.537,-6.685],[1.977,-0.948],[9.61,-2.967],[0,0],[12,-19],[0,0],[6.894,-13.526],[-9,-34],[0,0],[-4.511,-6.1]],\"v\":[[166,-182],[142.226,-178.772],[118.5,-165.75],[104.445,-167.327],[90.018,-161.407],[69.5,-161.5],[61.75,-141],[32.731,-125.412],[11.06,-137.943],[-10.25,-140],[-20.586,-156.942],[-42.062,-164.657],[-72.225,-184.726],[-105.941,-167.407],[-135.75,-154],[-143.677,-157.193],[-127.997,-171.695],[-157.25,-175],[-173.153,-153.482],[-148.789,-155.532],[-149,-149.25],[-215.5,-124.5],[-231.25,-78.25],[-217.75,-1.25],[-155,30],[-140.25,62],[-112.259,65.765],[-115.824,47.268],[-128.5,39],[-102.285,44.956],[-77.909,55.814],[-69.342,69.609],[-76.446,71.481],[-95.214,83.819],[-87.5,98.25],[-64.716,90.174],[-64.128,77.554],[-56.682,75.116],[-49.105,84.318],[-52.5,97.5],[-46,142.75],[-29,152.25],[-20.5,164.5],[-4,161.25],[18.5,154.5],[42,124],[58,116.25],[59.5,98.75],[93,83.75],[108.207,71.72],[123.048,55.997],[136.065,57.709],[151.75,42.25],[204,5.75],[209.5,-42.75],[227.03,-63.49],[244.75,-108.75],[200.25,-150],[181.607,-169.76]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[-28,-15.25],[0,0],[-15.75,9.5],[0,0],[-10.5,-4.25],[0,0],[-0.25,-4.75],[0,0],[6,0],[0,0],[10.25,-9.5],[-1.75,-8],[0,0],[10.25,-0.75],[0,0],[2,10.5],[0,0],[17.75,4.5],[5,-3.5],[0,0],[2.5,4],[0,0],[-0.75,7.5],[-4.25,8.75]],\"o\":[[0,0],[28,15.25],[0,0],[15.75,-9.5],[0,0],[10.5,4.25],[0,0],[0.25,4.75],[0,0],[-6,0],[0,0],[-10.25,9.5],[1.75,8],[0,0],[-10.25,0.75],[0,0],[-2,-10.5],[0,0],[-17.75,-4.5],[-5,3.5],[0,0],[-2.5,-4],[0,0],[0.75,-7.5],[4.25,-8.75]],\"v\":[[-50.5,-75.25],[-29.75,-39.75],[19.25,-34.75],[50.75,-41.75],[69,-59.75],[91,-37.75],[107,-23.75],[99.75,-11.75],[99.75,1.25],[84.75,-4.75],[76,-0.25],[55.25,0.5],[42,23],[45,39.5],[19,35.25],[-10.25,39],[-9,14.75],[-18.25,-1.5],[-32.25,-27.5],[-63.25,-21.75],[-71.25,-6.25],[-73.5,-14.75],[-83,-20.25],[-66.5,-33.75],[-62.25,-65.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.074,0.04],[0,0],[0.041,-0.025],[0,0],[0.028,0.011],[0,0],[0.001,0.012],[0,0],[-0.016,0],[0,0],[-0.027,0.025],[0.005,0.021],[0,0],[-0.027,0.002],[0,0],[-0.005,-0.028],[0,0],[-0.047,-0.012],[-0.013,0.009],[0,0],[-0.007,-0.011],[0,0],[0.002,-0.02],[0.011,-0.023]],\"o\":[[0,0],[-0.074,-0.04],[0,0],[-0.041,0.025],[0,0],[-0.028,-0.011],[0,0],[-0.001,-0.012],[0,0],[0.016,0],[0,0],[0.027,-0.025],[-0.005,-0.021],[0,0],[0.027,-0.002],[0,0],[0.005,0.028],[0,0],[0.047,0.012],[0.013,-0.009],[0,0],[0.007,0.011],[0,0],[-0.002,0.02],[-0.011,0.023]],\"v\":[[12.164,-17.724],[12.11,-17.817],[11.981,-17.831],[11.898,-17.812],[11.85,-17.765],[11.792,-17.823],[11.75,-17.86],[11.769,-17.891],[11.769,-17.925],[11.809,-17.91],[11.832,-17.921],[11.886,-17.923],[11.921,-17.983],[11.913,-18.026],[11.982,-18.015],[12.059,-18.025],[12.055,-17.961],[12.08,-17.918],[12.116,-17.85],[12.198,-17.865],[12.219,-17.906],[12.225,-17.883],[12.25,-17.869],[12.207,-17.833],[12.195,-17.75]],\"c\":true}]},{\"t\":15}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.125,0.057],[0,0],[0.038,-0.016],[0,0],[0.063,-0.035],[0,0],[0.061,0.023],[0,0.05],[-0.003,0.025],[0,0],[-0.031,0.004],[0,0],[-0.05,0.025],[-0.01,0.057],[0,0],[0.019,0.048],[0,0],[-0.02,0.051],[0,0],[-0.023,-0.034],[0,0],[0.009,-0.101],[-0.038,0.016],[0,0],[-0.02,-0.019],[0,0],[-0.023,-0.047],[0,0],[-0.128,0.007],[0.003,0.025],[0,0],[-0.034,-0.034],[0,0],[0.023,-0.09],[0.028,-0.051]],\"o\":[[0,0],[-0.125,-0.057],[0,0],[-0.038,0.016],[0,0],[-0.063,0.035],[0,0],[-0.061,-0.023],[0,-0.05],[0.003,-0.025],[0,0],[0.031,-0.004],[0,0],[0.05,-0.025],[0.01,-0.057],[0,0],[-0.019,-0.048],[0,0],[0.02,-0.051],[0,0],[0.023,0.034],[0,0],[-0.009,0.101],[0.038,-0.016],[0,0],[0.02,0.019],[0,0],[0.023,0.047],[0,0],[0.128,-0.007],[-0.003,-0.025],[0,0],[0.034,0.034],[0,0],[-0.023,0.09],[-0.028,0.051]],\"v\":[[10.723,4.496],[10.612,4.271],[10.433,4.229],[10.313,4.238],[10.272,4.29],[10.125,4.315],[10.008,4.395],[9.924,4.296],[9.791,4.147],[9.848,4.052],[9.857,4.001],[9.965,4.025],[10.049,3.991],[10.096,4.034],[10.198,3.937],[10.14,3.873],[10.166,3.78],[10.11,3.706],[10.186,3.612],[10.239,3.5],[10.262,3.579],[10.317,3.614],[10.183,3.708],[10.38,3.802],[10.459,3.77],[10.479,3.809],[10.529,3.832],[10.527,3.971],[10.573,4.06],[10.699,4.128],[10.841,4.044],[10.832,4],[10.877,4.079],[10.959,4.13],[10.826,4.268],[10.787,4.449]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}],\"e\":[{\"i\":[[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,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]],\"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],[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]],\"v\":[[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4]],\"c\":true}]},{\"t\":16}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.022,0.041],[0,0],[-0.044,0.022],[0,0],[0.015,-0.081]],\"o\":[[0,0],[-0.022,-0.041],[0,0],[0.044,-0.022],[0,0],[-0.015,0.081]],\"v\":[[-66.087,51.996],[-66.157,51.959],[-66.25,51.904],[-66.168,51.885],[-66.083,51.8],[-66.106,51.881]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.004,-0.043],[0,0],[0.045,0.015],[0,0],[-0.034,0.023]],\"o\":[[0,0],[-0.004,0.052],[0,0],[-0.053,-0.018],[0,0],[0.061,-0.041]],\"v\":[[-54.598,33.581],[-54.607,33.711],[-54.571,33.906],[-54.697,33.794],[-54.742,33.729],[-54.698,33.67]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-0.005,-0.001],[-0.001,0.001],[0,0],[0.001,-0.002],[-0.023,-0.015],[0,0],[-0.005,0.008],[0,0.002],[0,0],[-0.003,0],[-0.007,0.006],[-0.004,0.003],[0,0],[-0.013,-0.005],[0,0],[-0.004,-0.006],[0,0],[0.005,-0.009],[0,-0.003],[0,0],[0.001,0],[0.004,0],[0.009,-0.004],[0,0.006],[0.002,-0.004],[0.005,-0.01],[-0.003,-0.004],[0,0],[0.002,-0.006],[0,0],[0.004,-0.006],[0.001,-0.002],[0,0],[0,-0.001],[0,-0.001],[0,0],[0,0],[0,0],[0,0],[0.002,0.006],[0,0],[0.001,0.01],[0.007,-0.001],[0,0],[0.005,0.001],[0.002,0],[0,0],[0.011,0.017],[0.013,0],[0,0],[0.001,-0.006],[0,0],[0,0],[0.007,0.006],[0,0],[0.003,0.005],[0,0],[-0.003,0.011],[0,0],[-0.003,0.009]],\"o\":[[0,0],[0.004,0.001],[0,0],[0,0],[-0.003,0.008],[0.03,0.019],[0,0],[0.004,-0.005],[0,-0.001],[0,0],[0.008,-0.001],[0.005,-0.004],[0.003,-0.003],[0,0],[0.013,0.005],[0,0],[0.004,0.006],[0,0],[-0.002,0.004],[0,0.003],[0,0],[-0.002,0],[-0.008,-0.001],[-0.016,0.006],[0,-0.006],[-0.002,0.004],[-0.005,0.01],[0.003,0.004],[0,0],[-0.002,0.006],[0,0],[-0.001,0.002],[0,0],[0,0.001],[-0.001,0.001],[0,0],[0,0],[0,0],[0,0],[0.001,-0.004],[-0.003,-0.008],[0,0],[-0.001,-0.01],[-0.007,0.001],[0,0],[-0.004,-0.001],[-0.001,0],[0,0],[-0.011,-0.017],[-0.013,0],[0,0],[-0.001,0.006],[0,0],[-0.002,-0.003],[-0.008,-0.007],[0,0],[-0.003,-0.005],[0,0],[0.003,-0.011],[0,0],[0.003,-0.009]],\"v\":[[9.302,5.518],[9.307,5.522],[9.313,5.52],[9.314,5.52],[9.312,5.523],[9.33,5.564],[9.367,5.573],[9.388,5.572],[9.393,5.561],[9.393,5.559],[9.397,5.559],[9.43,5.551],[9.444,5.539],[9.449,5.534],[9.467,5.558],[9.489,5.572],[9.493,5.589],[9.5,5.591],[9.487,5.608],[9.484,5.618],[9.484,5.623],[9.483,5.623],[9.475,5.622],[9.446,5.625],[9.436,5.626],[9.418,5.64],[9.425,5.65],[9.425,5.67],[9.433,5.678],[9.419,5.695],[9.417,5.709],[9.408,5.717],[9.404,5.723],[9.404,5.725],[9.402,5.727],[9.401,5.73],[9.401,5.731],[9.4,5.732],[9.4,5.731],[9.401,5.73],[9.401,5.71],[9.393,5.695],[9.404,5.677],[9.38,5.667],[9.365,5.671],[9.358,5.664],[9.345,5.663],[9.345,5.663],[9.338,5.62],[9.305,5.602],[9.292,5.614],[9.285,5.622],[9.291,5.642],[9.291,5.641],[9.277,5.621],[9.263,5.613],[9.258,5.599],[9.25,5.588],[9.277,5.575],[9.283,5.553],[9.294,5.531]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.5,-3.25],[-8.083,-4.093],[0,0],[5.225,-1.81],[-10.076,-17.051],[0,0],[-4.25,6.5],[2.192,7.761],[0,0],[-5.285,-1.77],[-9.617,3.023],[-7.065,13.364],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[-2.345,-3.979],[0,0],[5.1,-5.315],[-0.891,1.119],[11,-1],[5.076,-2.343],[0.981,-0.196],[0.317,-9.834],[-6,-5.75],[0,0],[3.117,-4.572],[0,0],[3.315,-5.461],[0.004,-0.142],[3.538,3.662],[6.177,1.037],[7.159,1.756],[6.076,4.663],[0,0],[0.268,2.167],[-1.669,-1.529],[-12.757,3.744],[0,0],[0.5,8.5],[6,4.75],[0,0],[12.25,3.25],[4.665,8.641],[0,0],[1.804,17.317],[11,0],[0,0],[-1.078,-4.792],[0,0],[7.696,-4.137],[11.048,13.67],[0,0],[6.716,15.802],[0,0],[-8.75,8.5],[0,0],[-1.848,8.102]],\"o\":[[0,0],[2.721,1.179],[6.999,3.545],[0,0],[-9.722,3.368],[6.5,11],[0,0],[2.56,-3.915],[-1.447,-5.123],[0,0],[7.507,2.515],[7.991,-2.512],[7.121,-13.47],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.767,3.043],[3.627,6.153],[0,0],[-7.721,8.046],[4.699,-5.902],[-14.287,1.299],[-3.25,1.5],[0.5,0.25],[-0.25,7.75],[3.254,3.118],[0,0],[-7.5,11],[0,0],[-2.732,4.499],[0.001,0.02],[-4.471,-4.629],[-6.724,-1.129],[-4.847,-1.189],[-10.206,-7.834],[0,0],[-0.293,-2.368],[7.64,6.999],[6.682,-1.961],[0,0],[-0.5,-8.5],[-4.614,-3.652],[0,0],[-9.452,-2.508],[-1.955,-3.621],[0,0],[-1.25,-12],[-11,0],[0,0],[2.25,10],[0,0],[-9.622,5.171],[-5.56,-6.88],[0,0],[-8.5,-20],[0,0],[7.177,-6.972],[0,0],[3.25,-14.25]],\"v\":[[-55.25,-99],[-38,-102.5],[-26.499,-92.295],[-11,-85.75],[-16.181,-80.022],[-27.25,-57.5],[-9,-52.75],[9.75,-54],[-3.88,-73.713],[3.25,-80.5],[12.303,-78.912],[49.75,-76],[79.565,-93.114],[107.75,-102.75],[96.5,-67],[114.75,-52],[127.75,-39.5],[127.25,-24.75],[114,-12],[109.472,3.722],[125.5,11],[112.338,18.324],[99.729,37.643],[91,9.5],[73.5,13.5],[70.25,20.75],[65.5,31.5],[72.75,46.5],[94,43],[67.25,65.25],[56,93.25],[44.25,104.75],[39.746,121.392],[31.212,126.088],[14.486,118.584],[-9.366,124.723],[-25.155,109.278],[-43.5,97.5],[-45.859,91.202],[-40.39,89.001],[-14.5,94],[-3.25,84.5],[1.25,73.75],[-7.5,59],[-18.75,57.25],[-30.75,52.25],[-41.665,32.609],[-37.25,20.25],[-30.25,5.25],[-46.25,-5.25],[-58.5,-0.75],[-59.25,8],[-49.313,14.25],[-53.696,28.137],[-92.25,33.5],[-107.75,19],[-104.5,-19.25],[-112,-57.25],[-88.75,-44.25],[-72,-69.5],[-65.5,-81.75]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.04,-0.009],[-0.019,-0.009],[0.026,-0.016],[0.026,-0.028],[0,0],[0.019,0.068]],\"o\":[[0.04,0.009],[0.019,0.009],[-0.026,0.016],[-0.026,0.028],[0,0],[-0.016,-0.058]],\"v\":[[-51.449,39.759],[-51.357,39.815],[-51.332,39.874],[-51.435,39.914],[-51.509,40],[-51.533,39.818]],\"c\":true}],\"e\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}],\"e\":[{\"i\":[[-5.84,0.724],[-2.429,-1.796],[2.794,-3.365],[2.214,-5.016],[0,0],[8.09,15.052]],\"o\":[[5.84,-0.724],[5.929,4.383],[-2.794,3.365],[-2.214,5.016],[0,0],[-4.108,-7.644]],\"v\":[[-62.831,35.704],[-44.679,38.617],[-41.313,54.729],[-46.827,64.288],[-57.43,67.573],[-72.59,55.198]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.104,-0.071],[0.086,0.038],[0.145,0.005],[0,0],[0.014,0.093],[0,0],[-0.123,0.023],[0,0]],\"o\":[[0.12,0.081],[-0.035,-0.016],[-0.145,-0.005],[0,0],[-0.014,-0.093],[0,0],[0.123,-0.023],[0,0]],\"v\":[[-82.663,-101.709],[-82.586,-101.615],[-82.846,-101.602],[-83.042,-101.565],[-83.224,-101.565],[-83.137,-101.671],[-82.993,-101.705],[-82.858,-101.698]],\"c\":true}],\"e\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}],\"e\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}],\"e\":[{\"i\":[[-8.912,-4.564],[3.5,-16.5],[11.5,-1],[0,0],[2,7.25],[0,0],[-9.5,3],[0,0]],\"o\":[[10.25,5.25],[-3.5,16.5],[-11.5,1],[0,0],[-2,-7.25],[0,0],[9.5,-3],[0,0]],\"v\":[[-83.5,-123],[-54.25,-109.75],[-90,-99.5],[-111.75,-81],[-115,-103.5],[-125.75,-114.5],[-109.25,-119],[-99,-126]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[5.5,0],[-3.75,-7.75],[-5,5.25],[3.5,2]],\"o\":[[-5.5,0],[3.75,7.75],[5,-5.25],[-3.5,-2]],\"v\":[[64.25,-40.75],[59,-26.75],[76.25,-25.75],[74.25,-37.75]],\"c\":true}],\"e\":[{\"i\":[[-0.106,0],[0.072,0.149],[0.096,-0.101],[-0.067,-0.038]],\"o\":[[0.106,0],[-0.072,-0.149],[-0.096,0.101],[0.067,0.038]],\"v\":[[72.077,-31.166],[72.178,-31.435],[71.846,-31.454],[71.885,-31.224]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":13,\"s\":[0,0],\"h\":1},{\"t\":14,\"s\":[100,100],\"h\":1},{\"t\":21,\"s\":[0,0],\"h\":1}],\"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 8\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-40.51,7.147],[0,0],[-17.338,-13.577],[0,0],[-8.296,0],[0,0],[-26.663,15.973],[0,0],[-33.95,-10.778],[0,0],[-21.615,-37.512],[0,0],[8.98,-29.643],[0,0],[16.078,-18.847],[0,0],[19.91,-14.379],[0,0],[9.955,-9.125],[0,0],[16.722,-12.243],[0,0],[18.514,-5.056],[0,0],[9.125,-0.553],[0,0],[18.949,11.815],[0,0],[16.315,12.72],[0,0],[23.953,16.773],[0,0],[11.973,13.619],[0,0],[6.913,32.077],[0,0],[-4.701,15.209],[0,0],[-10.231,17.145],[0,0],[-9.402,7.743],[0,0]],\"o\":[[43.349,-7.648],[0,0],[17.031,13.336],[0,0],[3.739,0],[0,0],[17.54,-10.508],[0,0],[33.43,10.613],[0,0],[16.117,27.97],[0,0],[-7.619,25.151],[0,0],[-16.113,18.888],[0,0],[-19.91,14.379],[0,0],[-9.955,9.125],[0,0],[-16.624,12.172],[0,0],[-14.931,4.078],[0,0],[-9.125,0.553],[0,0],[-22.801,-14.217],[0,0],[-16.315,-12.72],[0,0],[-19.543,-13.685],[0,0],[-14.781,-16.813],[0,0],[-6.913,-32.077],[0,0],[4.701,-15.209],[0,0],[10.231,-17.145],[0,0],[9.402,-7.743],[0,0]],\"v\":[[-122.349,-200.852],[-67.036,-197.802],[-29.531,-189.336],[-8.428,-159.127],[5.686,-161.605],[12.864,-156.627],[42.96,-187.992],[81.916,-196.269],[137.57,-196.113],[183.871,-164.877],[232.883,-120.97],[241.361,-65.366],[240.52,-14.357],[219.652,17.144],[204.113,62.612],[179.151,78.022],[158.805,108.917],[131.471,116.361],[108.784,144.6],[82.14,158.301],[67.624,177.828],[43.385,190.688],[24.986,203.556],[3.47,204.704],[-15.345,210.947],[-32.448,201.14],[-56.949,189.685],[-78.783,151.211],[-100.318,142.161],[-117.198,116.933],[-155.953,98.227],[-179.067,65.84],[-206.973,51.381],[-217.527,16.527],[-241.967,-19.72],[-239.542,-62.358],[-241.872,-94.094],[-219.588,-110.856],[-217.027,-145.422],[-189.511,-163.714],[-181.673,-176.147],[-165.9,-178.912]],\"c\":true}],\"e\":[{\"i\":[[-41.027,10.852],[0,0],[-32.19,-17.46],[0,0],[-0.18,0.259],[0,0],[-27.898,13.394],[0,0],[-45.894,-13.697],[0,0],[-15.016,-36.577],[0,0],[5.71,-33.936],[0,0],[21.4,-13.403],[0,0],[17.976,-16.121],[0,0],[10.092,-8.239],[0,0],[19.309,-16.744],[0,0],[19.25,-9.223],[0,0],[12.239,3.847],[0,0],[15.375,17.378],[0,0],[11.519,13.671],[0,0],[24.516,15.038],[0,0],[12.163,12.071],[0,0],[6.597,28.03],[0,0],[-1.353,14.044],[0,0],[-16.709,12.856],[0,0],[-8.214,8.547],[0,0]],\"o\":[[44.248,-11.704],[0,0],[18.544,10.058],[0,0],[-0.18,0.259],[0,0],[18.352,-8.811],[0,0],[38.632,11.53],[0,0],[13.202,32.158],[0,0],[-3.833,22.781],[0,0],[-19.873,12.446],[0,0],[-19.185,17.206],[0,0],[-19.586,15.988],[0,0],[-11.367,9.857],[0,0],[-14.319,6.86],[0,0],[-20.345,-6.395],[0,0],[-17.652,-19.952],[0,0],[-13.005,-15.434],[0,0],[-20.002,-12.269],[0,0],[-15.015,-14.901],[0,0],[-6.597,-28.03],[0,0],[1.428,-14.823],[0,0],[14.517,-11.169],[0,0],[11.131,-11.582],[0,0]],\"v\":[[-115.248,-190.796],[-59.008,-190.107],[-10.81,-172.04],[19.517,-144.869],[19.18,-146.759],[19.528,-146.795],[54.253,-183.013],[96.25,-182.982],[162.394,-192.803],[206.803,-147.766],[248.798,-114.658],[238.601,-66.134],[250.833,-17.781],[241.164,16.728],[212.1,46.403],[176.142,53.42],[165.685,84.794],[131.081,97.874],[119.086,124.512],[72.746,132.43],[64.367,162.143],[42.534,175.875],[17.75,190.723],[-3.557,191.818],[-24.655,195.895],[-44.198,175.545],[-65.375,158.622],[-72.314,125.748],[-87.019,114.329],[-103.831,93.1],[-142.713,85.645],[-170.687,49.612],[-206.339,36.512],[-226.657,9.999],[-241.335,-25.987],[-238.074,-63.029],[-240.428,-90.677],[-234.051,-113.839],[-215.291,-138.856],[-184.468,-150.252],[-177.631,-164.918],[-158.245,-175.028]],\"c\":true}]},{\"t\":14}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[3.25,0],[0,0],[-0.5,-7],[0,0],[-5.5,-1.25],[0,0],[-2.5,7.75],[0,0],[6,0],[0,0],[1.75,-2.75],[0.75,5.5]],\"o\":[[0,0],[-3.25,0],[0,0],[0.5,7],[0,0],[5.5,1.25],[0,0],[2.5,-7.75],[0,0],[-6,0],[0,0],[-1.75,2.75],[-0.75,-5.5]],\"v\":[[10.25,-12.5],[2.5,-9.25],[-3.25,-9],[0.25,6.25],[-1.5,20],[11.5,22.25],[20.75,27.75],[24.75,15],[41.75,-3],[30.75,-6.75],[20.75,-8.25],[21.5,1.25],[9,-1.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.108,0],[0,0],[0.017,0.197],[0,0],[0.183,0.035],[0,0],[0.083,-0.219],[0,0],[-0.2,0],[0,0],[-0.058,0.078],[-0.025,-0.155]],\"o\":[[0,0],[0.108,0],[0,0],[-0.017,-0.197],[0,0],[-0.183,-0.035],[0,0],[-0.083,0.219],[0,0],[0.2,0],[0,0],[0.058,-0.078],[0.025,0.155]],\"v\":[[19.55,8.193],[19.808,8.101],[20,8.094],[19.883,7.664],[19.942,7.276],[19.508,7.212],[19.2,7.057],[19.067,7.417],[18.5,7.925],[18.867,8.03],[19.2,8.073],[19.175,7.805],[19.592,7.882]],\"c\":true}]},{\"t\":10}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.064,0.03],[0.037,0.036],[0,0],[0.094,-0.005],[0,0],[0.034,-0.041],[0,0],[0.003,-0.023],[0,0],[-0.014,0],[0,0],[-0.057,0.03],[0,0],[-0.022,0.001],[0,0],[-0.007,-0.022]],\"o\":[[0.064,-0.03],[-0.037,-0.036],[0,0],[-0.094,0.005],[0,0],[-0.034,0.041],[0,0],[-0.003,0.023],[0,0],[0.014,0],[0,0],[0.057,-0.03],[0,0],[0.022,-0.001],[0,0],[0.007,0.022]],\"v\":[[15.686,3.128],[15.702,2.98],[15.653,2.842],[15.507,2.878],[15.377,2.865],[15.343,2.944],[15.269,2.975],[15.272,3.015],[15.25,3.072],[15.283,3.074],[15.344,3.115],[15.374,3.045],[15.463,3.052],[15.501,3.031],[15.54,3.041],[15.561,3.087]],\"c\":true}],\"e\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}],\"e\":[{\"i\":[[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]],\"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]],\"v\":[[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14]],\"c\":true}]},{\"t\":11}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.059,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.17],[0,0],[0.193,-0.003],[0,0],[0.094,-0.181],[0,0],[0.023,-0.059],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.059,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.17],[0,0],[-0.193,0.003],[0,0],[-0.094,0.182],[0,0],[-0.023,0.059],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.749],[28.945,-0.819],[29.012,-0.842],[28.992,-0.998],[29.214,-0.945],[29.346,-0.951],[29.434,-0.854],[29.583,-0.851],[29.697,-0.796],[29.706,-0.898],[29.75,-0.989],[29.607,-1.244],[29.601,-1.501],[29.279,-1.434],[28.971,-1.472],[28.901,-1.229],[28.582,-1.1],[28.523,-1.015],[28.5,-0.878],[28.775,-0.939]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.058,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.169],[0,0],[0.193,-0.003],[0,0],[0.093,-0.181],[0,0],[0.023,-0.058],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.058,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.169],[0,0],[-0.193,0.003],[0,0],[-0.093,0.181],[0,0],[-0.023,0.058],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.75],[28.946,-0.82],[29.013,-0.843],[28.992,-0.998],[29.214,-0.946],[29.345,-0.951],[29.433,-0.855],[29.582,-0.852],[29.696,-0.797],[29.704,-0.899],[29.748,-0.989],[29.605,-1.243],[29.599,-1.5],[29.278,-1.433],[28.972,-1.471],[28.902,-1.229],[28.584,-1.1],[28.525,-1.016],[28.502,-0.878],[28.776,-0.94]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.008,0.004],[0,0],[0.014,0.026],[-0.085,0.002],[0,0],[-0.017,0.014],[0,0],[-0.057,0.004],[0,0],[-0.053,-0.011],[0,0],[-0.001,0.014],[0,0],[0.033,0.05],[0,0],[0.033,0],[0,0],[0.115,-0.02],[0,0],[0,-0.02],[0,0],[-0.036,-0.017]],\"o\":[[0,0],[0.008,-0.004],[0,0],[-0.014,-0.026],[0.085,-0.002],[0,0],[0.017,-0.014],[0,0],[0.057,-0.004],[0,0],[0.053,0.011],[0,0],[0.001,-0.014],[0,0],[-0.033,-0.05],[0,0],[-0.033,0],[0,0],[-0.075,0.013],[0,0],[0,0.02],[0,0],[0.036,0.017]],\"v\":[[26.605,7.051],[26.632,7.031],[26.664,7.016],[26.567,6.967],[26.642,6.901],[26.718,6.986],[26.756,6.951],[26.803,6.935],[26.798,6.874],[26.844,6.92],[26.938,6.911],[27.037,6.945],[27.032,6.916],[27.044,6.884],[26.995,6.819],[26.969,6.667],[26.891,6.689],[26.783,6.666],[26.64,6.844],[26.501,6.807],[26.516,6.85],[26.501,6.926],[26.536,6.975]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.003,0.001],[0,0],[0.005,0.009],[-0.029,0.001],[0,0],[-0.006,0.005],[0,0],[-0.02,0.001],[0,0],[-0.018,-0.004],[0,0],[0,0.005],[0,0],[0.011,0.017],[0,0],[0.011,0],[0,0],[0.039,-0.007],[0,0],[0,-0.007],[0,0],[-0.012,-0.006]],\"o\":[[0,0],[0.003,-0.001],[0,0],[-0.005,-0.009],[0.029,-0.001],[0,0],[0.006,-0.005],[0,0],[0.02,-0.001],[0,0],[0.018,0.004],[0,0],[0,-0.005],[0,0],[-0.011,-0.017],[0,0],[-0.011,0],[0,0],[-0.026,0.005],[0,0],[0,0.007],[0,0],[0.012,0.006]],\"v\":[[21.286,5.989],[21.295,5.982],[21.306,5.977],[21.273,5.96],[21.299,5.937],[21.324,5.966],[21.338,5.955],[21.353,5.949],[21.352,5.928],[21.368,5.944],[21.4,5.941],[21.434,5.953],[21.432,5.943],[21.436,5.932],[21.419,5.91],[21.41,5.858],[21.384,5.865],[21.347,5.857],[21.298,5.918],[21.25,5.906],[21.255,5.92],[21.25,5.946],[21.262,5.963]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.005,0.026],[0,0],[0.02,0],[0,0],[-0.02,-0.025]],\"o\":[[0,0],[0.005,-0.026],[0,0],[-0.02,0],[0,0],[0.02,0.025]],\"v\":[[27.221,7.084],[27.23,7.031],[27.25,6.977],[27.211,6.996],[27.148,6.996],[27.199,7.032]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.002,0.009],[0,0],[0.007,0],[0,0],[-0.007,-0.009]],\"o\":[[0,0],[0.002,-0.009],[0,0],[-0.007,0],[0,0],[0.007,0.009]],\"v\":[[21.497,6],[21.499,5.982],[21.506,5.964],[21.493,5.97],[21.472,5.97],[21.489,5.982]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[-0.003,0.012],[0,0],[0.022,0],[0.014,0.004],[0,0],[0.003,0.01],[0,0],[0.024,0],[0,0],[0.014,-0.007],[0.002,-0.008],[0.01,0],[0,0],[0.005,0],[0,0],[0,-0.004],[0,0],[-0.008,-0.008],[0,0],[-0.02,0.013],[0,0],[-0.031,-0.014]],\"o\":[[0,0],[0.003,-0.012],[0,0],[-0.022,0],[-0.014,-0.004],[0,0],[-0.003,-0.01],[0,0],[-0.024,0],[0,0],[-0.005,0.003],[-0.002,0.008],[-0.01,0],[0,0],[-0.005,0],[0,0],[0,0.004],[0,0],[0.008,0.008],[0,0],[0.02,-0.013],[0,0],[0.031,0.014]],\"v\":[[25.23,5.825],[25.239,5.785],[25.25,5.763],[25.219,5.77],[25.184,5.766],[25.175,5.744],[25.16,5.728],[25.156,5.675],[25.117,5.683],[25.085,5.675],[25.081,5.703],[25.071,5.72],[25.057,5.731],[25.039,5.727],[25.029,5.729],[25,5.727],[25.005,5.742],[25.006,5.77],[25.026,5.786],[25.049,5.806],[25.084,5.775],[25.132,5.769],[25.183,5.773]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-8],[0,0],[-14.75,0],[-9.75,-2.5],[0,0],[-1.75,-6.75],[0,0],[-16.75,0],[0,0],[-9.75,4.75],[-1.5,5.75],[-7,0],[0,0],[-3.75,0],[0,0],[0,3],[0,0],[5.5,5.75],[0,0],[13.75,-9],[0,0],[21.25,9.5]],\"o\":[[0,0],[-2.25,8],[0,0],[14.75,0],[9.75,2.5],[0,0],[1.75,6.75],[0,0],[16.75,0],[0,0],[3.554,-1.731],[1.5,-5.75],[7,0],[0,0],[3.75,0],[0,0],[0,-3],[0,0],[-5.5,-5.75],[0,0],[-13.75,9],[0,0],[-21.25,-9.5]],\"v\":[[-56.25,-68.75],[-62.75,-41.25],[-70,-26.25],[-49,-31.25],[-24.5,-28.25],[-18.5,-13],[-8.5,-2.25],[-5.75,34.25],[21,28.75],[42.75,34],[45.5,14.75],[52.5,3.5],[62.5,-4.25],[74.25,-1.75],[81.5,-2.75],[101.25,-1.5],[98,-11.5],[97,-31],[83.5,-42],[68,-55.5],[44,-34.5],[10.5,-30.25],[-24.25,-33]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0.047,-0.026],[-0.06,-0.047],[0.011,0.108]],\"o\":[[-0.047,0.026],[0.06,0.047],[-0.011,-0.108]],\"v\":[[55.32,-24.341],[55.305,-24.172],[55.495,-24.267]],\"c\":true}],\"e\":[{\"i\":[[5.5,-3],[-7,-5.5],[1.25,12.5]],\"o\":[[-5.5,3],[7,5.5],[-1.25,-12.5]],\"v\":[[61,-42.5],[59.25,-23],[81.25,-34]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[-0.106,0.009],[0.124,0.008]],\"o\":[[0.106,-0.009],[-0.066,-0.004]],\"v\":[[39.106,-21.324],[39.124,-21.43]],\"c\":true}],\"e\":[{\"i\":[[6,-0.5],[-7.002,-0.467]],\"o\":[[-6,0.5],[3.75,0.25]],\"v\":[[33.75,-23.75],[32.75,-17.75]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.173,-0.02],[0.061,0.133],[0.041,-0.122]],\"o\":[[0.173,0.02],[-0.061,-0.133],[-0.041,0.122]],\"v\":[[15.411,-2.936],[15.564,-3.202],[15.166,-3.171]],\"c\":true}],\"e\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}],\"e\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}],\"e\":[{\"i\":[[0.726,0.085],[-0.256,-0.555],[-0.171,0.512]],\"o\":[[-0.726,-0.085],[0.256,0.555],[0.171,-0.512]],\"v\":[[15.476,0.335],[14.835,1.445],[16.5,1.317]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":8,\"s\":[0,0],\"h\":1},{\"t\":9,\"s\":[100,100],\"h\":1},{\"t\":14,\"s\":[0,0],\"h\":1}],\"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 7\",\"np\":11,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.527,-15.381],[0,0],[-16.592,-17.145],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-13.448,7.664],[0,0],[-17.698,10.784],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-3.871,25.993],[0,0],[8.117,32.855],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[14.031,8.836],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[9.314,9.861],[0,0],[16.592,17.145],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[15.014,-8.556],[0,0],[17.698,-10.784],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[3.871,-25.993],[0,0],[-10.383,-42.03],[0,0],[-33.95,-10.778],[0,0],[-26.662,15.973],[0,0],[-8.296,0],[0,0],[-18.634,-11.735],[0,0]],\"v\":[[-121.849,-206.352],[-161.4,-175.412],[-182.173,-172.147],[-193.511,-153.214],[-214.027,-135.922],[-218.088,-102.356],[-229.872,-81.594],[-235.542,-46.858],[-241.467,0.28],[-222.027,33.027],[-205.473,58.881],[-178.067,73.84],[-160.953,112.227],[-121.198,125.433],[-113.318,152.661],[-89.783,163.211],[-64.949,195.685],[-25.948,210.14],[-11.345,221.447],[9.97,215.704],[36.986,213.556],[40.385,184.688],[78.624,178.828],[104.64,145.801],[121.784,144.1],[126.971,127.861],[160.805,114.917],[180.651,77.022],[213.113,53.612],[225.152,8.645],[241.52,-22.857],[229.361,-60.866],[232.883,-107.97],[180.871,-152.377],[142.07,-197.613],[82.916,-185.269],[39.46,-183.492],[17.864,-151.627],[4.686,-158.605],[-5.428,-154.127],[-28.031,-182.836],[-68.036,-192.302]],\"c\":true}],\"e\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.781,-16.813],[0,0],[-19.543,-13.685],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-14.931,4.078],[0,0],[-16.624,12.172],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-7.619,25.151],[0,0],[16.117,27.97],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[17.031,13.336],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[11.973,13.619],[0,0],[23.953,16.773],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[18.514,-5.056],[0,0],[16.722,-12.243],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[8.98,-29.643],[0,0],[-21.615,-37.512],[0,0],[-33.95,-10.778],[0,0],[-26.663,15.973],[0,0],[-8.296,0],[0,0],[-17.338,-13.577],[0,0]],\"v\":[[-122.349,-200.852],[-165.9,-178.912],[-181.673,-176.147],[-189.511,-163.714],[-217.027,-145.422],[-219.588,-110.856],[-241.872,-94.094],[-239.542,-62.358],[-241.967,-19.72],[-217.527,16.527],[-206.973,51.381],[-179.067,65.84],[-155.953,98.227],[-117.198,116.933],[-100.318,142.161],[-78.783,151.211],[-56.949,189.685],[-32.448,201.14],[-15.345,210.947],[3.47,204.704],[24.986,203.556],[43.385,190.688],[67.624,177.828],[82.14,158.301],[108.784,144.6],[131.471,116.361],[158.805,108.917],[179.151,78.022],[204.113,62.612],[219.652,17.144],[240.52,-14.357],[241.361,-65.366],[232.883,-120.97],[183.871,-164.877],[137.57,-196.113],[81.916,-196.269],[42.96,-187.992],[12.864,-156.627],[5.686,-161.605],[-8.428,-159.127],[-29.531,-189.336],[-67.036,-197.802]],\"c\":true}]},{\"t\":9}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":4,\"s\":[0,0],\"h\":1},{\"t\":5,\"s\":[100,100],\"h\":1},{\"t\":9,\"s\":[0,0],\"h\":1}],\"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 6\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[37,-3.75],[0,0],[8.5,-7],[0,0],[9.25,-15.5],[0,0],[4.25,-13.75],[0,0],[-6.25,-29],[0,0],[-8.75,-18.25],[0,0],[-15,-15.5],[0,0],[-14.75,-11.5],[0,0],[-22.25,-9.75],[0,0],[-8.25,0.5],[0,0],[-13.25,4.5],[0,0],[-16,9.75],[0,0],[-9,8.25],[0,0],[-18,13],[0,0],[-12.25,18.75],[0,0],[-3.5,23.5],[0,0],[11.75,28.25],[0,0],[26,19],[0,0],[35,-6.25],[0,0],[7.5,0],[0,0],[8.75,8],[0,0]],\"o\":[[-37,3.75],[0,0],[-8.5,7],[0,0],[-9.25,15.5],[0,0],[-4.25,13.75],[0,0],[6.25,29],[0,0],[8.75,18.25],[0,0],[15,15.5],[0,0],[14.75,11.5],[0,0],[22.25,9.75],[0,0],[8.25,-0.5],[0,0],[13.25,-4.5],[0,0],[16,-9.75],[0,0],[9,-8.25],[0,0],[18,-13],[0,0],[12.25,-18.75],[0,0],[3.5,-23.5],[0,0],[-11.75,-28.25],[0,0],[-26,-19],[0,0],[-35,6.25],[0,0],[-7.5,0],[0,0],[-8.75,-8],[0,0]],\"v\":[[-99.5,-183.25],[-144.75,-160.25],[-156.75,-157.75],[-167,-144.25],[-186,-125],[-196,-93.75],[-205.75,-79.5],[-205,-49],[-209,-10],[-186,18.25],[-185.5,47.5],[-155.75,77.75],[-145.25,100.25],[-107.5,125.75],[-94.5,146.75],[-68.25,159],[-46.25,175.25],[-13.25,184.25],[-0.5,189.5],[14.25,182.5],[33.25,178.75],[53.5,163.5],[72.25,157.75],[91.25,141],[106.75,136.75],[125,118],[147,106.75],[166.75,74.75],[185.25,56.75],[199.75,17],[215,-16],[213.5,-58.5],[209,-104.25],[178.25,-134],[149.5,-164.5],[91.5,-177.75],[49.5,-177.5],[13.25,-150.5],[4.5,-155],[-6,-150.5],[-18.75,-164.25],[-40,-171]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":3,\"s\":[0,0],\"h\":1},{\"t\":4,\"s\":[100,100],\"h\":1},{\"t\":5,\"s\":[0,0],\"h\":1}],\"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 5\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[28.5,3],[0,0],[22.75,-14.5],[0,0],[6.75,-23.75],[0,0],[-1.75,-23.5],[0,0],[-7.25,-11.75],[0,0],[-10.5,-8.25],[0,0],[-9.75,-8.75],[0,0],[-14,-6.5],[0,0],[-5.5,-2.75],[0,0],[-14.75,4.5],[0,0],[-14.5,6],[0,0],[-20,14.25],[0,0],[-6.5,15],[0,0],[-1.75,21],[0,0],[9.5,20.75],[0,0],[6.75,5.5],[0,0],[14.75,3.75],[0,0],[24.5,-4.5],[0,0],[4.5,1],[0,0]],\"o\":[[-28.5,-3],[0,0],[-22.75,14.5],[0,0],[-6.75,23.75],[0,0],[1.75,23.5],[0,0],[7.25,11.75],[0,0],[10.5,8.25],[0,0],[9.75,8.75],[0,0],[14,6.5],[0,0],[5.5,2.75],[0,0],[14.75,-4.5],[0,0],[14.5,-6],[0,0],[20,-14.25],[0,0],[6.5,-15],[0,0],[1.75,-21],[0,0],[-9.5,-20.75],[0,0],[-6.75,-5.5],[0,0],[-14.75,-3.75],[0,0],[-24.5,4.5],[0,0],[-4.5,-1],[0,0]],\"v\":[[-42.25,-141.75],[-83.5,-133],[-116.75,-124.25],[-131.75,-102],[-157,-69.5],[-155.75,-47.25],[-164,-6.75],[-151.25,18.75],[-146,44.75],[-134.75,55.5],[-123.25,79.5],[-110,85.5],[-98.5,104.25],[-79.75,113],[-61.75,129.75],[-42.75,132.5],[-32,141],[-13.5,141.75],[8,140.25],[26.75,131.25],[56.75,125.75],[73,110.75],[101,97.5],[129,67.25],[146,41.5],[153.25,14],[165.25,-17.25],[160.75,-52.5],[154.25,-91],[134.5,-109.75],[126.75,-123.75],[115.25,-125.25],[93,-140],[68,-140.5],[30.5,-141.5],[12,-124],[2.5,-126.5],[-8.75,-123.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":2,\"s\":[0,0],\"h\":1},{\"t\":3,\"s\":[100,100],\"h\":1},{\"t\":4,\"s\":[0,0],\"h\":1}],\"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 4\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,-3],[5.5,-1.75],[0,0],[26.75,0.25],[0,0],[9,-17.25],[0,0],[-3.25,-19.25],[0,0],[-8.5,-9.25],[0,0],[-14.75,-9.5],[0,0],[-18.5,2.75],[0,0],[-13,5],[0,0],[-9.5,16.5],[0,0],[-7,16.25],[0,0],[12.75,16.25],[0,0],[20.25,11.75],[0,0]],\"o\":[[-10.25,3],[-5.5,1.75],[0,0],[-26.75,-0.25],[0,0],[-9,17.25],[0,0],[3.25,19.25],[0,0],[8.5,9.25],[0,0],[14.75,9.5],[0,0],[18.5,-2.75],[0,0],[13,-5],[0,0],[9.5,-16.5],[0,0],[7,-16.25],[0,0],[-12.75,-16.25],[0,0],[-20.25,-11.75],[0,0]],\"v\":[[19,-97],[2.25,-85.75],[-4.75,-87.5],[-31.75,-96.5],[-64.5,-83],[-93.75,-63.5],[-99,-34.75],[-108,-0.5],[-99.5,20.5],[-90,53],[-70.5,62.5],[-54,82],[-35.75,87.5],[2.25,92],[18.5,84],[45,82.5],[60.25,69.25],[86.75,55.5],[91,28.75],[106.25,7.75],[108.75,-25.25],[105.5,-54.75],[88.25,-66.75],[70.25,-88.5],[41.25,-89.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":1,\"s\":[0,0],\"h\":1},{\"t\":2,\"s\":[100,100],\"h\":1},{\"t\":3,\"s\":[0,0],\"h\":1}],\"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 3\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.87,0.318],[0,0],[20.098,-10.357],[0,0],[5.5,-10.375],[0,0],[-8.375,-17.375],[0,0],[-8.75,-6.625],[0,0],[-14.875,0.5],[0,0],[-11.625,3.5],[0,0],[-5.25,9],[0,0],[-0.5,17.375],[0,0],[6.125,8],[0,0],[6.625,3.125],[0,0]],\"o\":[[-11.625,-0.375],[0,0],[-20.375,10.5],[0,0],[-6.558,12.37],[0,0],[8.156,16.92],[0,0],[8.75,6.625],[0,0],[14.875,-0.5],[0,0],[11.625,-3.5],[0,0],[5.25,-9],[0,0],[0.447,-15.518],[0,0],[-6.125,-8],[0,0],[-6.625,-3.125],[0,0]],\"v\":[[8.125,-57.25],[-3.75,-46.75],[-37.5,-48.875],[-42.125,-21.75],[-60.5,-21.125],[-51.125,-5.25],[-59.625,20.25],[-38.875,28.25],[-38.125,46.875],[-22.25,41.625],[-2.75,53.625],[14.375,40.375],[32.125,45.625],[39.25,36],[55.625,28.5],[51.5,13.25],[65.625,-9.125],[55.25,-22.5],[55.75,-41.125],[38.625,-40.25],[34,-53.75],[19.25,-44.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":0,\"s\":[0,0],\"h\":1},{\"t\":1,\"s\":[100,100],\"h\":1},{\"t\":2,\"s\":[0,0],\"h\":1}],\"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 2\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.875,-2.25],[0,0],[3.375,-4.5],[0,0],[0.125,-15.625],[0,0],[-9.125,-7.125],[0,0],[-15.809,5.312],[0,0],[-1.625,15],[0,0],[13.75,8.375],[0,0]],\"o\":[[-8.37,1.586],[0,0],[-3.375,4.5],[0,0],[-0.125,15.625],[0,0],[11.114,8.678],[0,0],[15.625,-5.25],[0,0],[1.625,-15],[0,0],[-13.75,-8.375],[0,0]],\"v\":[[-14.875,-37.75],[-24.5,-27.25],[-33.625,-26.25],[-34.25,-17.875],[-45.25,-2.625],[-35.5,15],[-28.5,33.25],[-8,35.75],[16.125,36.75],[33.125,23.875],[46.125,4.625],[40.625,-13.5],[28.625,-36],[3.625,-36]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":-1,\"s\":[0,0],\"h\":1},{\"t\":0,\"s\":[100,100],\"h\":1},{\"t\":1,\"s\":[0,0],\"h\":1}],\"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\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[3.5,2.75],[-1.75,-4]],\"o\":[[-3.5,-2.75],[1.75,4]],\"v\":[[-0.25,-62.25],[-4.625,-57.5]],\"c\":true}],\"e\":[{\"i\":[[0.045,0.036],[-0.023,-0.052]],\"o\":[[-0.045,-0.036],[0.023,0.052]],\"v\":[[-1.545,-59.289],[-1.602,-59.227]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 64\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.625,0.625],[-2.75,-7.125],[0.125,4.875]],\"o\":[[-4.625,-0.625],[2.75,7.125],[-0.125,-4.875]],\"v\":[[-11.875,-74.5],[-18,-64.625],[-5,-67.375]],\"c\":true}],\"e\":[{\"i\":[[0.036,0.005],[-0.022,-0.056],[0.001,0.038]],\"o\":[[-0.036,-0.005],[0.022,0.056],[-0.001,-0.038]],\"v\":[[-12.805,-66.377],[-12.853,-66.299],[-12.751,-66.321]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 65\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[1.312,0.875],[-2.438,-1.75]],\"o\":[[-1.312,-0.875],[2.438,1.75]],\"v\":[[218.25,-117.562],[217.062,-114.812]],\"c\":true}],\"e\":[{\"i\":[[0.017,0.011],[-0.031,-0.022]],\"o\":[[-0.017,-0.011],[0.031,0.022]],\"v\":[[217.108,-115.773],[217.093,-115.738]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 66\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.625,0],[-2.438,-5.312],[-1.062,4.125]],\"o\":[[-3.625,0],[2.438,5.312],[1.062,-4.125]],\"v\":[[216.062,-112.125],[210.375,-102.812],[220.562,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.05,0],[0.033,0.073],[0.015,-0.057]],\"o\":[[0.05,0],[-0.033,-0.073],[-0.015,0.057]],\"v\":[[214.764,-104.712],[214.842,-104.84],[214.702,-104.779]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 67\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.062,0.25],[-0.375,-3.5],[-1.062,2.438]],\"o\":[[-3.062,-0.25],[0.375,3.5],[1.062,-2.438]],\"v\":[[218.875,-126.688],[214.938,-120.812],[222.062,-122.188]],\"c\":true}],\"e\":[{\"i\":[[-0.067,-0.005],[0.008,0.077],[0.023,-0.053]],\"o\":[[0.067,0.005],[-0.008,-0.077],[-0.023,0.053]],\"v\":[[218.843,-122.025],[218.929,-122.154],[218.773,-122.124]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 68\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[2.25,-0.75],[-4,-4],[1,5.375]],\"o\":[[-2.25,0.75],[4,4],[-1,-5.375]],\"v\":[[-158.75,-23.375],[-159.25,-13.5],[-151.25,-18.875]],\"c\":true}],\"e\":[{\"i\":[[0.267,-0.089],[-0.475,-0.475],[0.119,0.638]],\"o\":[[-0.267,0.089],[0.475,0.475],[-0.119,-0.638]],\"v\":[[-156.987,-17.646],[-157.047,-16.475],[-156.097,-17.112]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 69\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.5,0.75],[-2.625,-4.375],[-0.625,4.625]],\"o\":[[-4.5,-0.75],[2.625,4.375],[0.625,-4.625]],\"v\":[[-174.375,-63],[-179.875,-56.375],[-169.875,-58.25]],\"c\":true}],\"e\":[{\"i\":[[-0.255,-0.042],[0.149,0.248],[0.035,-0.262]],\"o\":[[0.255,0.042],[-0.149,-0.248],[-0.035,0.262]],\"v\":[[-175.96,-57.585],[-175.649,-57.96],[-176.215,-57.854]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 70\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,1.25],[-3.25,-3]],\"o\":[[-3.125,-1.25],[3.25,3]],\"v\":[[-168.625,-97.625],[-170.375,-92.875]],\"c\":true}],\"e\":[{\"i\":[[0.24,0.096],[-0.25,-0.231]],\"o\":[[-0.24,-0.096],[0.25,0.231]],\"v\":[[-169.49,-94.625],[-169.625,-94.26]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 71\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.125,1.125],[-2.125,-3.25]],\"o\":[[-4.125,-1.125],[2.125,3.25]],\"v\":[[-174.75,-46.25],[-177.75,-41.25]],\"c\":true}],\"e\":[{\"i\":[[-0.223,-0.061],[0.115,0.176]],\"o\":[[0.223,0.061],[-0.115,-0.176]],\"v\":[[-175.277,-42.495],[-175.115,-42.765]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 72\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4,1.75],[-2.375,-2.5],[1.875,-2.125],[-6,2],[0,3.875]],\"o\":[[-4,-1.75],[2.375,2.5],[-1.875,2.125],[6,-2],[0,-3.875]],\"v\":[[-135.25,-91.25],[-140.375,-86.375],[-140.625,-79],[-138.5,-73],[-131.875,-84]],\"c\":true}],\"e\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}],\"e\":[{\"i\":[[-0.226,-0.099],[0.134,0.142],[-0.106,0.12],[0.34,-0.113],[0,-0.219]],\"o\":[[0.226,0.099],[-0.134,-0.142],[0.106,-0.12],[-0.34,0.113],[0,0.219]],\"v\":[[-138.024,-81.476],[-137.733,-81.752],[-137.719,-82.17],[-137.84,-82.509],[-138.215,-81.887]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 73\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.375,0.5],[-0.875,-5.875],[-0.25,4]],\"o\":[[-3.375,-0.5],[0.875,5.875],[0.25,-4]],\"v\":[[-149.375,-91.5],[-154,-81.25],[-144.25,-83.75]],\"c\":true}],\"e\":[{\"i\":[[0.272,0.04],[-0.07,-0.473],[-0.02,0.322]],\"o\":[[-0.272,-0.04],[0.07,0.473],[0.02,-0.322]],\"v\":[[-149.432,-84.316],[-149.805,-83.491],[-149.02,-83.693]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 74\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.25,0.5],[-1.625,-3.375],[0,2.75]],\"o\":[[-3.25,-0.5],[1.625,3.375],[0,-2.75]],\"v\":[[-139,-26.125],[-141.625,-19.5],[-134.5,-20.625]],\"c\":true}],\"e\":[{\"i\":[[-0.464,-0.071],[0.232,0.482],[0,-0.393]],\"o\":[[0.464,0.071],[-0.232,-0.482],[0,0.393]],\"v\":[[-138.857,-20.696],[-138.482,-21.643],[-139.5,-21.482]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 75\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,0.25],[-4.125,-0.5]],\"o\":[[-3.125,-0.25],[4.125,0.5]],\"v\":[[-129.25,-31.375],[-128.25,-26.5]],\"c\":true}],\"e\":[{\"i\":[[-0.379,-0.03],[0.5,0.061]],\"o\":[[0.379,0.03],[-0.5,-0.061]],\"v\":[[-128.129,-28.502],[-128.25,-29.093]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 76\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.875,0.25],[-6.125,-10.5],[0.875,9.875]],\"o\":[[-4.875,-0.25],[6.084,10.43],[-0.875,-9.875]],\"v\":[[-121.25,-44.375],[-123.25,-23.75],[-111.875,-31.25]],\"c\":true}],\"e\":[{\"i\":[[-0.298,-0.015],[0.375,0.643],[-0.054,-0.605]],\"o\":[[0.298,0.015],[-0.373,-0.639],[0.054,0.605]],\"v\":[[-120.122,-28.029],[-120,-29.292],[-120.696,-28.833]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 77\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[5.75,-0.125],[-1.25,-3.625],[-1.125,5.25]],\"o\":[[-5.75,0.125],[1.25,3.625],[1.125,-5.25]],\"v\":[[-177,-126.875],[-183.875,-117.875],[-168.5,-120.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-176.25,-120.625],[-176.25,-120.625],[-176.25,-120.625]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 78\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.625,-0.125],[0,0],[2.46,-4.038],[-3.208,-3.921],[0,0],[-1.375,10.5],[0,0],[1.065,4.639]],\"o\":[[-7.625,0.125],[0,0],[-2.228,3.658],[6.75,8.25],[0,0],[1.375,-10.5],[0,0],[-1.75,-7.625]],\"v\":[[-188.125,-106.125],[-193.75,-93.625],[-201.198,-89.718],[-200.125,-76],[-187.5,-73.625],[-172.875,-75.25],[-176.25,-88],[-173.375,-97.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.863,4.079],[-1.375,-8.125],[-4.25,1],[0,0],[-4.5,1.875],[4,3.25]],\"o\":[[-3.875,-3.25],[1.375,8.125],[4.25,-1],[0,0],[4.5,-1.875],[-4,-3.25]],\"v\":[[-151.125,-47.625],[-158.375,-39.375],[-148.75,-28.875],[-144.125,-31.75],[-136.75,-31.875],[-134.625,-46.375]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[1.75,2.5],[5,-5.25],[0,0],[-10.625,-1.875]],\"o\":[[-1.75,-2.5],[-5,5.25],[0,0],[10.625,1.875]],\"v\":[[-161.625,-32],[-173.25,-37],[-175,-28.625],[-168,-17]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,-1.5],[0,0],[4.75,-10.25],[-6.625,-1],[-1,4.5],[0,0],[0.625,8.5]],\"o\":[[-4.25,1.5],[0,0],[-4.75,10.25],[6.625,1],[1,-4.5],[0,0],[-0.625,-8.5]],\"v\":[[-191.5,-60.125],[-195.25,-53.5],[-209.625,-48.125],[-199.625,-31.75],[-188.125,-37.75],[-187.875,-44.875],[-180.125,-53.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 79\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,0],[4.5,2],[-1,-6.25],[-4,1.875],[-1.5,3.375]],\"o\":[[-4.25,0],[-4.5,-2],[1,6.25],[4,-1.875],[1.5,-3.375]],\"v\":[[-138.375,-45.625],[-149,-44.5],[-155.5,-36.75],[-144.5,-33.75],[-135.5,-35.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.625,1.25],[1.125,-4.875],[-1.75,-1.5],[0,0],[0,0],[3.625,-9.5],[-6.5,2.125],[-2.75,-2.5],[0.875,6.125],[0,0],[-0.125,3.625]],\"o\":[[-2.625,-1.25],[-1.125,4.875],[1.75,1.5],[0,0],[0,0],[-3.625,9.5],[6.5,-2.125],[2.75,2.5],[-0.875,-6.125],[0,0],[0.125,-3.625]],\"v\":[[-180.375,-103.75],[-191.375,-101.375],[-190,-93.25],[-185.875,-91.375],[-186.5,-89.125],[-199.625,-86.875],[-189.875,-74.875],[-181.5,-72.75],[-174.5,-78.875],[-179.25,-88.75],[-175.75,-97.125]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.243,-1.321],[0,0],[0,0],[4.125,0.25],[-2.125,-8.75],[-3.375,3],[0,0],[-1.529,-0.888],[0.5,4.75]],\"o\":[[-6.75,2.75],[0,0],[0,0],[-4.125,-0.25],[2.125,8.75],[3.375,-3],[0,0],[3.875,2.25],[-0.5,-4.75]],\"v\":[[-189,-58.75],[-191.25,-50.375],[-191.25,-50.125],[-199.75,-52.625],[-208.375,-40.375],[-192.75,-35.625],[-192,-46.125],[-188.875,-48.875],[-181.75,-53.375]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.125,0],[-0.375,-4.875],[-7,0.375],[1.5,4]],\"o\":[[-3.125,0],[0.375,4.875],[7,-0.375],[-1.5,-4]],\"v\":[[-168.25,-36.375],[-174,-29.875],[-166,-19.5],[-161.75,-30.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":28,\"s\":[0,0],\"h\":1},{\"t\":29,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 80\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,-0.75],[-2.625,-1.375],[0,4]],\"o\":[[-3.375,0.75],[2.625,1.375],[0,-4]],\"v\":[[-149.875,-43],[-151.625,-34.25],[-140.625,-37.875]],\"c\":true}],\"e\":[{\"i\":[[-0.036,0.016],[0.023,0.017],[0.003,-0.039]],\"o\":[[0.035,-0.016],[-0.03,-0.023],[-0.004,0.049]],\"v\":[[-147.285,-38.411],[-147.278,-38.502],[-147.371,-38.464]],\"c\":true}]},{\"t\":37}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":37,\"s\":[0,0],\"h\":1}],\"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 81\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,-1.25],[-3.625,-2.375],[2.25,3.125]],\"o\":[[-3.875,1.25],[3.625,2.375],[-2.25,-3.125]],\"v\":[[-168.875,-33.875],[-169.875,-23.625],[-163.625,-30.375]],\"c\":true}],\"e\":[{\"i\":[[0.04,-0.013],[-0.037,-0.024],[0.023,0.032]],\"o\":[[-0.04,0.013],[0.037,0.024],[-0.023,-0.032]],\"v\":[[-167.46,-27.678],[-167.463,-27.584],[-167.398,-27.653]],\"c\":true}]},{\"t\":36}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":36,\"s\":[0,0],\"h\":1}],\"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 82\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,0.625],[-3.75,-1.875]],\"o\":[[-3.375,-0.625],[3.75,1.875]],\"v\":[[-187,-58.125],[-187.875,-52.75]],\"c\":true}],\"e\":[{\"i\":[[0.105,0.02],[-0.117,-0.059]],\"o\":[[-0.105,-0.02],[0.117,0.059]],\"v\":[[-187.605,-54.916],[-187.633,-54.748]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 83\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.5,0.875],[-5.5,-5.875],[0.875,4]],\"o\":[[-4.5,-0.875],[5.5,5.875],[-0.875,-4]],\"v\":[[-200,-50.25],[-204.125,-37.625],[-192.375,-45.25]],\"c\":true}],\"e\":[{\"i\":[[-0.132,-0.026],[0.179,0.154],[-0.003,-0.12]],\"o\":[[0.132,0.026],[-0.128,-0.11],[0.004,0.139]],\"v\":[[-201.803,-42.273],[-201.682,-42.643],[-201.997,-42.496]],\"c\":true}]},{\"t\":39}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":39,\"s\":[0,0],\"h\":1}],\"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 84\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.375,0.875],[-2,-1.75]],\"o\":[[-2.375,-0.875],[2,1.75]],\"v\":[[-178.25,-80.5],[-180.375,-75.875]],\"c\":true}],\"e\":[{\"i\":[[0.183,0.067],[-0.154,-0.135]],\"o\":[[-0.183,-0.067],[0.154,0.135]],\"v\":[[-179.058,-77.962],[-179.221,-77.606]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 85\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.625,1.125],[-4.25,-5.5],[-2.125,4.125]],\"o\":[[-4.625,-1.125],[4.25,5.5],[2.125,-4.125]],\"v\":[[-191.75,-89.5],[-196.875,-79.375],[-186.875,-80.75]],\"c\":true}],\"e\":[{\"i\":[[-0.097,-0.024],[0.089,0.115],[0.045,-0.087]],\"o\":[[0.097,0.024],[-0.089,-0.115],[-0.045,0.087]],\"v\":[[-192.962,-82.098],[-192.839,-82.31],[-193.08,-82.289]],\"c\":true}]},{\"t\":38}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":38,\"s\":[0,0],\"h\":1}],\"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 86\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.346,0.324],[-2.993,-3.154],[-0.566,2.346]],\"o\":[[-2.346,-0.324],[2.993,3.154],[0.566,-2.346]],\"v\":[[-182.926,-100.581],[-185.757,-95],[-179.691,-95.647]],\"c\":true}],\"e\":[{\"i\":[[0.03,0.004],[-0.039,-0.041],[-0.007,0.03]],\"o\":[[-0.03,-0.004],[0.039,0.041],[0.007,-0.03]],\"v\":[[-183.924,-96.43],[-183.961,-96.357],[-183.882,-96.366]],\"c\":true}]},{\"t\":35}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":35,\"s\":[0,0],\"h\":1}],\"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 87\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.94,0.03,0.33,1]},\"o\":{\"a\":0,\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"}],\"ip\":0,\"op\":41,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Shape Layer 2\",\"parent\":3,\"tt\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100},\"r\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[0,0,0]},\"a\":{\"a\":0,\"k\":[0,0,0]},\"s\":{\"a\":0,\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":30,\"s\":[{\"i\":[[0,0],[-9.75,-3.125],[0,0],[3.625,1.25]],\"o\":[[0,0],[9.75,3.125],[0,0],[-3.625,-1.25]],\"v\":[[-198,-88.125],[-193.375,-74.75],[-185.75,-84.25],[-193.75,-80.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-9.75,-3.125],[0,0],[3.625,1.25]],\"o\":[[0,0],[9.75,3.125],[0,0],[-3.625,-1.25]],\"v\":[[-197.625,-89.625],[-193,-76.25],[-185.375,-85.75],[-193.375,-82.375]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":30,\"s\":[{\"i\":[[0,0],[-14.375,-2],[0,0],[3.375,0.625]],\"o\":[[0,0],[14.375,2],[0,0],[-3.375,-0.625]],\"v\":[[-152.875,-43],[-145.25,-31.5],[-139.75,-39.625],[-149.125,-36.125]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.375,-2],[0,0],[3.375,0.625]],\"o\":[[0,0],[14.375,2],[0,0],[-3.375,-0.625]],\"v\":[[-152,-44.625],[-144.375,-33.125],[-138.875,-41.25],[-148.25,-37.75]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":30,\"s\":[{\"i\":[[0,0],[-14.625,-3],[0,0],[5.875,-0.25]],\"o\":[[0,0],[14.625,3],[0,0],[-5.875,0.25]],\"v\":[[-207.25,-46.375],[-200.75,-31.75],[-192.5,-44.875],[-200.75,-40.375]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.625,-3],[0,0],[5.875,-0.25]],\"o\":[[0,0],[14.625,3],[0,0],[-5.875,0.25]],\"v\":[[-206.75,-48],[-200.25,-33.375],[-192,-46.5],[-200.25,-42]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":33,\"s\":[{\"i\":[[0,0],[-14.625,-3],[0,0],[5.875,-0.25]],\"o\":[[0,0],[14.625,3],[0,0],[-5.875,0.25]],\"v\":[[-206.75,-48],[-200.25,-33.375],[-192,-46.5],[-200.25,-42]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.625,-3],[0,0],[5.875,-0.25]],\"o\":[[0,0],[14.625,3],[0,0],[-5.875,0.25]],\"v\":[[-208,-48.5],[-201.5,-33.875],[-193.25,-47],[-201.5,-42.5]],\"c\":true}]},{\"t\":37}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":38,\"s\":[0,0],\"h\":1}],\"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 39\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4.625,0],[0,0],[-8.875,0.25]],\"o\":[[0,0],[-4.625,0],[0,0],[8.875,-0.25]],\"v\":[[-113.375,-34.875],[-118.25,-28.125],[-126.125,-33.375],[-116.125,-17]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[2.375,0],[0,0],[-10,0.375]],\"o\":[[0,0],[-2.375,0],[0,0],[10,-0.375]],\"v\":[[-151.875,-19.875],[-154.75,-16.375],[-160.5,-18.25],[-153.5,-12.375]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-13.625,5.75],[0,0],[7,-0.125]],\"o\":[[0,0],[13.625,-5.75],[0,0],[-7,0.125]],\"v\":[[-178.125,-33.375],[-163,-19.25],[-161,-31.375],[-168.25,-24.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.701,3.25],[0,0],[3.957,-0.071]],\"o\":[[0,0],[7.701,-3.25],[0,0],[-3.957,0.071]],\"v\":[[-173.75,-31.429],[-165.201,-23.446],[-164.071,-30.299],[-168.168,-26.625]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":30,\"s\":[{\"i\":[[0,0],[-7.701,3.25],[0,0],[3.957,-0.071]],\"o\":[[0,0],[7.701,-3.25],[0,0],[-3.957,0.071]],\"v\":[[-173.75,-31.429],[-165.201,-23.446],[-164.071,-30.299],[-168.168,-26.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.701,3.25],[0,0],[3.957,-0.071]],\"o\":[[0,0],[7.701,-3.25],[0,0],[-3.957,0.071]],\"v\":[[-173.375,-32.179],[-164.826,-24.196],[-163.696,-31.049],[-167.793,-27.375]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":28,\"s\":[0,0],\"h\":1},{\"t\":29,\"s\":[100,100],\"h\":1},{\"t\":36,\"s\":[0,0],\"h\":1}],\"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 38\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[0,0],[-16.5,0],[0,0],[5.625,0.375]],\"o\":[[0,0],[16.5,0],[0,0],[-5.625,-0.375]],\"v\":[[-184.375,-126.125],[-175.25,-114.75],[-167.125,-123.875],[-178.25,-118.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-16.5,0],[0,0],[5.625,0.375]],\"o\":[[0,0],[16.5,0],[0,0],[-5.625,-0.375]],\"v\":[[-183.5,-127.5],[-174.375,-116.125],[-166.25,-125.25],[-177.375,-120.125]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[0,0],[-16.5,0],[0,0],[5.625,0.375]],\"o\":[[0,0],[16.5,0],[0,0],[-5.625,-0.375]],\"v\":[[-183.5,-127.5],[-174.375,-116.125],[-166.25,-125.25],[-177.375,-120.125]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-16.5,0],[0,0],[5.625,0.375]],\"o\":[[0,0],[16.5,0],[0,0],[-5.625,-0.375]],\"v\":[[-182.875,-128],[-173.75,-116.625],[-165.625,-125.75],[-176.75,-120.625]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[0,0],[-10.25,-2.375],[0,0],[4.75,0.25]],\"o\":[[0,0],[10.25,2.375],[0,0],[-4.75,-0.25]],\"v\":[[-154.75,-87.875],[-152.25,-76.125],[-144.5,-87.25],[-150.25,-82.375]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-10.25,-2.375],[0,0],[4.75,0.25]],\"o\":[[0,0],[10.25,2.375],[0,0],[-4.75,-0.25]],\"v\":[[-154,-89.5],[-151.5,-77.75],[-143.75,-88.875],[-149.5,-84]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4.5,-0.375],[0,0],[-9.5,2.375]],\"o\":[[0,0],[-4.5,0.375],[0,0],[9.5,-2.375]],\"v\":[[-136.5,-25.5],[-138.5,-21.5],[-141.75,-24.75],[-136.375,-15.875]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[3,0],[0,0],[-6.25,0.25]],\"o\":[[0,0],[-3,0],[0,0],[6.25,-0.25]],\"v\":[[-173.25,-45.375],[-176,-42.5],[-180.75,-45.375],[-175.75,-38.625]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[0,0],[-7.375,0.375],[0,0],[4.375,1.375]],\"o\":[[0,0],[7.375,-0.375],[0,0],[-4.375,-1.375]],\"v\":[[-181,-59.75],[-172.625,-51.75],[-168.75,-61.125],[-176.125,-57]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.375,0.375],[0,0],[4.375,1.375]],\"o\":[[0,0],[7.375,-0.375],[0,0],[-4.375,-1.375]],\"v\":[[-182.375,-60.875],[-174,-52.875],[-170.125,-62.25],[-177.5,-58.125]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 37\",\"np\":5,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-2.25,-3.938],[-11.312,1.812],[0,0],[9.188,0.125]],\"o\":[[0,0],[2.25,3.938],[11.312,-1.812],[0,0],[-9.188,-0.125]],\"v\":[[-159.625,-134.375],[-161,-127.375],[-145.5,-121.625],[-142.75,-134.125],[-150.5,-128.062]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-19.375,-2.25],[0,0],[7.125,3]],\"o\":[[0,0],[19.375,2.25],[0,0],[-7.125,-3]],\"v\":[[203.375,-81.875],[206.875,-68.5],[218.125,-79.25],[208,-75.5]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[8.25,-0.5],[0,0],[-25,0]],\"o\":[[0,0],[-8.25,0.5],[0,0],[25,0]],\"v\":[[163.75,-50.125],[159.875,-43.625],[148.5,-47.375],[161.25,-34.75]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[6.375,0],[0,0],[-19.625,5.75]],\"o\":[[0,0],[-6.375,0],[0,0],[19.625,-5.75]],\"v\":[[200.875,-43],[193.375,-34.625],[189.5,-40.875],[200.75,-23.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[6.375,0],[0,0],[-19.625,5.75]],\"o\":[[0,0],[-6.375,0],[0,0],[19.625,-5.75]],\"v\":[[200.125,-40.75],[192.625,-32.375],[188.75,-38.625],[200,-21.625]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-26.5,-1.25],[0,0],[16,1.375]],\"o\":[[0,0],[26.5,1.25],[0,0],[-16,-1.375]],\"v\":[[139.5,-93.25],[152.375,-71.875],[163,-89],[149.875,-82.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-26.5,-1.25],[0,0],[16,1.375]],\"o\":[[0,0],[26.5,1.25],[0,0],[-16,-1.375]],\"v\":[[134.25,-96],[147.125,-74.625],[157.75,-91.75],[144.625,-85.25]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[8.688,-0.75],[0,0],[-14.25,1.25]],\"o\":[[0,0],[-8.688,0.75],[0,0],[14.25,-1.25]],\"v\":[[207,-140.938],[201.375,-134.812],[191.938,-140.375],[204.375,-128.812]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[9.938,0.562],[0,0],[-18,0]],\"o\":[[0,0],[-9.938,-0.562],[0,0],[18,0]],\"v\":[[165.812,-157.75],[156.812,-152.125],[148.812,-157.5],[153.688,-147.438]],\"c\":true}],\"e\":[{\"i\":[[0,0],[9.938,0.562],[0,0],[-18,0]],\"o\":[[0,0],[-9.938,-0.562],[0,0],[18,0]],\"v\":[[166.812,-158.75],[157.812,-153.125],[149.812,-158.5],[154.688,-148.438]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[10.062,0.062],[0,0],[-12.812,0.062]],\"o\":[[0,0],[-10.062,-0.062],[0,0],[12.812,-0.062]],\"v\":[[110.688,-129.812],[105.062,-125],[98.125,-129.438],[104.812,-118.125]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[14.75,0.562],[0,0],[-24,-3.625]],\"o\":[[0,0],[-14.75,-0.562],[0,0],[24,3.625]],\"v\":[[79,-126.875],[69.562,-118.25],[59.25,-125.562],[65.688,-109.625]],\"c\":true}},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-11.562,-1.625],[0,0],[6,0]],\"o\":[[0,0],[11.562,1.625],[0,0],[-6,0]],\"v\":[[7.562,-111.312],[11.062,-101.312],[18.812,-109.938],[12.875,-105.75]],\"c\":true}},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[1.25,-1.75],[6.625,1.938],[0,0],[-19.875,-2.75]],\"o\":[[0,0],[-1.25,1.75],[-6.625,-1.938],[0,0],[19.875,2.75]],\"v\":[[33,-128.375],[31.688,-122],[18.938,-118.5],[12.875,-126.938],[20.5,-112.688]],\"c\":true}},\"nm\":\"Path 11\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":11,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[8.312,0],[0,0],[-17.375,-1.875]],\"o\":[[0,0],[-8.312,0],[0,0],[17.375,1.875]],\"v\":[[-32.562,-140.625],[-40.812,-133.312],[-50.25,-139.562],[-44.688,-126.562]],\"c\":true}],\"e\":[{\"i\":[[0,0],[8.312,0],[0,0],[-17.375,-1.875]],\"o\":[[0,0],[-8.312,0],[0,0],[17.375,1.875]],\"v\":[[-32.562,-144.125],[-40.812,-136.812],[-50.25,-143.062],[-44.688,-130.062]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":29,\"s\":[{\"i\":[[0,0],[8.312,0],[0,0],[-17.375,-1.875]],\"o\":[[0,0],[-8.312,0],[0,0],[17.375,1.875]],\"v\":[[-32.562,-144.125],[-40.812,-136.812],[-50.25,-143.062],[-44.688,-130.062]],\"c\":true}],\"e\":[{\"i\":[[0,0],[8.312,0],[0,0],[-17.375,-1.875]],\"o\":[[0,0],[-8.312,0],[0,0],[17.375,1.875]],\"v\":[[-32.562,-144.125],[-42.312,-135.562],[-50.25,-143.062],[-44.688,-130.062]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 12\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":12,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-5.5,-1.375],[0,0],[2.812,0]],\"o\":[[0,0],[5.5,1.375],[0,0],[-2.812,0]],\"v\":[[-64.25,-143.312],[-60.875,-137],[-55.25,-142.438],[-60.5,-140.438]],\"c\":true}},\"nm\":\"Path 13\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":13,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[3.312,0],[0,0],[-5.188,0.125]],\"o\":[[0,0],[-3.312,0],[0,0],[5.188,-0.125]],\"v\":[[-69.625,-155.562],[-74.312,-152.5],[-78.125,-154.75],[-74.312,-148.5]],\"c\":true}},\"nm\":\"Path 14\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":36,\"s\":[0,0],\"h\":1}],\"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 35\",\"np\":14,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[5.938,-0.312],[0,0],[-7.272,-2.083]],\"o\":[[0,0],[-5.938,0.312],[0,0],[13.312,3.812]],\"v\":[[141.438,-162.75],[136.125,-158.25],[130.438,-162.312],[133.25,-150.562]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[0,0],[6.375,0.75],[0,0],[-8.25,2]],\"o\":[[0,0],[-6.375,-0.75],[0,0],[8.25,-2]],\"v\":[[9.625,-128.125],[0.5,-122.25],[-7.25,-128],[1.375,-113]],\"c\":true}],\"e\":[{\"i\":[[0,0],[6.375,0.75],[0,0],[-8.25,2]],\"o\":[[0,0],[-6.375,-0.75],[0,0],[8.25,-2]],\"v\":[[8.625,-128.75],[-0.5,-122.875],[-8.25,-128.625],[0.375,-113.625]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 34\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[4.5,-0.125],[0,0],[-14.875,-0.25]],\"o\":[[0,0],[-4.5,0.125],[0,0],[14.875,0.25]],\"v\":[[168.125,21.375],[159.625,27.75],[151.25,22.25],[159.75,38.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.798,-0.078],[0,0],[-9.25,-0.155]],\"o\":[[0,0],[-2.798,0.078],[0,0],[9.25,0.155]],\"v\":[[165.458,20.434],[160.172,24.398],[154.964,20.978],[160.25,31.161]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-8.5,-1.25],[0,0],[4.5,0]],\"o\":[[0,0],[8.5,1.25],[0,0],[-4.5,0]],\"v\":[[132.625,-23.125],[134.75,-10.375],[145,-22.125],[136.625,-16.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-8.625,-0.25],[0,0],[1.875,0.75]],\"o\":[[0,0],[8.625,0.25],[0,0],[-1.875,-0.75]],\"v\":[[-94.125,-173.625],[-92.25,-164.75],[-85.875,-170.375],[-91.125,-169]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-8.625,-0.25],[0,0],[1.875,0.75]],\"o\":[[0,0],[8.625,0.25],[0,0],[-1.875,-0.75]],\"v\":[[-94.125,-174.75],[-92.25,-165.875],[-85.875,-171.5],[-91.125,-170.125]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-23.125,-0.25],[0,0],[10.375,-0.125]],\"o\":[[0,0],[23.125,0.25],[0,0],[-10.375,0.125]],\"v\":[[-125.75,-157.125],[-118,-138.25],[-99,-154],[-115,-147]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.875,-0.161],[0,0],[6.674,-0.08]],\"o\":[[0,0],[14.875,0.161],[0,0],[-6.674,0.08]],\"v\":[[-120.985,-156.214],[-116,-144.072],[-103.778,-154.203],[-114.07,-149.701]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[3.875,0],[0,0],[-5.375,0.875]],\"o\":[[0,0],[-3.875,0],[0,0],[5.375,-0.875]],\"v\":[[-145.875,-167.625],[-151.25,-164.125],[-155.625,-167.125],[-152.375,-159.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[3.875,0],[0,0],[-5.375,0.875]],\"o\":[[0,0],[-3.875,0],[0,0],[5.375,-0.875]],\"v\":[[-145.875,-168.875],[-151.25,-165.375],[-155.625,-168.375],[-152.375,-160.875]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.375,-0.375],[-10.875,-0.5],[1.375,2.75]],\"o\":[[-3.375,0.375],[10.875,0.5],[-1.375,-2.75]],\"v\":[[-156.125,5.125],[-159,15.375],[-148,8.125]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-19.5,0.5],[0,0],[5.875,0.25]],\"o\":[[0,0],[19.5,-0.5],[0,0],[-5.875,-0.25]],\"v\":[[-108.5,-6.25],[-102.75,13.25],[-95.625,-3.125],[-102.75,3.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14,0.359],[0,0],[4.218,0.179]],\"o\":[[0,0],[14,-0.359],[0,0],[-4.218,-0.179]],\"v\":[[-107.628,-3.429],[-103.5,10.571],[-98.385,-1.186],[-104.308,1.865]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-18.25,-0.25],[0.5,5],[0,0],[9.125,0.875]],\"o\":[[0,0],[18.25,0.25],[-0.5,-5],[0,0],[-9.125,-0.875]],\"v\":[[-153.5,34.875],[-142.125,50.875],[-132,42.5],[-136,39.5],[-143.875,43.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-12.402,0.016],[0.391,3.392],[0,0],[6.209,0.501]],\"o\":[[0,0],[12.402,-0.016],[-0.391,-3.392],[0,0],[-6.209,-0.501]],\"v\":[[-152.311,34.096],[-141.17,49.601],[-137.626,39.057],[-140.374,37.06],[-145.684,39.858]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":27,\"s\":[{\"i\":[[0,0],[-12.402,0.016],[0.391,3.392],[0,0],[6.209,0.501]],\"o\":[[0,0],[12.402,-0.016],[-0.391,-3.392],[0,0],[-6.209,-0.501]],\"v\":[[-152.311,34.096],[-141.17,49.601],[-137.626,39.057],[-140.374,37.06],[-145.684,39.858]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-12.402,0.016],[0.391,3.392],[0,0],[6.209,0.501]],\"o\":[[0,0],[12.402,-0.016],[-0.391,-3.392],[0,0],[-6.209,-0.501]],\"v\":[[-154.811,31.596],[-143.67,47.101],[-140.126,36.557],[-142.874,34.56],[-148.184,37.358]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-19.625,0.875],[0,0],[8.375,0.75]],\"o\":[[0,0],[19.625,-0.875],[0,0],[-8.375,-0.75]],\"v\":[[-37.625,129],[-26.5,143.375],[-21.25,133.375],[-29.5,136.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-10.617,0.473],[0,0],[4.531,0.406]],\"o\":[[0,0],[10.617,-0.473],[0,0],[-4.531,-0.406]],\"v\":[[-35.643,129.25],[-29.625,137.027],[-26.785,131.617],[-31.248,133.51]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-15,-0.625],[0,0],[6.25,1.5]],\"o\":[[0,0],[15,0.625],[0,0],[-6.25,-1.5]],\"v\":[[88.375,68.125],[91.375,79.75],[103,73.375],[92.875,75.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-8,-0.333],[0,0],[3.333,0.8]],\"o\":[[0,0],[8,0.333],[0,0],[-3.333,-0.8]],\"v\":[[91.15,69.983],[92.75,76.183],[98.95,72.783],[93.55,73.983]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-20.25,-1.125],[0,0],[9.375,-0.625]],\"o\":[[0,0],[20.25,1.125],[0,0],[-9.375,0.625]],\"v\":[[122.5,46.625],[136.375,66],[148.125,49.125],[135.375,56.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-13.802,-0.659],[0,0],[6.39,-0.366]],\"o\":[[0,0],[13.802,0.659],[0,0],[-6.39,0.366]],\"v\":[[125.366,48.75],[134.823,60.091],[142.832,50.213],[134.142,54.384]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":27,\"s\":[{\"i\":[[0,0],[-13.802,-0.659],[0,0],[6.39,-0.366]],\"o\":[[0,0],[13.802,0.659],[0,0],[-6.39,0.366]],\"v\":[[125.366,48.75],[134.823,60.091],[142.832,50.213],[134.142,54.384]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-13.802,-0.659],[0,0],[6.39,-0.366]],\"o\":[[0,0],[13.802,0.659],[0,0],[-6.39,0.366]],\"v\":[[125.366,47.75],[134.823,59.091],[142.832,49.213],[134.142,53.384]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 11\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 33\",\"np\":11,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[0,0],[7.25,-0.375],[0,0],[-18.625,-0.125]],\"o\":[[0,0],[0,0],[-7.25,0.375],[0,0],[18.625,0.125]],\"v\":[[95.25,21.5],[93.875,22.25],[85,28.875],[77.75,22.5],[84.5,39.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[3.795,-0.196],[0,0],[-9.75,-0.065]],\"o\":[[0,0],[0,0],[-3.795,0.196],[0,0],[9.75,0.065]],\"v\":[[92.003,21.908],[91.283,22.3],[86.637,25.768],[82.841,22.431],[86.375,31.527]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 32\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[2.5,-0.125],[0,0],[-9.25,1.5]],\"o\":[[0,0],[-2.5,0.125],[0,0],[9.25,-1.5]],\"v\":[[1.875,-61.875],[-2.875,-58.125],[-6.25,-61.5],[-0.875,-52.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.5,-0.125],[0,0],[-9.25,1.5]],\"o\":[[0,0],[-2.5,0.125],[0,0],[9.25,-1.5]],\"v\":[[2.125,-62.75],[-2.625,-59],[-6,-62.375],[-0.625,-53.625]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[-10.375,-0.125],[0,0],[4.25,0.375]],\"o\":[[0,0],[10.375,0.125],[0,0],[-4.25,-0.375]],\"v\":[[-98.875,-67.75],[-90.375,-59.25],[-86.625,-66.875],[-93.75,-64]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-10.375,-0.125],[0,0],[4.25,0.375]],\"o\":[[0,0],[10.375,0.125],[0,0],[-4.25,-0.375]],\"v\":[[-98.625,-68.625],[-90.125,-60.125],[-86.375,-67.75],[-93.5,-64.875]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[-14,-1.125],[0,0],[0,0],[7.875,0.75]],\"o\":[[0,0],[14,1.125],[0,0],[0,0],[-7.875,-0.75]],\"v\":[[-98.75,-88.875],[-92.125,-72.375],[-73.25,-80.5],[-75.625,-84.375],[-88.75,-79.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14,-1.125],[0,0],[0,0],[7.875,0.75]],\"o\":[[0,0],[14,1.125],[0,0],[0,0],[-7.875,-0.75]],\"v\":[[-98.5,-89.75],[-91.875,-73.25],[-73,-81.375],[-75.375,-85.25],[-88.5,-80.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-14,-1.125],[0,0],[0,0],[7.875,0.75]],\"o\":[[0,0],[14,1.125],[0,0],[0,0],[-7.875,-0.75]],\"v\":[[-98.5,-89.75],[-91.875,-73.25],[-73,-81.375],[-75.375,-85.25],[-88.5,-80.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14,-1.125],[0,0],[0,0],[7.875,0.75]],\"o\":[[0,0],[14,1.125],[0,0],[0,0],[-7.875,-0.75]],\"v\":[[-98,-90.5],[-91.375,-74],[-72.5,-82.125],[-74.875,-86],[-88,-81.25]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[-7.625,0.125],[0,0],[5.375,-0.125]],\"o\":[[0,0],[7.625,-0.125],[0,0],[-5.375,0.125]],\"v\":[[-19,-72],[-13.25,-59.125],[-4.375,-69.125],[-12.5,-64.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.625,0.125],[0,0],[5.375,-0.125]],\"o\":[[0,0],[7.625,-0.125],[0,0],[-5.375,0.125]],\"v\":[[-18.75,-72.875],[-13,-60],[-4.125,-70],[-12.25,-65.625]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[-7.625,0.125],[0,0],[5.375,-0.125]],\"o\":[[0,0],[7.625,-0.125],[0,0],[-5.375,0.125]],\"v\":[[-18.75,-72.875],[-13,-60],[-4.125,-70],[-12.25,-65.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.625,0.125],[0,0],[5.375,-0.125]],\"o\":[[0,0],[7.625,-0.125],[0,0],[-5.375,0.125]],\"v\":[[-18.75,-72.875],[-13,-60],[-4.125,-70],[-12.625,-66]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 31\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[0,0],[-16.125,-0.75],[0,0],[4.25,0.25]],\"o\":[[0,0],[16.125,0.75],[0,0],[-4.25,-0.25]],\"v\":[[-95.25,73.125],[-89.5,90],[-82.5,76],[-89.5,77.875]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-16.125,-0.75],[0,0],[4.25,0.25]],\"o\":[[0,0],[16.125,0.75],[0,0],[-4.25,-0.25]],\"v\":[[-101.625,69.375],[-95.875,86.25],[-88.875,72.25],[-95.875,74.125]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[0,0],[-21.625,0],[0,0],[7.75,0.125]],\"o\":[[0,0],[21.625,0],[0,0],[-7.75,-0.125]],\"v\":[[-36.75,70.125],[-23.125,87.125],[-12.875,70.5],[-24.875,76.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.629,0],[0,0],[5.243,0.085]],\"o\":[[0,0],[14.629,0],[0,0],[-5.243,-0.085]],\"v\":[[-32.842,71.125],[-23.625,82.625],[-16.691,71.379],[-24.809,75.438]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[0,0],[-14.629,0],[0,0],[5.243,0.085]],\"o\":[[0,0],[14.629,0],[0,0],[-5.243,-0.085]],\"v\":[[-32.842,71.125],[-23.625,82.625],[-16.691,71.379],[-24.809,75.438]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-14.629,0],[0,0],[5.243,0.085]],\"o\":[[0,0],[14.629,0],[0,0],[-5.243,-0.085]],\"v\":[[-33.092,68.875],[-23.875,80.375],[-16.941,69.129],[-25.059,73.188]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 30\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[0,0],[2.75,0],[0,0],[0,0],[1.75,0],[-16.125,0.875],[-0.5,4]],\"o\":[[0,0],[-2.75,0],[0,0],[0,0],[-1.75,0],[16.125,-0.875],[0.5,-4]],\"v\":[[-43.125,27],[-47,30.25],[-52.75,27.75],[-77.875,44.25],[-84.5,47.75],[-66,51.875],[-36.375,35.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.75,0],[0,0],[0,0],[1.75,0],[-16.125,0.875],[-0.5,4]],\"o\":[[0,0],[-2.75,0],[0,0],[0,0],[-1.75,0],[16.125,-0.875],[0.5,-4]],\"v\":[[-43.125,27],[-47.5,29.75],[-52.75,27.75],[-77.875,44.25],[-84.5,47.75],[-66,51.875],[-36.375,35.625]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[{\"i\":[[0,0],[2.75,0],[0,0],[0,0],[1.75,0],[-16.125,0.875],[-0.5,4]],\"o\":[[0,0],[-2.75,0],[0,0],[0,0],[-1.75,0],[16.125,-0.875],[0.5,-4]],\"v\":[[-43.125,27],[-47.5,29.75],[-52.75,27.75],[-77.875,44.25],[-84.5,47.75],[-66,51.875],[-36.375,35.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.75,0],[0,0],[0,0],[1.75,0],[-16.125,0.875],[-0.5,4]],\"o\":[[0,0],[-2.75,0],[0,0],[0,0],[-1.75,0],[16.125,-0.875],[0.5,-4]],\"v\":[[-43.125,27],[-47,29.125],[-52.75,27.75],[-77.875,44.25],[-84.5,47.75],[-66,51.875],[-36.375,35.625]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 29\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[3.875,-0.125],[0,0],[-0.5,-2.438],[-4.5,0.438]],\"o\":[[0,0],[-3.875,0.125],[0,0],[0.5,2.438],[4.5,-0.438]],\"v\":[[-37.688,5.25],[-41.25,9.25],[-46,6.5],[-48.312,9.5],[-40.625,12.938]],\"c\":true}],\"e\":[{\"i\":[[0,0],[3.875,-0.125],[0,0],[-0.5,-2.438],[-4.5,0.438]],\"o\":[[0,0],[-3.875,0.125],[0,0],[0.5,2.438],[4.5,-0.438]],\"v\":[[-38.188,4.125],[-41.75,8.125],[-46.5,5.375],[-48.812,8.375],[-41.125,11.812]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 28\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[-11.625,0.375],[0,0],[3.5,-0.125]],\"o\":[[0,0],[11.625,-0.375],[0,0],[-3.5,0.125]],\"v\":[[45.5,1.625],[47.625,16],[56.375,4.875],[49.75,7]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-11.625,0.375],[0,0],[3.5,-0.125]],\"o\":[[0,0],[11.625,-0.375],[0,0],[-3.5,0.125]],\"v\":[[44.125,-1.5],[46.25,12.875],[55,1.75],[48.375,3.875]],\"c\":true}]},{\"t\":19}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":17,\"s\":[0,0],\"h\":1},{\"t\":18,\"s\":[100,100],\"h\":1},{\"t\":20,\"s\":[0,0],\"h\":1}],\"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 27\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-10.25,-0.25],[0,0],[7,0]],\"o\":[[0,0],[10.25,0.25],[0,0],[-7,0]],\"v\":[[61.125,-32.5],[65.375,-21],[79,-32.125],[69.75,-28.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-3.329,-0.081],[0,0],[2.273,0]],\"o\":[[0,0],[3.329,0.081],[0,0],[-2.274,0]],\"v\":[[68.403,-31.72],[69.783,-27.985],[74.208,-31.598],[71.204,-30.421]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-3.329,-0.081],[0,0],[2.273,0]],\"o\":[[0,0],[3.329,0.081],[0,0],[-2.274,0]],\"v\":[[68.403,-31.72],[69.783,-27.985],[74.208,-31.598],[71.204,-30.421]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.131,0.003],[0,0],[-0.09,0]],\"o\":[[0,0],[-0.131,-0.003],[0,0],[0.09,0]],\"v\":[[70.354,-31.33],[70.3,-31.478],[70.125,-31.335],[70.244,-31.381]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":14,\"s\":[0,0],\"h\":1},{\"t\":15,\"s\":[100,100],\"h\":1},{\"t\":18,\"s\":[0,0],\"h\":1}],\"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 26\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[3.25,-0.75],[2.25,-1.125],[6.625,-2.375],[1.375,4.875],[0,0],[-3.625,-8.25],[-6.75,-0.125],[0,0],[2.75,-0.5],[0,0],[4.25,-0.25],[0,0],[-17.375,-8],[-8.625,3.625],[-1.75,-3.125],[-7.75,0],[0,3.5],[0,0],[3.25,-0.5],[0,0],[3.625,0.25],[-1,5.625],[2.25,4.75],[-6.5,0.875],[4.25,6.25],[0,0.375]],\"o\":[[0,0],[-3.25,0.75],[-2.25,1.125],[-6.625,2.375],[-1.375,-4.875],[0,0],[3.625,8.25],[6.75,0.125],[0,0],[-2.75,0.5],[0,0],[-4.25,0.25],[0,0],[17.375,8],[8.625,-3.625],[1.75,3.125],[7.75,0],[0,-3.5],[0,0],[-3.25,0.5],[0,0],[-3.625,-0.25],[1,-5.625],[-2.25,-4.75],[6.5,-0.875],[-4.25,-6.25],[0,-0.375]],\"v\":[[-175.875,-100.5],[-181.25,-93.875],[-181.75,-87.875],[-182.375,-79.625],[-195.375,-84.625],[-195,-92.875],[-200.75,-78.5],[-180,-65.75],[-182.125,-57.625],[-186.25,-50],[-193,-46.75],[-198.875,-38.25],[-208.75,-45.625],[-206.375,-28.25],[-174.25,-36.75],[-162.25,-38.25],[-150.875,-27.875],[-131.25,-35.125],[-134.5,-43.625],[-139.25,-37.125],[-146.75,-38.75],[-151.5,-35.875],[-157.25,-42.75],[-178.875,-50.875],[-177,-68],[-169.125,-78.375],[-172,-92.125]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":28,\"s\":[0,0],\"h\":1},{\"t\":29,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 25\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,1.875],[0,0],[3.375,-1.25],[0,0],[4.5,0.75],[0,0],[0,-15],[-8.875,0.125],[0,0],[3.625,-0.875],[0,0],[4.875,-0.5],[0,0],[-14.875,0],[-2,6],[-4.5,-0.5],[-1.5,-3.5],[-3,-4.125],[0,0],[2,1.25],[0,0],[6.25,0],[0,0],[-11.5,-5.125],[-5.5,4.375],[-1.625,2.25],[0,0],[-3.5,0],[-0.75,-3.5],[-9.75,4.75],[0,5.25],[0,0],[5.5,-1.75],[0,0],[0,0],[3.5,-0.375],[0,0],[4.625,-0.25],[0,0.375],[0,0],[0.25,3.625],[-4.375,0.125],[0.5,1.625],[-8.75,0.5],[0,0],[2.375,0],[0,0],[3.875,-1.625],[6.875,4.5],[0,4]],\"o\":[[0,-1.875],[0,0],[-3.375,1.25],[0,0],[-4.5,-0.75],[0,0],[0,15],[8.875,-0.125],[0,0],[-3.625,0.875],[0,0],[-4.875,0.5],[0,0],[14.875,0],[2,-6],[4.5,0.5],[1.5,3.5],[3,4.125],[0,0],[-2,-1.25],[0,0],[-6.25,0],[0,0],[11.5,5.125],[5.5,-4.375],[1.625,-2.25],[0,0],[3.5,0],[0.75,3.5],[9.75,-4.75],[0,-5.25],[0,0],[-5.5,1.75],[0,0],[0,0],[-3.5,0.375],[0,0],[-4.625,0.25],[0,-0.375],[0,0],[-0.25,-3.625],[4.375,-0.125],[-0.5,-1.625],[8.75,-0.5],[0,0],[-2.375,0],[0,0],[-3.875,1.625],[-6.875,-4.5],[0,-4]],\"v\":[[-171.5,-102.5],[-173.5,-100.75],[-180.5,-89],[-187,-87.25],[-194.375,-83.125],[-194.125,-94.375],[-207,-85.5],[-197.5,-67],[-180.875,-58.25],[-186.125,-50.875],[-193.625,-49.125],[-200.75,-39.375],[-212.25,-44.875],[-200.875,-28.75],[-180.875,-41.75],[-174,-49.5],[-163.25,-39.25],[-153.625,-25.125],[-152,-17.625],[-158.375,-17.5],[-162.625,-23.125],[-169.75,-23],[-177.25,-31.875],[-172.375,-11.375],[-150.5,-6.875],[-146.75,-23.875],[-134.625,-27.625],[-130.25,-32.625],[-125.25,-27.25],[-115.25,-14.625],[-106.875,-39.125],[-111.875,-42.5],[-118.5,-27.5],[-128.25,-37.625],[-131.875,-41.25],[-141.125,-35.75],[-146.875,-37.625],[-153.25,-34.375],[-159.875,-42.375],[-178.375,-51.875],[-182.75,-64.125],[-173.5,-68.875],[-167,-78],[-141.375,-68.25],[-130.125,-86.625],[-135.125,-79.875],[-139.25,-84.125],[-146.125,-74.875],[-163.125,-79.375],[-172.625,-91.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4.5,-0.25],[0,0],[-12.25,0],[1.625,3.625]],\"o\":[[0,0],[-4.5,0.25],[0,0],[12.25,0],[-1.625,-3.625]],\"v\":[[176,-72.75],[168.625,-65.125],[161.375,-68.625],[166.25,-57.625],[182.375,-65.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 24\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[3.375,0],[-0.5,-4],[-9,-1],[-8.625,-4.75],[0.25,-2.5],[0,0],[5.25,-0.75],[0,0],[2,0.625],[5,0.375],[0,0],[2.125,2.5],[0,0],[1.75,2],[-1.625,-1.25],[2.25,-3],[0,0],[3.625,-0.25],[2.375,3],[0,0],[-8.25,-4.25],[-7.625,-1.375],[-0.625,-2.625],[2.75,1.375],[0,0],[-1.125,-2],[-8,-0.625],[3.25,-0.125],[0,0],[5.5,-1.125],[0,0],[8.5,0.125],[0,0],[-11.5,-3.375],[-3.125,5.25],[-1.625,3.25],[-4.75,-2.25],[2.25,-1.75],[0,0],[0,0],[-4,-1.5],[0,3],[-11.375,-4],[2.75,-3.75],[0,0],[-1.875,0.875],[-1,-1.125],[-5.875,1.875],[-0.125,-6.875],[4.625,1.125],[0,0],[1.75,1.125],[0,0],[2.25,-0.25],[1.125,-2.625],[0.5,1.875],[0,0],[2.5,1.25],[0,0],[5.125,-1.875],[0,0],[3.375,1.75],[0,0],[1.75,1.125],[0,0],[-2.75,-8.25],[-9.25,0],[-9,3],[-1.5,2.25],[0.25,9],[3.25,6.625],[2,0.625]],\"o\":[[0,0],[-3.375,0],[0.5,4],[9,1],[8.625,4.75],[-0.25,2.5],[0,0],[-5.25,0.75],[0,0],[-2,-0.625],[-5,-0.375],[0,0],[-2.125,-2.5],[0,0],[-1.75,-2],[1.625,1.25],[-2.25,3],[0,0],[-3.625,0.25],[-2.375,-3],[0,0],[8.25,4.25],[7.625,1.375],[0.625,2.625],[-2.75,-1.375],[0,0],[1.125,2],[8,0.625],[-3.25,0.125],[0,0],[-5.5,1.125],[0,0],[-8.5,-0.125],[0,0],[11.5,3.375],[3.125,-5.25],[1.625,-3.25],[4.75,2.25],[-2.25,1.75],[0,0],[0,0],[4,1.5],[0,-3],[11.375,4],[-2.75,3.75],[0,0],[1.875,-0.875],[1,1.125],[5.875,-1.875],[0.125,6.875],[-4.625,-1.125],[0,0],[-1.75,-1.125],[0,0],[-2.25,0.25],[-1.125,2.625],[-0.5,-1.875],[0,0],[-2.5,-1.25],[0,0],[-5.125,1.875],[0,0],[-3.375,-1.75],[0,0],[-1.75,-1.125],[0,0],[2.75,8.25],[9.25,0],[9,-3],[1.5,-2.25],[-0.25,-9],[-3.25,-6.625],[-2,-0.625]],\"v\":[[-166.875,-122.5],[-176.375,-118.875],[-186.125,-111.375],[-164.5,-106.125],[-137.25,-98.125],[-126,-85.625],[-129.625,-85.75],[-136.75,-74.625],[-138.625,-86.5],[-143.5,-85.75],[-150.625,-79.75],[-156.25,-87.125],[-164.75,-86.125],[-165.125,-93.625],[-176.375,-95],[-173.5,-87.25],[-175,-80.375],[-182.375,-79.5],[-188.75,-74.25],[-203,-79.5],[-206.75,-89.125],[-204.75,-74],[-189.5,-69.75],[-181.125,-65.5],[-184.625,-62.125],[-190.625,-64],[-182.125,-58.625],[-174,-64.625],[-177.125,-53.375],[-183.25,-54.625],[-188.625,-43.5],[-197,-44.375],[-204.875,-36.875],[-214.25,-45.25],[-206.5,-29],[-186.5,-25.125],[-182.5,-38.625],[-173.25,-46.875],[-172,-40.375],[-178.875,-39.375],[-178,-36.875],[-165.375,-38.875],[-164.25,-48.75],[-140.125,-53.625],[-134.25,-39.875],[-140.125,-37.25],[-132.875,-35.375],[-129,-36.625],[-125.75,-47.75],[-110.875,-34.875],[-120.875,-26.5],[-126.125,-31],[-129.25,-29.25],[-133,-32.375],[-138.125,-28.125],[-136.75,-21.375],[-142.625,-24.25],[-143,-30.375],[-152,-28.75],[-156.25,-32.5],[-159.5,-22.5],[-166.625,-25.25],[-172.875,-24.625],[-173.125,-30],[-180,-30.125],[-180.75,-35.5],[-183.375,-21.25],[-159.125,-5.5],[-132.25,-10.75],[-110.75,-18.125],[-104.375,-37.25],[-117.75,-76.625],[-135.375,-113.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[9.125,-0.5],[2.5,-1],[-0.625,4.375],[-6.5,0],[-6.5,7.625]],\"o\":[[0,0],[-9.125,0.5],[-2.5,1],[0.625,-4.375],[6.5,0],[6.5,-7.625]],\"v\":[[4.25,138.125],[-1.5,146.75],[-17,146.5],[-24.75,145.875],[-14.375,156.875],[9.25,152.875]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[3.25,-2],[-1.125,-2.625],[6.125,1.375],[0,0],[3.75,-11.375],[0,0],[5,-0.125],[0,0],[-8.125,-4],[-7.375,7.375],[-9.625,6.25],[-11.75,5.25],[2.75,6.375]],\"o\":[[0,0],[0,0],[-3.25,2],[1.125,2.625],[-6.125,-1.375],[0,0],[-3.75,11.375],[0,0],[-5,0.125],[0,0],[8.125,4],[7.375,-7.375],[9.625,-6.25],[11.75,-5.25],[-2.75,-6.375]],\"v\":[[222,-128.875],[223.75,-127.5],[220.75,-122.625],[221,-113.625],[212.625,-106.375],[208.625,-113],[191.125,-97.125],[176.875,-74.625],[169.125,-67.625],[163.625,-73],[163,-61.5],[182.875,-62.875],[197.5,-86.625],[220.5,-96.25],[235.375,-122.375]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 23\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[6,0],[1,-4],[2.5,0],[-7.25,0.25],[-5,-1.75],[-2,-7.25],[3.25,1],[0,0],[5.5,3],[2.75,-0.25],[0,0],[-5.75,-5.25],[-7.5,-3.75],[-0.5,-8.5],[0,0],[7.5,-1.5],[0,0],[7,1],[0,0],[7.25,0],[0,0],[8,4.5],[0,0],[-3,0],[0,0],[0.75,13.75],[0,0],[2.75,-20],[-21,-7],[-13.25,4],[-10.5,9.75],[5,7.75],[5.25,10.5]],\"o\":[[0,0],[-6,0],[-1,4],[-2.5,0],[7.25,-0.25],[5,1.75],[2,7.25],[-3.25,-1],[0,0],[-5.5,-3],[-2.75,0.25],[0,0],[5.75,5.25],[7.5,3.75],[0.5,8.5],[0,0],[-7.5,1.5],[0,0],[-7,-1],[0,0],[-7.25,0],[0,0],[-8,-4.5],[0,0],[3,0],[0,0],[-0.75,-13.75],[0,0],[-2.75,20],[21,7],[13.25,-4],[10.5,-9.75],[-5,-7.75],[-5.25,-10.5]],\"v\":[[-139.25,-133],[-151,-128],[-166.25,-121.75],[-179,-118],[-181.25,-110],[-151.25,-105],[-131,-92.5],[-135.5,-74.75],[-145.5,-81.5],[-154.25,-85],[-162.5,-84.25],[-172.5,-88.25],[-164.25,-78],[-134.75,-56.75],[-104.75,-44],[-108.5,-37],[-114,-25.5],[-128.5,-32],[-143,-26.75],[-154.25,-32.25],[-165.5,-25.25],[-178.75,-37.5],[-201,-40.75],[-199,-58.5],[-190.75,-57.5],[-185.25,-61.75],[-201.5,-80.5],[-200,-107.5],[-234.5,-57.75],[-204.25,1.5],[-137.25,0],[-92.5,-16.25],[-97.25,-63.5],[-125.5,-96.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-9.25,-12.5],[-17,10.5],[0.5,13.5],[0,0],[8,-0.5],[3,-1.25],[-0.25,1.75],[-0.75,2.75],[0,0],[7.25,2.75]],\"o\":[[0,0],[9.25,12.5],[17,-10.5],[-0.5,-13.5],[0,0],[-8,0.5],[-3,1.25],[0.25,-1.75],[0.75,-2.75],[0,0],[-7.25,-2.75]],\"v\":[[-39.25,126.25],[-41.75,153],[-3,164.75],[22.75,142.5],[5,138],[-3.75,147],[-17.75,146.5],[-31.5,143.5],[-23.5,138.75],[-23.75,130],[-32,136]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,-4.25],[4.5,2.5],[0,0],[-13,-2.25],[-5.25,5.75]],\"o\":[[0,0],[0,4.25],[-4.5,-2.5],[0,0],[13,2.25],[5.25,-5.75]],\"v\":[[171.5,-52.75],[165,-46],[155.5,-43],[150,-50.75],[148.75,-30.5],[170.5,-42]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-27.5,-6],[0,0],[8,2.25]],\"o\":[[0,0],[27.5,6],[0,0],[-8,-2.25]],\"v\":[[122.25,43.5],[126.25,68.25],[147,46.75],[133.5,56.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[6.75,-1.5],[0,0],[-21.5,5]],\"o\":[[0,0],[-6.75,1.5],[0,0],[21.5,-5]],\"v\":[[221.5,-80.75],[211,-73.75],[198.25,-80.75],[216.25,-61.5]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[10,0],[0,0],[-20.75,-4.5]],\"o\":[[0,0],[-10,0],[0,0],[20.75,4.5]],\"v\":[[206.5,-39.25],[195,-28.5],[185.25,-39.25],[191.5,-14.25]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[7.75,3.25],[1.5,-3.75],[0,0],[6.25,0],[0,0],[-14.25,-4.5],[-12,-5],[-5.75,0.25],[-16.5,26],[0,0],[3.5,-0.75],[0,0],[6,-1.75],[1.5,5.75],[0,0],[-2.5,3.25]],\"o\":[[0,0],[-7.75,-3.25],[-1.5,3.75],[0,0],[-6.25,0],[0,0],[14.25,4.5],[12,5],[5.75,-0.25],[16.5,-26],[0,0],[-3.5,0.75],[0,0],[-6,1.75],[-1.5,-5.75],[0,0],[2.5,-3.25]],\"v\":[[-59.75,-157.75],[-80.75,-152.5],[-92,-148],[-101.75,-153.25],[-114.75,-149],[-126.25,-155.75],[-116.75,-130],[-71.25,-115.5],[-30.5,-107],[-52.5,-142.5],[-56.75,-147.5],[-59,-140.5],[-66.75,-143.25],[-71,-133.5],[-84.25,-140.75],[-81.25,-146.25],[-68.25,-150.25]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4.5,-1],[0,0],[-4.25,-5.25],[-8.5,2.5],[-0.25,5.25]],\"o\":[[0,0],[-4.5,1],[0,0],[4.25,5.25],[8.5,-2.5],[0.25,-5.25]],\"v\":[[-32.75,-140],[-40.75,-132.25],[-49.5,-137.75],[-55.5,-127],[-30.25,-120.75],[-24.5,-135.25]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[7.25,0.25],[0,0],[0,0],[9,-0.25],[0,0],[-26,0],[-7,6.5]],\"o\":[[0,0],[-7.25,-0.25],[0,0],[0,0],[-9,0.25],[0,0],[26,0],[7,-6.5]],\"v\":[[118.75,-131.5],[106,-123.5],[93.25,-128.5],[81,-124],[70,-115.5],[52.5,-120.25],[63.5,-99.75],[110.5,-114]],\"c\":true}},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[3.75,-0.5],[6.5,-1],[0,0],[-11.25,-4],[-4.75,11],[0,0]],\"o\":[[0,0],[-3.75,0.5],[-6.5,1],[0,0],[11.25,4],[4.75,-11],[0,0]],\"v\":[[33.5,-123.25],[24.75,-117.5],[15,-109.25],[8.5,-115.75],[5.25,-92.25],[32.5,-92],[36.25,-122.75]],\"c\":true}},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.5,-6.75],[-13,-5.5],[-6.75,1.5],[0,7.25],[0,0],[3,0],[0,0],[2,10.5]],\"o\":[[-4.5,6.75],[13,5.5],[6.75,-1.5],[0,-7.25],[0,0],[-3,0],[0,0],[-2,-10.5]],\"v\":[[127.75,-96],[125.25,-65.25],[168.75,-57.5],[184,-63.25],[177,-77.5],[171.5,-70.25],[166.75,-78.5],[139.25,-87.5]],\"c\":true}},\"nm\":\"Path 11\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":11,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,4.75],[-3.25,-1.5],[-3.25,-11.75],[-6.25,0],[-7.5,10.75],[0.75,2.5],[2.25,-3.5],[0.5,3.75],[-1,3.25],[0,0],[4.75,4],[-0.5,4],[0,0],[4.25,0.25],[1.75,-2.5]],\"o\":[[0,-4.75],[3.25,1.5],[3.25,11.75],[6.25,0],[7.5,-10.75],[-0.75,-2.5],[-2.25,3.5],[-0.5,-3.75],[1,-3.25],[0,0],[-4.75,-4],[0.5,-4],[0,0],[-4.25,-0.25],[-1.75,2.5]],\"v\":[[146.25,-158.25],[139.25,-138.25],[176.5,-120.25],[193.5,-93.25],[224.75,-94],[229.25,-122],[220,-107.25],[214.25,-111.75],[213.5,-125],[217.75,-131],[199.25,-133.5],[192.25,-146.25],[180.5,-154.25],[172.5,-151.75],[155.25,-153.75]],\"c\":true}},\"nm\":\"Path 12\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 22\",\"np\":12,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[10.5,-11.5],[0,0],[12,-7.5],[0,0],[-17.5,27],[8.5,15]],\"o\":[[0,0],[-10.5,11.5],[0,0],[-12,7.5],[0,0],[17.5,-27],[-8.5,-15]],\"v\":[[232.5,-135.5],[227,-92],[196.5,-80.5],[197.5,-60.5],[148,-43.5],[233,-55.5],[254.5,-111]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[12.5,-11.5],[0,0],[-12.5,-12.5],[0.5,-15],[0,0],[-6,-9],[0,0],[-6,5],[20,-33],[1,-13.5],[32.5,-7],[0,0],[-12,1],[0,0],[11.5,-17],[3.5,-23],[-10,4],[0,0],[12,2.5],[-8.5,4.5],[-18,-8.5],[0,0],[6.5,2.5],[-11,13],[6,5],[3,8.5],[0,0],[16.5,9],[0,0],[-0.5,5.5],[0,0],[12,-10.5],[0,0],[17,3],[0,0],[10.5,7],[0,0],[11,1.5]],\"o\":[[0,0],[-12.5,11.5],[0,0],[12.5,12.5],[-0.5,15],[0,0],[6,9],[0,0],[6,-5],[-20,33],[-1,13.5],[-32.5,7],[0,0],[12,-1],[0,0],[-11.5,17],[-3.5,23],[10,-4],[0,0],[-12,-2.5],[8.5,-4.5],[18,8.5],[0,0],[-6.5,-2.5],[11,-13],[-6,-5],[-3,-8.5],[0,0],[-16.5,-9],[0,0],[0.5,-5.5],[0,0],[-12,10.5],[0,0],[-17,-3],[0,0],[-10.5,-7],[0,0],[-11,-1.5]],\"v\":[[-103,-151],[-120,-125.5],[-165,-104],[-135.5,-90],[-122.5,-54.5],[-139.5,-23.5],[-113.5,-13.5],[-108.5,18],[-16.5,-29],[30,-14],[39,75],[-11,109],[-48,76],[-24,84],[4.5,61],[61,-23.5],[37.5,33.5],[93,45.5],[103.5,24],[80.5,30.5],[74,8],[108,11],[140,1],[123,1.5],[128,-26.5],[184,-40],[147.5,-53],[152.5,-76],[124,-76.5],[121,-110],[103,-116],[102,-132],[82.5,-109.5],[43,-95.5],[13,-89],[-21,-113],[-41.5,-113],[-54.5,-137],[-81,-134.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[-8.5,2],[3.5,-9.75],[12.5,8.25],[-6.5,6.75]],\"o\":[[8.5,-2],[-3.5,9.75],[-12.5,-8.25],[6.5,-6.75]],\"v\":[[-94.25,-100],[-73.5,-80.75],[-103.25,-68],[-106,-94.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[-7.659,0.208],[1.087,-5.73],[8.051,8.963]],\"o\":[[7.659,-0.208],[-1.087,5.73],[-8.051,-8.963]],\"v\":[[-22.638,-79.123],[2.068,-64.523],[-24.152,-60.386]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":19,\"s\":[0,0],\"h\":1},{\"t\":20,\"s\":[100,100],\"h\":1},{\"t\":21,\"s\":[0,0],\"h\":1}],\"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 21\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[5.5,-1.5],[5.5,-1.75],[0,0],[-8,-3.25],[-16.75,0],[0,-5],[4.75,-2.5],[0,0],[8,-3.5],[1,6.5],[-20.75,-4],[-17.75,9],[-17.25,-10.5],[0,0],[2.5,2.75],[6.25,3.5],[-3.25,-11.25],[-1.25,-4.5],[0,0],[9,0.5],[0,0],[-7.75,-2.25],[-10.75,-12.5],[0,0],[19,-1],[0,0],[0,0],[9.5,-4],[0,0],[-17,3.75],[-10.25,-5.25],[-8,12.5],[-12,11.5],[-4.25,-7],[11,-3.5],[0,0],[-5,-10.75],[-6.25,7.25],[-3.5,8],[13,-1.25],[-3.75,12],[-9.5,0.75],[-12.25,0.5],[-5.5,-4.75],[0,0],[-8,3.5],[7.5,2.5],[0,0],[11.75,-0.25],[0,0],[8.5,-1.5],[0,0],[13.25,-4],[0,0],[12,-0.25],[0,0],[8.5,3.5],[0,0],[6,0.5],[0,0],[11.75,4.25]],\"o\":[[0,0],[-5.5,1.5],[-5.5,1.75],[0,0],[8,3.25],[16.75,0],[0,5],[-4.75,2.5],[0,0],[-8,3.5],[-1,-6.5],[20.75,4],[17.75,-9],[17.25,10.5],[0,0],[-2.5,-2.75],[-6.25,-3.5],[3.25,11.25],[1.25,4.5],[0,0],[-9,-0.5],[0,0],[7.75,2.25],[10.75,12.5],[0,0],[-19,1],[0,0],[0,0],[-9.5,4],[0,0],[17,-3.75],[10.25,5.25],[8,-12.5],[12,-11.5],[4.25,7],[-11,3.5],[0,0],[5,10.75],[6.25,-7.25],[3.5,-8],[-13,1.25],[3.75,-12],[9.5,-0.75],[12.25,-0.5],[5.5,4.75],[0,0],[8,-3.5],[-7.5,-2.5],[0,0],[-11.75,0.25],[0,0],[-8.5,1.5],[0,0],[-13.25,4],[0,0],[-12,0.25],[0,0],[-8.5,-3.5],[0,0],[-6,-0.5],[0,0],[-11.75,-4.25]],\"v\":[[-98.25,-151.25],[-110,-141],[-127.25,-125.75],[-143.75,-128.25],[-124.75,-111],[-85,-104.75],[-65,-91.75],[-77.5,-78.75],[-89,-76],[-90.75,-61.75],[-106,-73.25],[-97.25,-47.75],[-41.75,-70.5],[-9.75,-81.5],[5,-58],[-8.5,-60.75],[-21,-62.25],[-26.75,-50.5],[0.75,-22.75],[-30.75,4.5],[-41.25,8.75],[-54.5,3],[-45.25,22],[-12.5,32.25],[-5,70.5],[-25.75,83.75],[-46.25,71],[-66.5,80.25],[-77.25,92.25],[-92.5,87.5],[-72,100.75],[-25.5,97.25],[5,101],[63.25,14.75],[96.75,9.5],[86.5,34.25],[73,24],[61,51],[101.25,38],[131,4.25],[98.5,-11],[67.25,-52.5],[108.75,-102.25],[148.75,-103.5],[169,-97.5],[175,-88],[183.75,-107.75],[173,-114],[166.25,-124.5],[137.75,-122.5],[117.75,-134.25],[96.5,-122.5],[77.25,-124.25],[65.25,-100.75],[42.5,-109.25],[18.25,-93.75],[4,-105.5],[-21.5,-109.25],[-26.25,-122.75],[-41.25,-123.5],[-46.5,-133.75],[-75.75,-134]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":22,\"s\":[0,0],\"h\":1}],\"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 19\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[12.75,0],[0,0],[10.75,-3],[0,0],[-14.75,-1.75],[-16.5,3],[0.5,-4],[0,0],[5.5,-2.75],[0,0],[7.75,-4],[0,0],[0,-3],[-12,-0.75],[-10,4.5],[-16,-2.25],[-2,-5],[0,0],[2.5,1.5],[0,0],[5.25,0.5],[0,0],[-6,-12.5],[-1.75,-2.5],[0,0],[7.25,1],[0,0],[-6.25,-2.5],[-7.25,7],[-5.25,-3.5],[0,4.75],[13,1.5],[8.5,-5.25],[26.25,-8.5],[7,9.75],[0,0],[-12,1.25],[0,0],[0,0],[-11.5,4.5],[0,0],[0,0],[-7.25,2.75],[4.75,9.25],[-3.5,15.75],[-13.25,4.5],[-6.25,-2.25],[0,0],[-5.25,2.25],[8.75,4.25],[0,0],[16.75,0.25],[0,0],[6.5,1.25],[0,0],[11.25,-3.25],[0,0],[16.25,0],[0,0],[5.75,3.75],[0,0],[10.25,1.5],[0,0],[9.5,2.5]],\"o\":[[0,0],[-12.75,0],[0,0],[-10.75,3],[0,0],[14.75,1.75],[16.5,-3],[-0.5,4],[0,0],[-5.5,2.75],[0,0],[-7.75,4],[0,0],[0,3],[12,0.75],[10,-4.5],[16,2.25],[2,5],[0,0],[-2.5,-1.5],[0,0],[-5.25,-0.5],[0,0],[6,12.5],[1.75,2.5],[0,0],[-7.25,-1],[0,0],[6.25,2.5],[7.25,-7],[5.25,3.5],[0,-4.75],[-13,-1.5],[-8.5,5.25],[-26.25,8.5],[-7,-9.75],[0,0],[12,-1.25],[0,0],[0,0],[11.5,-4.5],[0,0],[0,0],[7.25,-2.75],[-4.75,-9.25],[3.5,-15.75],[13.25,-4.5],[6.25,2.25],[0,0],[5.25,-2.25],[-8.75,-4.25],[0,0],[-16.75,-0.25],[0,0],[-6.5,-1.25],[0,0],[-11.25,3.25],[0,0],[-16.25,0],[0,0],[-5.75,-3.75],[0,0],[-10.25,-1.5],[0,0],[-9.5,-2.5]],\"v\":[[-93,-150.25],[-111.25,-140.75],[-124,-146.75],[-132.25,-125.25],[-151.25,-123.25],[-127,-111.5],[-98.75,-103],[-66.5,-93.25],[-69.5,-85.25],[-79.75,-75],[-87.75,-74.5],[-92.75,-65.75],[-103.5,-72],[-109.75,-64.75],[-91,-43.75],[-62.25,-49],[-26,-83],[7.75,-69.75],[3.5,-59.25],[-1.75,-57.75],[-10,-62.75],[-17.75,-61.25],[-25.75,-71.5],[-38,-46],[-16,-20],[-32.5,3.75],[-42,11.75],[-51.25,3.75],[-51.25,21.25],[44,-4.25],[120.25,-11.5],[134.75,7.25],[72,52.75],[25.5,73],[-23.5,96],[-91,98],[-96.75,78.5],[-82,86.5],[-71.5,77.75],[-41,78.75],[-22.5,78.25],[-7.75,65.25],[70.25,32.75],[84.25,32.25],[93.5,15],[88.25,-71.25],[121.25,-104.75],[170,-104.25],[181.75,-92.75],[187.5,-98.5],[189.5,-115.25],[173,-131.75],[147.75,-131.75],[127.5,-137.5],[98.75,-124],[90.75,-130],[78,-107],[45.25,-113.5],[21.75,-98.75],[2,-107.75],[-16,-114],[-22,-125.5],[-46,-125.75],[-54.75,-140.25],[-84,-140.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":21,\"s\":[0,0],\"h\":1},{\"t\":22,\"s\":[100,100],\"h\":1},{\"t\":23,\"s\":[0,0],\"h\":1}],\"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 18\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[9.25,-3.25],[0,0],[7.5,-7.75],[0,0],[-3.75,-11.25],[-17,-0.25],[-0.25,-4.75],[3.25,-2],[0,0],[3.5,-2.5],[0,0],[-19.25,-5.5],[-12.25,12.25],[-11.75,-6.75],[1.5,-8],[3.25,-1],[1.75,2.25],[5.5,-0.75],[0.25,3.25],[-4.5,-4.25],[-5.25,-4.75],[2.75,-4],[0,0],[2.5,-0.5],[0,0],[-6.5,-4.5],[2.75,-4.75],[5.25,-3.5],[0,0],[7,-0.25],[0,0],[-10,0],[-6.25,9.75],[-16.5,-4.75],[0,0],[6.5,-0.25],[0,0],[-14.25,0],[-10,27.5],[-20.75,12],[-8,-0.5],[0,0],[5.5,1.5],[0,0],[-5.75,-2.25],[-8.25,8],[-6.5,12.75],[18.25,-0.25],[-2,25.25],[-14.75,4.75],[0,0],[0,0],[-3.75,3.25],[0,0],[5,11.5],[-5,2.5],[-11.75,-1.25],[-2.5,-4.75],[0,0],[3.75,7.5],[6.75,0],[8.5,3.5],[0,0],[6,2.25],[1.5,-5.25],[11.25,-6],[0,0],[13,1],[1,0],[8.25,-0.75],[0,0],[9.5,2.25],[2,6.25],[0,0],[20.412,2.268],[0,0],[11,5]],\"o\":[[0,0],[-9.25,3.25],[0,0],[-7.5,7.75],[0,0],[3.75,11.25],[17,0.25],[0.25,4.75],[-3.25,2],[0,0],[-3.5,2.5],[0,0],[19.25,5.5],[12.25,-12.25],[11.75,6.75],[-1.5,8],[-3.25,1],[-1.75,-2.25],[-5.5,0.75],[-0.25,-3.25],[4.5,4.25],[5.25,4.75],[-2.75,4],[0,0],[-2.5,0.5],[0,0],[6.5,4.5],[-2.75,4.75],[-5.25,3.5],[0,0],[-7,0.25],[0,0],[10,0],[6.25,-9.75],[16.5,4.75],[0,0],[-6.5,0.25],[0,0],[14.25,0],[10,-27.5],[20.75,-12],[8,0.5],[0,0],[-5.5,-1.5],[0,0],[5.75,2.25],[8.25,-8],[6.5,-12.75],[-18.25,0.25],[2,-25.25],[14.75,-4.75],[0,0],[0,0],[3.75,-3.25],[0,0],[-5,-11.5],[5,-2.5],[11.75,1.25],[2.5,4.75],[0,0],[-3.75,-7.5],[-6.75,0],[-8.5,-3.5],[0,0],[-6,-2.25],[-1.5,5.25],[-11.25,6],[0,0],[-13,-1],[-1,0],[-8.25,0.75],[0,0],[-9.5,-2.25],[-2,-6.25],[0,0],[-11.25,-1.25],[0,0],[-11,-5]],\"v\":[[-89.75,-157],[-110.75,-144.25],[-130.75,-143.5],[-137.5,-125.25],[-153,-117],[-121.25,-102.5],[-94.5,-104.5],[-73.5,-93],[-78.75,-80.75],[-88.5,-78.5],[-90,-67.25],[-100.25,-73.25],[-90.5,-51.5],[-45,-69],[-18.5,-86.25],[9.75,-66],[3.25,-59.75],[-5,-61.5],[-14.5,-64.25],[-21.25,-72],[-28,-45.5],[37.5,-25],[-27.5,0.25],[-35.25,6],[-42.5,10.25],[-52,6.5],[-45.75,23.25],[-39.25,37.75],[-53.25,52],[-77.5,77.75],[-86,83],[-96.75,80.75],[-85.25,94.75],[-51.5,67.75],[-19,45],[-10.75,72.25],[-24,79.5],[-39.75,73.5],[-32.5,92],[21.5,69.75],[43.75,17.25],[81.75,1.5],[96.5,25],[83.25,30.5],[73.5,23.75],[78,39.25],[96.25,40],[126.5,12.25],[106,-10.25],[79.5,-49.25],[94,-89.25],[128.5,-53.75],[131,-53.5],[147.5,-58.75],[150.25,-69],[120.25,-79.25],[125.75,-101],[152.75,-107.25],[181.5,-99.25],[191.25,-97.25],[198,-124.5],[181.25,-137],[162.75,-141.5],[146.75,-151.5],[130,-151.25],[111.5,-142],[101.25,-117.75],[91.25,-120.75],[68.75,-112],[46.75,-116.25],[28,-108.75],[21.75,-113.75],[9.25,-107],[-12.75,-123],[-20,-133.5],[-47.5,-128],[-57.5,-140.75],[-81.75,-144.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":22,\"s\":[0,0],\"h\":1},{\"t\":23,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 17\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4,-2.5],[1.25,-8],[0,0],[2,-7.25],[6.25,2.75],[8.75,-6.5],[0,0],[-21,0.25],[5.75,-17.5],[-13.5,-6.25],[0.75,2.75],[0,0],[2.25,3.25],[0,0],[7,4.25],[-13,4.25],[-5.25,-2],[-5.5,0],[-4,8.25],[0,0],[8.25,0.75],[0,0],[14.25,0]],\"o\":[[0,0],[-4,2.5],[-1.25,8],[0,0],[-2,7.25],[-6.25,-2.75],[-8.75,6.5],[0,0],[21,-0.25],[-5.75,17.5],[13.5,6.25],[-0.75,-2.75],[0,0],[-2.25,-3.25],[0,0],[-7,-4.25],[13,-4.25],[5.25,2],[5.5,0],[4,-8.25],[0,0],[-8.25,-0.75],[0,0],[-14.25,0]],\"v\":[[130.25,-168.25],[123.25,-167.5],[120.75,-149.25],[112.5,-144],[116.5,-130],[96.5,-121],[82.25,-117.75],[48.5,-117.5],[77.25,-93.25],[108,-93.75],[141.75,-57],[159,-61.5],[162,-67.25],[155,-70.5],[156.25,-82],[132.25,-80.5],[141.25,-105],[164.5,-101.75],[186,-91.25],[200.25,-111.25],[211.25,-133.5],[197.75,-132.5],[181.75,-144],[148.75,-148.5]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[2.5,1],[0,-2.75],[0,0],[10.5,-0.25],[0,0],[0,0],[3.5,-1],[0,0],[-6.25,-1.75],[-13.75,-11.75],[-22.5,-6],[-30.75,-10.25],[-3.711,5.218],[0,0],[7.75,0],[0,0],[7.25,0.75],[-0.25,9],[0,0],[9,-0.5],[4.75,2.5],[9.5,5],[0,0]],\"o\":[[0,0],[-2.5,-1],[0,2.75],[0,0],[-10.5,0.25],[0,0],[0,0],[-3.5,1],[0,0],[6.25,1.75],[13.75,11.75],[22.5,6],[30.75,10.25],[16,-22.5],[0,0],[-7.75,0],[0,0],[-7.25,-0.75],[0.25,-9],[0,0],[-9,0.5],[-4.75,-2.5],[-9.5,-5],[0,0]],\"v\":[[-83.5,-171.75],[-89.75,-168],[-98,-165.5],[-98,-153.25],[-113.75,-148.25],[-125.75,-158.5],[-145,-168.5],[-151.5,-163],[-160.5,-163.5],[-153.25,-155.5],[-125.75,-133.25],[-74.25,-105.5],[-19.75,-86.25],[41.25,-71],[38.5,-128.75],[29.25,-114.25],[16.5,-113],[1,-109.75],[-14.5,-126.5],[-26.75,-136.5],[-45.25,-131],[-60,-135],[-81,-135.25],[-86.75,-153.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 16\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[5.625,-7.125],[4.125,-0.375],[4.375,-0.25],[0,0],[1.25,-2.75],[-2.5,-4.875],[-13.375,8.375]],\"o\":[[0,0],[-5.625,7.125],[-4.125,0.375],[-4.375,0.25],[0,0],[-1.25,2.75],[2.5,4.875],[13.375,-8.375]],\"v\":[[4.75,131.75],[3.375,141.875],[-9.75,145],[-17.625,148.25],[-21.375,145.875],[-29.25,148.125],[-22.375,158.875],[14,150.125]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[5.75,-1.5],[0,0],[7,-3.25],[0,0],[0,0],[0,0],[-6.75,-6],[0,0],[-4.5,7.25],[-9,-5.75],[10.5,1.5],[0,0],[12.25,-7],[7.25,9.75],[0,0],[0,0],[-6,-7.25],[0,0],[-24.5,-0.5],[10.5,-9],[0,0],[16.25,2],[0,0],[5,3],[0,0],[9,10.75],[0,0],[-22,-10.5],[-5,-0.25],[-6.25,9],[3.5,17]],\"o\":[[0,0],[-5.75,1.5],[0,0],[-7,3.25],[0,0],[0,0],[0,0],[6.75,6],[0,0],[4.5,-7.25],[9,5.75],[-10.5,-1.5],[0,0],[-12.25,7],[-7.25,-9.75],[0,0],[0,0],[6,7.25],[0,0],[24.5,0.5],[-10.5,9],[0,0],[-16.25,-2],[0,0],[-5,-3],[0,0],[-9,-10.75],[0,0],[22,10.5],[5,0.25],[6.25,-9],[-3.5,-17]],\"v\":[[-137.5,-132.75],[-148.5,-123.75],[-164.5,-126.25],[-171.25,-113.75],[-188,-125.25],[-203.75,-118],[-195.75,-112],[-170.25,-104.75],[-164,-90.5],[-153.75,-99.75],[-131.5,-106],[-138.5,-74.25],[-161,-82.75],[-169.75,-63.25],[-210.5,-74.5],[-218,-98.5],[-211,-64],[-182,-56],[-179.5,-38.25],[-139.5,-60.25],[-120.5,-27.75],[-138.75,-23.25],[-160.5,-17.75],[-172.5,-26.75],[-184,-27.75],[-190.5,-33.75],[-217.25,-35.75],[-226.25,-58.25],[-216.25,1],[-156.75,2.75],[-104,-13.5],[-111.75,-76.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-3.25,-11],[-14,0],[-2.75,6.75],[0,0],[10,-3.5],[0,0],[0.253,-0.105],[3.551,0],[0,0],[6.5,6.75]],\"o\":[[0,0],[3.25,11],[14,0],[2.75,-6.75],[0,0],[-10,3.5],[0,0],[-0.946,0.394],[-4.5,0],[0,0],[-6.5,-6.75]],\"v\":[[-86.25,-153.75],[-92,-123.25],[-58.5,-111.5],[-25,-127.75],[-31,-143],[-42,-132.75],[-55.75,-134.5],[-56.137,-134.328],[-63.25,-133],[-69.25,-136.5],[-81.25,-136.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.25,-6],[-13.25,0],[-3,9.5],[0,0],[4,-1.75],[0,0],[4.75,-0.25],[0,0],[4,7.25]],\"o\":[[0,0],[1.25,6],[13.25,0],[3,-9.5],[0,0],[-4,1.75],[0,0],[-4.75,0.25],[0,0],[-4,-7.25]],\"v\":[[-9,-135],[-16.75,-116],[7.25,-85.5],[34.5,-100.75],[37.75,-126.75],[27,-116.75],[17.75,-115.75],[12.25,-107.25],[8.25,-116.5],[-6.75,-121.75]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[9.25,-3],[7.25,-2.25],[12.5,1.5],[0,0],[-2.5,-12],[-10.25,0],[-12.5,1.25],[0,6.75]],\"o\":[[0,0],[-9.25,3],[-7.25,2.25],[-12.5,-1.5],[0,0],[2.5,12],[10.25,0],[12.5,-1.25],[0,-6.75]],\"v\":[[113.75,-133.75],[107.25,-122],[83.75,-124.75],[66.75,-119.25],[56.25,-130.75],[44.25,-107.5],[71.75,-104.25],[105,-105.5],[127.5,-121.5]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[2.75,-4.75],[-12,-9.75],[0,0],[3.25,-4.5],[0,0],[0,0],[0,0],[8,0.75],[0,0],[0,0],[-11.25,-4],[-8.25,6.25],[-0.25,6.5],[0,0],[6,1.5],[0,0],[13.5,3]],\"o\":[[0,0],[-2.75,4.75],[12,9.75],[0,0],[-3.25,4.5],[0,0],[0,0],[0,0],[-8,-0.75],[0,0],[0,0],[11.25,4],[8.25,-6.25],[0.25,-6.5],[0,0],[-6,-1.5],[0,0],[-13.5,-3]],\"v\":[[130.5,-95.5],[125,-93.5],[127,-67.5],[159.25,-71.75],[165.5,-65.25],[158,-61],[159.75,-56],[163.5,-51.75],[158.75,-44.75],[151.75,-52.25],[144.75,-52.25],[151,-33.25],[173,-37.75],[181.5,-67.5],[175,-81],[164.25,-74.5],[159.75,-82.25],[144,-82.25]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[4.25,-4.25],[0,0],[2.25,-4],[0,0],[-0.75,-7.25],[6.75,2.75],[0,0],[-5.25,-9.5],[-8.5,25.5],[3.75,5.5]],\"o\":[[0,0],[-4.25,4.25],[0,0],[-2.25,4],[0,0],[0.75,7.25],[-6.75,-2.75],[0,0],[5.25,9.5],[8.5,-25.5],[-3.75,-5.5]],\"v\":[[203,-50.5],[201,-25.25],[192.5,-26.25],[189.25,-17],[181.25,-5.25],[197,-0.75],[184,11.5],[176.25,1.5],[174.75,22],[208.75,11],[215.5,-49]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,-7],[-16,-8.75],[-10,-2.75],[-4,4],[2.5,-10.5],[2.75,-2.75],[-1.75,-1.5],[4,-5.5],[0,0],[-14.25,-0.5],[-4,12.75],[0,0],[-0.75,-3],[7.5,0.5],[0.5,2.75],[0,0],[10.25,0.25],[0,0],[4.5,1]],\"o\":[[0,0],[0,7],[16,8.75],[10,2.75],[4,-4],[-2.5,10.5],[-2.75,2.75],[1.75,1.5],[-4,5.5],[0,0],[14.25,0.5],[4,-12.75],[0,0],[0.75,3],[-7.5,-0.5],[-0.5,-2.75],[0,0],[-10.25,-0.25],[0,0],[-4.5,-1]],\"v\":[[128,-164.75],[121.25,-162.25],[146,-137.75],[196.25,-119.25],[211.25,-124.75],[223.5,-112.5],[202.25,-102.25],[206.75,-90],[207,-77.25],[194.5,-78.5],[207.5,-61.25],[231,-75.25],[222.5,-144.75],[223.25,-136.75],[207,-131.5],[188,-143.25],[180.75,-149],[160.75,-149],[143.5,-156],[135.75,-157.5]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 15\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[24.5,16],[0,0],[3,-23],[0,0],[14.5,-8.5],[0,0],[24.5,7],[-0.5,11],[0,-10],[-11.5,-6],[-5,6.5],[0,0],[-14,-4.5],[15,-14],[0,0],[7,-2.5],[0,0],[7,-5],[0,0],[19.5,-8.5],[0,0],[0,0],[3.5,-9.5],[0,0],[16,1],[12,6.5],[3.5,15],[0,0],[11.5,-3.5],[6,13.5],[-8,5],[-1,12.5],[7,13.5],[1.142,2.177],[0,0],[24,-8.5],[0,0],[24,15.5],[0,0],[-10.5,25],[0,0],[17.5,-59],[-38,-19.5],[-36,10.5],[-81,53],[-7.5,54.5]],\"o\":[[-24.5,-16],[0,0],[-3,23],[0,0],[-14.5,8.5],[0,0],[-24.5,-7],[0.5,-11],[0,10],[11.5,6],[5,-6.5],[0,0],[3.332,1.071],[-15,14],[0,0],[-7,2.5],[0,0],[-7,5],[0,0],[-19.5,8.5],[0,0],[0,0],[-3.5,9.5],[0,0],[-16,-1],[-12,-6.5],[-3.5,-15],[0,0],[-11.5,3.5],[-6,-13.5],[8,-5],[1,-12.5],[-1.202,-2.319],[-5.509,-10.498],[0,0],[-24,8.5],[0,0],[-24,-15.5],[0,0],[10.5,-25],[0,0],[-17.5,59],[38,19.5],[36,-10.5],[81,-53],[7.5,-54.5]],\"v\":[[241,-154.5],[199,-150],[218.5,-114],[206,-90.5],[197,-64.5],[167.5,-59.5],[144.5,-57],[112,-92],[97,-65.5],[128.5,-1.5],[159.5,-14.5],[177.5,-25.5],[188,-38],[191.5,-6.5],[167,5],[154,20.5],[133,23],[131.5,41],[108.5,43],[89.5,76.5],[70.5,70.5],[48,81],[31.5,110],[34.5,129],[2,144],[-23.5,144.5],[-42.5,121],[-43,98.5],[-81.5,108.5],[-118.5,91.5],[-109.5,56],[-86.5,40.5],[-97.5,-20],[-101.033,-26.771],[-111,-45.5],[-135,-5],[-164,-31],[-197,-32.5],[-208.5,-70.5],[-213,-106.5],[-180.5,-137.5],[-261,-96],[-116,133],[13.5,183.5],[152.5,92.5],[284.5,-37.5]],\"c\":true}],\"e\":[{\"i\":[[24.5,16],[0,0],[-1.396,-22.943],[0,0],[14.5,-8.5],[0,0],[29.833,13.667],[-0.5,11],[0,-10],[-11.5,-6],[-5,6.5],[0,0],[-6.488,-11.496],[15.697,-12.839],[0,0],[7,-2.5],[0,0],[12.667,-8.333],[0,0],[19.5,-8.5],[0,0],[0,0],[3.5,-9.5],[0,0],[11.388,-8.474],[7.667,9.167],[1.5,10],[0,0],[11.5,-3.5],[6,13.5],[-8,5],[-1,12.5],[7,13.5],[1.727,1.86],[0,0],[24,-8.5],[0,0],[24,15.5],[0,0],[-0.335,27.113],[0,0],[17.5,-59],[-38,-19.5],[-36,10.5],[-81,53],[-7.5,54.5]],\"o\":[[-24.5,-16],[0,0],[1.667,24.667],[0,0],[-14.5,8.5],[0,0],[-23.219,-10.207],[0.5,-11],[0,10],[11.5,6],[5,-6.5],[0,0],[7.146,12.662],[-15.697,12.839],[0,0],[-7,2.5],[0,0],[-11.849,7.806],[0,0],[-19.5,8.5],[0,0],[0,0],[-3.5,9.5],[0,0],[-9,5],[-8.222,-10.226],[-1.597,-11.458],[0,0],[-11.5,3.5],[-6,-13.5],[8,-5],[1,-12.5],[-1.035,-1.997],[-9.951,-10.715],[0,0],[-24,8.5],[0,0],[-24,-15.5],[0,0],[0.167,-13.5],[0,0],[-17.5,59],[38,19.5],[36,-10.5],[81,-53],[7.5,-54.5]],\"v\":[[241,-154.5],[191.667,-152],[220.833,-125],[207.333,-98.833],[205,-70.5],[176.5,-73.167],[151.833,-60.833],[105,-72.5],[97,-65.5],[128.5,-1.5],[168,-22],[181.5,-54.5],[200.5,-51.5],[189.167,1.833],[169.333,3.333],[158.667,24.5],[133,23],[136.167,51],[110.167,54],[92.167,77.167],[70.5,70.5],[48,81],[31.5,110],[11.833,120.667],[5,143.333],[-21.833,141.167],[-38.167,126],[-30.333,113.167],[-81.5,108.5],[-118.5,91.5],[-109.5,56],[-86.5,40.5],[-99.5,-43.5],[-102.217,-54.298],[-129.167,-61.5],[-139.333,-23.667],[-162.667,-42],[-194,-40.5],[-199.833,-72.833],[-211.167,-101],[-197.5,-119.667],[-261,-96],[-116,133],[13.5,183.5],[152.5,92.5],[284.5,-37.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[24.5,16],[0,0],[-1.396,-22.943],[0,0],[14.5,-8.5],[0,0],[29.833,13.667],[-0.5,11],[0,-10],[-11.5,-6],[-5,6.5],[0,0],[-6.488,-11.496],[15.697,-12.839],[0,0],[7,-2.5],[0,0],[12.667,-8.333],[0,0],[19.5,-8.5],[0,0],[0,0],[3.5,-9.5],[0,0],[11.388,-8.474],[7.667,9.167],[1.5,10],[0,0],[11.5,-3.5],[6,13.5],[-8,5],[-1,12.5],[7,13.5],[1.727,1.86],[0,0],[24,-8.5],[0,0],[24,15.5],[0,0],[-0.335,27.113],[0,0],[17.5,-59],[-38,-19.5],[-36,10.5],[-81,53],[-7.5,54.5]],\"o\":[[-24.5,-16],[0,0],[1.667,24.667],[0,0],[-14.5,8.5],[0,0],[-23.219,-10.207],[0.5,-11],[0,10],[11.5,6],[5,-6.5],[0,0],[7.146,12.662],[-15.697,12.839],[0,0],[-7,2.5],[0,0],[-11.849,7.806],[0,0],[-19.5,8.5],[0,0],[0,0],[-3.5,9.5],[0,0],[-9,5],[-8.222,-10.226],[-1.597,-11.458],[0,0],[-11.5,3.5],[-6,-13.5],[8,-5],[1,-12.5],[-1.035,-1.997],[-9.951,-10.715],[0,0],[-24,8.5],[0,0],[-24,-15.5],[0,0],[0.167,-13.5],[0,0],[-17.5,59],[38,19.5],[36,-10.5],[81,-53],[7.5,-54.5]],\"v\":[[241,-154.5],[191.667,-152],[220.833,-125],[207.333,-98.833],[205,-70.5],[176.5,-73.167],[151.833,-60.833],[105,-72.5],[97,-65.5],[128.5,-1.5],[168,-22],[181.5,-54.5],[200.5,-51.5],[189.167,1.833],[169.333,3.333],[158.667,24.5],[133,23],[136.167,51],[110.167,54],[92.167,77.167],[70.5,70.5],[48,81],[31.5,110],[11.833,120.667],[5,143.333],[-21.833,141.167],[-38.167,126],[-30.333,113.167],[-81.5,108.5],[-118.5,91.5],[-109.5,56],[-86.5,40.5],[-99.5,-43.5],[-102.217,-54.298],[-129.167,-61.5],[-139.333,-23.667],[-162.667,-42],[-194,-40.5],[-199.833,-72.833],[-211.167,-101],[-197.5,-119.667],[-261,-96],[-116,133],[13.5,183.5],[152.5,92.5],[284.5,-37.5]],\"c\":true}],\"e\":[{\"i\":[[24.5,16],[0,0],[-3.594,-22.915],[0,0],[14.5,-8.5],[0,0],[32.5,17],[-0.5,11],[0,-10],[-11.5,-6],[-5,6.5],[0,0],[-3.5,0],[15,-14],[0,0],[7,-2.5],[0,0],[15.5,-10],[0,0],[19.5,-8.5],[0,0],[0,0],[3.5,-9.5],[0,0],[9.082,-13.21],[5.5,10.5],[0.5,7.5],[0,0],[11.5,-3.5],[6,13.5],[-8,5],[-1,12.5],[7,13.5],[2.584,2.104],[0,0],[24,-8.5],[0,0],[24,15.5],[0,0],[-10.5,25],[0,0],[17.5,-59],[-38,-19.5],[-36,10.5],[-81,53],[-7.5,54.5]],\"o\":[[-24.5,-16],[0,0],[4,25.5],[0,0],[-14.5,8.5],[0,0],[-22.578,-11.81],[0.5,-11],[0,10],[11.5,6],[5,-6.5],[0,0],[3.5,0],[-15,14],[0,0],[-7,2.5],[0,0],[-14.273,9.208],[0,0],[-19.5,8.5],[0,0],[0,0],[-3.5,9.5],[0,0],[-5.5,8],[-6.332,-12.089],[-0.646,-9.687],[0,0],[-11.5,3.5],[-6,-13.5],[8,-5],[1,-12.5],[-1.202,-2.319],[-12.461,-10.144],[0,0],[-24,8.5],[0,0],[-24,-15.5],[0,0],[10.5,-25],[0,0],[-17.5,59],[38,19.5],[36,-10.5],[81,-53],[7.5,-54.5]],\"v\":[[241,-154.5],[188,-153],[222,-130.5],[208,-103],[209,-73.5],[181,-80],[155.5,-56],[112,-92],[97,-65.5],[128.5,-1.5],[159.5,-14.5],[186,-57.5],[200,-47],[188,6],[170.5,2.5],[161,26.5],[133,23],[138.5,56],[111,59.5],[93.5,77.5],[70.5,70.5],[48,81],[31.5,110],[0.5,116.5],[6.5,143],[-21,139.5],[-36,128.5],[-24,120.5],[-81.5,108.5],[-118.5,91.5],[-109.5,56],[-86.5,40.5],[-88.5,-36.5],[-94.345,-43.153],[-131.5,-60.5],[-141.5,-33],[-162,-47.5],[-192.5,-44.5],[-195.5,-74],[-203.5,-102],[-192.5,-119],[-261,-96],[-116,133],[13.5,183.5],[152.5,92.5],[284.5,-37.5]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 14\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[60.5,4.5],[33,-53.5],[-216,-2],[-26,57],[0,0],[31.75,-44.75],[0,0],[23.25,-17],[7.331,2.533],[0,0],[71.25,-9],[2.582,12.514],[0,0],[25.75,11.5],[0,0],[2.148,1.563],[9.484,-0.688],[7.276,8.004],[0,0],[25.326,54.269],[0,0],[-1,47],[-78,-16.5],[0,0],[-45.5,1]],\"o\":[[-60.5,-4.5],[-33,53.5],[216,2],[26,-57],[0,0],[-31.75,44.75],[0,0],[-13.398,9.797],[-5.39,-1.862],[0,0],[-52.676,6.654],[-0.911,-4.413],[0,0],[-25.75,-11.5],[0,0],[-5.608,-4.08],[-11.281,0.818],[-17.5,-19.25],[0,0],[-19.25,-41.25],[0,0],[1,-47],[78,16.5],[0,0],[45.5,-1]],\"v\":[[-22.5,-220],[-310.5,-130],[-26,211],[269,3],[214.5,-60.75],[212.75,0],[133.75,28],[132.25,61],[100.032,67.35],[91.5,62.75],[34,132.5],[-33.077,103.505],[-33.75,96],[-72.25,105],[-75.25,82.25],[-78.691,79.592],[-105.219,68.932],[-134.5,57.75],[-133.25,17],[-218.75,-12],[-199.75,-68.25],[-231.25,-113.25],[-79.5,-196.5],[32,-125.5],[74,-183]],\"c\":true}],\"e\":[{\"i\":[[60.5,4.5],[33,-53.5],[-216,-2],[-26,57],[0,0],[25.45,-39.5],[15.885,-2.072],[40.05,-25.1],[9.357,-3.933],[0,0],[47.4,-4.2],[3.106,17.125],[0,0],[17.35,7],[0,0],[0.049,1.338],[29.267,9.081],[7.276,8.004],[0,0],[25.326,54.269],[0,0],[-1,47],[-78,-16.5],[0,0],[-45.5,1]],\"o\":[[-60.5,-4.5],[-33,53.5],[216,2],[26,-57],[0,0],[-21.259,32.4],[0,0],[-11.921,7.824],[-10.272,5.503],[0,0],[-52.911,3.672],[-1.095,-6.038],[0,0],[-17.35,-7],[0,0],[-0.129,-3.494],[-10.882,-2.012],[-17.5,-19.25],[0,0],[-19.25,-41.25],[0,0],[1,-47],[78,16.5],[0,0],[45.5,-1]],\"v\":[[-22.5,-220],[-310.5,-130],[-26,211],[227.8,6.9],[184.5,-52.65],[194.45,0.3],[141.85,18.7],[119.65,56.2],[89.79,79.411],[64.8,79.55],[19,134.9],[-49.872,89.081],[-50.85,78.9],[-74.95,96.9],[-70.55,71.65],[-70.039,69.571],[-103.719,49.432],[-136.6,44.25],[-139.55,13.4],[-218.15,-20.1],[-205.45,-68.25],[-224.95,-115.05],[-79.5,-196.5],[32.9,-139.9],[74,-183]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[60.5,4.5],[33,-53.5],[-216,-2],[-26,57],[0,0],[25.45,-39.5],[15.885,-2.072],[40.05,-25.1],[9.357,-3.933],[0,0],[47.4,-4.2],[3.106,17.125],[0,0],[17.35,7],[0,0],[0.049,1.338],[29.267,9.081],[7.276,8.004],[0,0],[25.326,54.269],[0,0],[-1,47],[-78,-16.5],[0,0],[-45.5,1]],\"o\":[[-60.5,-4.5],[-33,53.5],[216,2],[26,-57],[0,0],[-21.259,32.4],[0,0],[-11.921,7.824],[-10.272,5.503],[0,0],[-52.911,3.672],[-1.095,-6.038],[0,0],[-17.35,-7],[0,0],[-0.129,-3.494],[-10.882,-2.012],[-17.5,-19.25],[0,0],[-19.25,-41.25],[0,0],[1,-47],[78,16.5],[0,0],[45.5,-1]],\"v\":[[-22.5,-220],[-310.5,-130],[-26,211],[227.8,6.9],[184.5,-52.65],[194.45,0.3],[141.85,18.7],[119.65,56.2],[89.79,79.411],[64.8,79.55],[19,134.9],[-49.872,89.081],[-50.85,78.9],[-74.95,96.9],[-70.55,71.65],[-70.039,69.571],[-103.719,49.432],[-136.6,44.25],[-139.55,13.4],[-218.15,-20.1],[-205.45,-68.25],[-224.95,-115.05],[-79.5,-196.5],[32.9,-139.9],[74,-183]],\"c\":true}],\"e\":[{\"i\":[[60.5,4.5],[33,-53.5],[-216,-2],[-26,57],[0,0],[21.25,-36],[26.474,-3.453],[51.25,-30.5],[10.708,-8.243],[0,0],[31.5,-1],[-1.766,36.884],[0,0],[11.75,4],[0,0],[-3.386,6.92],[30.15,11.074],[7.276,8.004],[0,0],[25.326,54.269],[0,0],[-1,47],[-78,-16.5],[0,0],[-45.5,1]],\"o\":[[-60.5,-4.5],[-33,53.5],[216,2],[26,-57],[0,0],[-14.265,24.167],[0,0],[-10.936,6.508],[-13.527,10.413],[0,0],[-39.38,1.25],[0.737,-15.397],[0,0],[-11.75,-4],[0,0],[3.574,-7.303],[-10.617,-3.9],[-17.5,-19.25],[0,0],[-19.25,-41.25],[0,0],[1,-47],[78,16.5],[0,0],[45.5,-1]],\"v\":[[-22.5,-220],[-310.5,-130],[-26,211],[219.5,-3],[164.5,-47.25],[182.25,0.5],[147.25,12.5],[111.25,53],[82.963,87.452],[47,90.75],[9,136.5],[-47.234,77.116],[-65.75,66.5],[-76.75,91.5],[-89.75,70.75],[-63.481,66.009],[-102.72,36.432],[-138,35.25],[-143.75,11],[-217.75,-25.5],[-196.25,-80.75],[-220.75,-116.25],[-79.5,-196.5],[33.5,-149.5],[74,-183]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":14,\"s\":[0,0],\"h\":1},{\"t\":15,\"s\":[100,100],\"h\":1},{\"t\":21,\"s\":[0,0],\"h\":1}],\"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 13\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[5.25,-4.75],[0,0],[4.75,-21.5],[0,0],[-6.5,0],[0,0],[0,0],[-16.75,-10],[0,0],[-1.25,-13],[0,0],[-22,-3.75],[0,0],[-39,8.5],[0,0],[-10.5,4.25],[0,0],[0,8],[0,0],[12.5,6.25],[0,0],[19.5,-3.75],[0,0],[10.25,10.75],[0,0],[11.25,0.75]],\"o\":[[0,0],[-5.25,4.75],[0,0],[-4.75,21.5],[0,0],[6.5,0],[0,0],[0,0],[16.869,10.071],[0,0],[1.25,13],[0,0],[22,3.75],[0,0],[29.087,-6.339],[0,0],[10.5,-4.25],[0,0],[0,-8],[0,0],[-12.5,-6.25],[0,0],[-19.5,3.75],[0,0],[-10.25,-10.75],[0,0],[-11.25,-0.75]],\"v\":[[-57.5,-106.75],[-67.5,-93.5],[-81.5,-88.75],[-72.5,-48.25],[-103.75,-23.25],[-90,-19.75],[-77,-20],[-60.5,-28.25],[-36.75,-24],[-32.25,3.25],[-16.25,18.5],[-26.5,45.5],[26.5,34],[60.5,46.75],[69,-5.75],[100.5,1.75],[111.75,-7.5],[130,-12],[124.75,-27.75],[131.75,-42],[93.75,-49.75],[75.5,-83.25],[38.75,-60.25],[12.25,-68.5],[-14.5,-73.75],[-22,-95],[-42,-90.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":13,\"s\":[0,0],\"h\":1},{\"t\":14,\"s\":[100,100],\"h\":1},{\"t\":15,\"s\":[0,0],\"h\":1}],\"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 12\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[7.104,-15.316],[2.289,-6.151],[0.848,-7.19],[0,0],[-13.5,-3.25],[0,0],[-5,-5],[0,-11],[0,0],[-4.5,4],[-25,-2.5],[0,0],[3.5,2],[-4.5,3.25],[0.75,4.5],[-12.5,1],[0,0],[-3.25,13],[0,0],[16,8.75],[0,0],[18,-6],[0,0],[20.797,5.727]],\"o\":[[0,0],[-2.927,6.312],[-1.77,4.755],[-1.5,12.722],[0,0],[13.5,3.25],[0,0],[5,5],[0,11],[0,0],[4.5,-4],[25,2.5],[0,0],[-3.5,-2],[4.5,-3.25],[-0.75,-4.5],[12.5,-1],[0,0],[3.25,-13],[0,0],[-16,-8.75],[0,0],[-18,6],[0,0],[-34.5,-9.5]],\"v\":[[-52.5,-109],[-65.001,-76.769],[-75.095,-61.171],[-71.942,-42.082],[-80.75,-16.5],[-51.5,-22.75],[-29.25,-10],[-18.25,-7.75],[-14.5,16.5],[-18.25,53.75],[-11.5,39.75],[20.25,29.5],[54,48.25],[44.25,28.75],[44,15.75],[56.5,9.75],[61,-5.5],[101.5,-0.75],[111.25,-30],[135.5,-52.75],[94,-55.5],[72.25,-89],[40.75,-59.75],[6.5,-64.75],[-27.25,-62]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":12,\"s\":[0,0],\"h\":1},{\"t\":13,\"s\":[100,100],\"h\":1},{\"t\":14,\"s\":[0,0],\"h\":1}],\"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 11\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[6.003,-13.756],[0,0],[-14,2.5],[0,0],[5.291,13.421]],\"o\":[[0,0],[-6,13.75],[0,0],[14,-2.5],[0,0],[-5.125,-13]],\"v\":[[-53.375,-82],[-63.625,-51.875],[-61.5,-22.875],[-43.75,-36.25],[-34.5,-39.25],[-46.875,-58.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[16.5,-6],[0,0],[4.25,-3.5],[0,0],[19.5,1],[0,0],[3.226,-3.226],[0,0],[10.569,-9.65],[0,0],[-18.25,-8.75],[0,0],[-29.5,4],[0,0],[-7.5,9.75],[0,0],[8.25,9]],\"o\":[[0,0],[-16.5,6],[0,0],[-4.25,3.5],[0,0],[-19.5,-1],[0,0],[-3.5,3.5],[0,0],[-11.5,10.5],[0,0],[18.25,8.75],[0,0],[29.5,-4],[0,0],[7.5,-9.75],[0,0],[-8.25,-9]],\"v\":[[86.75,-70.5],[63.25,-56],[35.25,-58.25],[35.5,-41.5],[24,-43.75],[10.5,-35.5],[-8.75,-53.75],[-18.75,-42.75],[-29.75,-38],[-28.5,-15],[-50,-8.75],[-28,0.75],[0.25,30],[53.75,-10],[96.5,-0.25],[105.25,-16.25],[124,-35],[99.75,-45.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":11,\"s\":[0,0],\"h\":1},{\"t\":12,\"s\":[100,100],\"h\":1},{\"t\":13,\"s\":[0,0],\"h\":1}],\"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 10\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[15,-7.5],[0,0],[0,-4],[0,0],[-15.25,-7.75],[0,0],[-19.75,-0.5],[0,0],[-9.5,7],[0,0],[2,11.25],[0,0],[19.75,-1],[0,0],[7.5,0.5],[0,0],[9,3.5]],\"o\":[[0,0],[-15,7.5],[0,0],[0,4],[0,0],[15.25,7.75],[0,0],[19.75,0.5],[0,0],[9.5,-7],[0,0],[-2,-11.25],[0,0],[-19.75,1],[0,0],[-7.5,-0.5],[0,0],[-9,-3.5]],\"v\":[[-11.25,-61],[-33.5,-35],[-78.5,-38],[-62.5,-26],[-65.75,-20.75],[-34,-8.5],[-20.25,41.5],[14.25,27.5],[45,33.5],[49.5,18.25],[100.25,8.75],[89.5,-6.25],[112.5,-36.75],[76.25,-32],[45.25,-44.5],[31,-30.25],[23.5,-39],[7.75,-39.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":10,\"s\":[0,0],\"h\":1},{\"t\":11,\"s\":[100,100],\"h\":1},{\"t\":12,\"s\":[0,0],\"h\":1}],\"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 9\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[16.125,-12.625],[0,0],[-20,-11.625],[0,0],[-12.75,-1.25],[0,0],[-22.75,5.625],[0,0],[1.375,9.375],[0,0],[10.5,-1.5],[0,0],[14,3.625],[0,0],[4.502,2.606]],\"o\":[[0,0],[-15.664,12.264],[0,0],[12.524,7.279],[0,0],[12.75,1.25],[0,0],[11.093,-2.743],[0,0],[-1.942,-13.243],[0,0],[-10.5,1.5],[0,0],[-14,-3.625],[0,0],[-4.75,-2.75]],\"v\":[[-7.875,-60.625],[-18.875,-26.625],[-70,-16.375],[-32.25,0.625],[-12.375,27.875],[14.375,17.625],[39,24.5],[57.25,12.875],[93.375,19.25],[70.875,-3.125],[85.375,-33.375],[61.125,-21.375],[45.375,-39.375],[19.5,-19.25],[12.625,-40.375],[2,-41.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":9,\"s\":[0,0],\"h\":1},{\"t\":10,\"s\":[100,100],\"h\":1},{\"t\":11,\"s\":[0,0],\"h\":1}],\"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 8\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[0.234,-0.431],[1.555,-1.16],[1.939,-0.595],[3.017,0],[3.719,3.69],[0,0],[0.003,-0.024],[0.016,-0.145],[0.016,-0.189],[0.012,-0.184],[0.008,-0.154],[0.006,-0.15],[0.001,-0.038],[0.002,-0.065],[0.002,-0.347],[-0.015,-0.473],[-0.558,-2.51],[-0.158,-0.565],[-0.22,-0.629],[-0.111,-0.286],[-0.283,-0.601],[-2.606,-2.303],[0,0],[-13,-2.75],[-0.115,-3.471],[0,0],[-0.009,0.018],[-0.013,0.025],[-0.072,0.128],[-0.085,0.143],[-0.318,0.482],[-0.51,0.689],[-0.209,0.27],[-0.154,0.193],[-0.625,0.713],[-0.503,0.536],[-6.349,4.233],[-4.068,3.932],[0,0],[9.25,2.75]],\"o\":[[0,0],[-0.398,0.732],[-1.1,0.821],[-1.95,0.598],[-6.38,0],[-3.714,-3.685],[0,0],[-0.006,0.049],[-0.013,0.124],[-0.013,0.147],[-0.009,0.135],[-0.007,0.136],[-0.001,0.037],[-0.002,0.063],[-0.009,0.302],[-0.002,0.416],[0.059,1.914],[0.123,0.552],[0.173,0.62],[0.1,0.286],[0.233,0.603],[1.295,2.747],[7.054,6.234],[0,0],[7.107,1.503],[0.097,2.932],[0,0],[0.007,-0.014],[0.033,-0.063],[0.058,-0.103],[0.184,-0.31],[0.341,-0.517],[0.185,-0.25],[0.142,-0.184],[0.5,-0.628],[0.438,-0.5],[3.232,-3.448],[7.861,-5.241],[3.696,-3.572],[0,0],[-9.25,-2.75]],\"v\":[[15.5,-23],[15.18,-22.301],[12.402,-19.205],[7.896,-16.99],[0.5,-16],[-14.915,-23.383],[-20.75,-30.75],[-20.755,-30.714],[-20.789,-30.42],[-20.834,-29.949],[-20.872,-29.452],[-20.898,-29.017],[-20.918,-28.589],[-20.922,-28.477],[-20.928,-28.285],[-20.946,-27.31],[-20.928,-25.975],[-20.093,-19.204],[-19.673,-17.527],[-19.084,-15.651],[-18.768,-14.793],[-17.994,-12.986],[-12.25,-5.25],[-0.25,20.5],[12.5,14.25],[21.474,23.359],[20.5,28.75],[20.514,28.723],[20.545,28.663],[20.702,28.377],[20.916,28.007],[21.665,26.813],[22.938,24.998],[23.528,24.219],[23.972,23.653],[25.657,21.638],[27.066,20.083],[41.25,8.25],[59.322,-6.299],[65,-12.25],[32,-10]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.745,-2.726],[12.068,-0.909],[4.302,4.247],[0.462,0.231],[12.678,3.584],[0,0],[-0.041,-0.021],[-0.253,-0.146],[-0.329,-0.207],[-0.32,-0.216],[-0.268,-0.191],[-0.261,-0.194],[-0.066,-0.049],[-0.113,-0.087],[-0.605,-0.503],[-0.825,-0.758],[-4.395,-6.118],[-0.284,-0.721],[-0.199,-0.897],[-0.077,-0.423],[-0.148,-0.935],[-3.828,-3.083],[0,0],[-25.25,-0.25],[-5.739,-5.746],[0,0],[0.033,0.082],[0.044,0.113],[0.198,0.551],[0.197,0.599],[0.467,1.87],[0.331,2.417],[0.077,0.908],[0.029,0.63],[-0.234,2.067],[-0.374,1.404],[-17.234,0.302],[-5.596,9.561],[0,0],[13.5,4.5]],\"o\":[[0,0],[-4.665,4.632],[-9.639,0.726],[-4.327,-4.271],[0,0],[-16.224,-4.587],[0,0],[0.086,0.044],[0.216,0.125],[0.257,0.162],[0.236,0.159],[0.237,0.168],[0.064,0.048],[0.11,0.082],[0.526,0.402],[0.725,0.603],[3.339,3.07],[0.432,0.601],[0.312,0.792],[0.09,0.408],[0.163,0.892],[0.675,4.277],[18.91,15.233],[0,0],[14.24,0.141],[4.848,4.853],[0,0],[-0.026,-0.065],[-0.11,-0.28],[-0.16,-0.445],[-0.426,-1.297],[-0.5,-2.003],[-0.12,-0.876],[-0.053,-0.62],[-0.094,-2.046],[0.164,-1.448],[2.405,-9.032],[9.446,-0.166],[5.084,-8.686],[0,0],[-16.799,-5.6]],\"v\":[[54.5,-50],[50.349,-45.168],[25.084,-33.206],[4.55,-40.722],[-2.25,-49.75],[-31.928,-40.584],[-57.5,-47.75],[-57.438,-47.718],[-56.927,-47.436],[-56.107,-46.94],[-55.24,-46.373],[-54.483,-45.848],[-53.737,-45.306],[-53.542,-45.16],[-53.207,-44.907],[-51.508,-43.55],[-49.18,-41.511],[-37.345,-27.931],[-36.284,-25.941],[-35.534,-23.397],[-35.284,-22.149],[-34.833,-19.399],[-29.5,-7.5],[-22.75,40.25],[20.25,23.5],[49.757,35.694],[56.75,45],[56.699,44.875],[56.593,44.609],[56.124,43.352],[55.585,41.781],[54.2,36.98],[52.897,30.287],[52.599,27.609],[52.475,25.734],[52.656,19.531],[53.453,15.241],[80.25,-1.75],[103.419,-21.558],[111.5,-38.5],[68.75,-28.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[2.745,-2.726],[12.068,-0.909],[4.302,4.247],[0.462,0.231],[12.678,3.584],[0,0],[-0.041,-0.021],[-0.253,-0.146],[-0.329,-0.207],[-0.32,-0.216],[-0.268,-0.191],[-0.261,-0.194],[-0.066,-0.049],[-0.113,-0.087],[-0.605,-0.503],[-0.825,-0.758],[-4.395,-6.118],[-0.284,-0.721],[-0.199,-0.897],[-0.077,-0.423],[-0.148,-0.935],[-3.828,-3.083],[0,0],[-25.25,-0.25],[-5.739,-5.746],[0,0],[0.033,0.082],[0.044,0.113],[0.198,0.551],[0.197,0.599],[0.467,1.87],[0.331,2.417],[0.077,0.908],[0.029,0.63],[-0.234,2.067],[-0.374,1.404],[-17.234,0.302],[-5.596,9.561],[0,0],[13.5,4.5]],\"o\":[[0,0],[-4.665,4.632],[-9.639,0.726],[-4.327,-4.271],[0,0],[-16.224,-4.587],[0,0],[0.086,0.044],[0.216,0.125],[0.257,0.162],[0.236,0.159],[0.237,0.168],[0.064,0.048],[0.11,0.082],[0.526,0.402],[0.725,0.603],[3.339,3.07],[0.432,0.601],[0.312,0.792],[0.09,0.408],[0.163,0.892],[0.675,4.277],[18.91,15.233],[0,0],[14.24,0.141],[4.848,4.853],[0,0],[-0.026,-0.065],[-0.11,-0.28],[-0.16,-0.445],[-0.426,-1.297],[-0.5,-2.003],[-0.12,-0.876],[-0.053,-0.62],[-0.094,-2.046],[0.164,-1.448],[2.405,-9.032],[9.446,-0.166],[5.084,-8.686],[0,0],[-16.799,-5.6]],\"v\":[[54.5,-50],[50.349,-45.168],[25.084,-33.206],[4.55,-40.722],[-2.25,-49.75],[-31.928,-40.584],[-57.5,-47.75],[-57.438,-47.718],[-56.927,-47.436],[-56.107,-46.94],[-55.24,-46.373],[-54.483,-45.848],[-53.737,-45.306],[-53.542,-45.16],[-53.207,-44.907],[-51.508,-43.55],[-49.18,-41.511],[-37.345,-27.931],[-36.284,-25.941],[-35.534,-23.397],[-35.284,-22.149],[-34.833,-19.399],[-29.5,-7.5],[-22.75,40.25],[20.25,23.5],[49.757,35.694],[56.75,45],[56.699,44.875],[56.593,44.609],[56.124,43.352],[55.585,41.781],[54.2,36.98],[52.897,30.287],[52.599,27.609],[52.475,25.734],[52.656,19.531],[53.453,15.241],[80.25,-1.75],[103.419,-21.558],[111.5,-38.5],[68.75,-28.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1.565,-5.313],[16.823,-1.378],[4.657,5.118],[0.462,0.231],[21.428,4.584],[0,0],[0.22,-1.204],[1.111,-5.986],[1.158,-6.105],[0.894,-4.578],[1.181,-2.552],[1.368,-2.14],[0.351,-0.522],[0.613,-0.851],[2.727,-3.576],[1.234,-3.782],[-32.655,-20.569],[-0.475,-0.604],[-0.286,-0.767],[-0.099,-0.363],[-0.151,-0.799],[-5.643,-2.015],[0,0],[-19.5,-2],[-3.877,-4.428],[0,0],[0.023,0.157],[0.023,0.211],[0.003,0.987],[-0.104,1.025],[-1.199,2.816],[-3.172,2.927],[-1.468,0.977],[-1.166,0.614],[-2.271,1.294],[-1.786,0.955],[-15.982,-6.665],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-2.659,9.029],[-17.99,1.474],[-4.684,-5.148],[0,0],[-16.487,-3.527],[0,0],[-0.457,2.501],[-0.951,5.121],[-0.903,4.763],[-0.527,2.697],[-1.041,2.25],[-0.338,0.528],[-0.585,0.869],[-2.844,3.95],[-3.269,4.287],[0.52,-0.052],[0.766,0.482],[0.522,0.664],[0.13,0.348],[0.209,0.764],[0.691,3.651],[17.5,6.25],[0,0],[14.167,1.453],[3.274,3.74],[0,0],[-0.018,-0.123],[-0.057,-0.526],[-0.002,-0.797],[0.226,-2.22],[1.284,-3.017],[1.149,-1.061],[1.003,-0.667],[1.818,-0.957],[1.591,-0.906],[11.484,-6.14],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[63.75,-72.25],[62.021,-62.805],[35.834,-39.956],[4.146,-48.277],[-1.25,-59.25],[-29.928,-51.834],[-54.5,-100.5],[-54.841,-98.63],[-57.294,-85.322],[-60.519,-68.122],[-63.245,-53.938],[-65.868,-46.065],[-69.524,-39.48],[-70.557,-37.905],[-72.356,-35.325],[-81.007,-24.041],[-88.27,-11.948],[-41.345,-14.931],[-39.507,-13.293],[-38.326,-11.136],[-37.985,-10.069],[-37.471,-7.714],[-30.5,1.75],[-9.5,42.5],[17.25,25],[42.77,36.048],[46.75,43],[46.712,42.761],[46.65,42.257],[46.53,39.956],[46.667,37.208],[48.642,29.491],[55.126,20.374],[59.043,17.307],[62.294,15.383],[68.445,11.938],[73.517,9.122],[116.25,3.5],[106.708,-21.474],[119.5,-49],[85,-53.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[1.565,-5.313],[16.823,-1.378],[4.657,5.118],[0.462,0.231],[21.428,4.584],[0,0],[0.22,-1.204],[1.111,-5.986],[1.158,-6.105],[0.894,-4.578],[1.181,-2.552],[1.368,-2.14],[0.351,-0.522],[0.613,-0.851],[2.727,-3.576],[1.234,-3.782],[-32.655,-20.569],[-0.475,-0.604],[-0.286,-0.767],[-0.099,-0.363],[-0.151,-0.799],[-5.643,-2.015],[0,0],[-19.5,-2],[-3.877,-4.428],[0,0],[0.023,0.157],[0.023,0.211],[0.003,0.987],[-0.104,1.025],[-1.199,2.816],[-3.172,2.927],[-1.468,0.977],[-1.166,0.614],[-2.271,1.294],[-1.786,0.955],[-15.982,-6.665],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-2.659,9.029],[-17.99,1.474],[-4.684,-5.148],[0,0],[-16.487,-3.527],[0,0],[-0.457,2.501],[-0.951,5.121],[-0.903,4.763],[-0.527,2.697],[-1.041,2.25],[-0.338,0.528],[-0.585,0.869],[-2.844,3.95],[-3.269,4.287],[0.52,-0.052],[0.766,0.482],[0.522,0.664],[0.13,0.348],[0.209,0.764],[0.691,3.651],[17.5,6.25],[0,0],[14.167,1.453],[3.274,3.74],[0,0],[-0.018,-0.123],[-0.057,-0.526],[-0.002,-0.797],[0.226,-2.22],[1.284,-3.017],[1.149,-1.061],[1.003,-0.667],[1.818,-0.957],[1.591,-0.906],[11.484,-6.14],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[63.75,-72.25],[62.021,-62.805],[35.834,-39.956],[4.146,-48.277],[-1.25,-59.25],[-29.928,-51.834],[-54.5,-100.5],[-54.841,-98.63],[-57.294,-85.322],[-60.519,-68.122],[-63.245,-53.938],[-65.868,-46.065],[-69.524,-39.48],[-70.557,-37.905],[-72.356,-35.325],[-81.007,-24.041],[-88.27,-11.948],[-41.345,-14.931],[-39.507,-13.293],[-38.326,-11.136],[-37.985,-10.069],[-37.471,-7.714],[-30.5,1.75],[-9.5,42.5],[17.25,25],[42.77,36.048],[46.75,43],[46.712,42.761],[46.65,42.257],[46.53,39.956],[46.667,37.208],[48.642,29.491],[55.126,20.374],[59.043,17.307],[62.294,15.383],[68.445,11.938],[73.517,9.122],[116.25,3.5],[106.708,-21.474],[119.5,-49],[85,-53.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[3.034,-4.449],[16.823,-1.378],[5.031,3.872],[0.462,0.231],[21.428,4.584],[0,0],[0.666,-1.216],[4.246,-4.504],[5.715,-2.299],[5.72,0.653],[-1.111,-2.901],[-0.86,-3.859],[-0.167,-0.997],[-0.098,-1.735],[5.649,-6.598],[21.411,-2.755],[-17.155,-9.069],[-0.704,0.795],[-0.651,1.915],[-0.311,0.996],[-0.898,2.274],[-23.063,-16.396],[0,0],[-5.75,-25],[-1.277,0.025],[0,0],[-2.88,9.889],[-3.651,5.012],[10.017,2.955],[6.396,2.27],[-6.547,5.514],[-10.314,-2.616],[-3.35,-1.641],[-2.073,-1.239],[-0.373,0.893],[-0.383,0.957],[-26.68,-9.801],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-5.155,7.561],[-17.99,1.474],[-5.06,-3.894],[0,0],[-16.487,-3.527],[0,0],[-1.384,2.527],[-3.633,3.854],[-4.459,1.794],[-0.104,-0.025],[0.979,2.557],[0.212,0.952],[0.278,1.661],[0.431,7.668],[-6.773,7.911],[0.52,-0.052],[1.021,0.54],[0.774,-0.873],[0.296,-0.87],[0.655,-2.1],[4.108,-10.397],[32,22.75],[0,0],[6.321,27.484],[14.51,-0.283],[0,0],[2.264,-7.774],[8.41,-11.543],[-22.582,-6.663],[-16.246,-5.767],[12.051,-10.149],[3.738,0.948],[2.287,1.121],[0.436,0.261],[0.262,-0.625],[2.461,-6.155],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[78.25,-80.75],[73.886,-72.856],[41.834,-53.456],[9.4,-59.288],[3.25,-67.75],[-24.428,-71.334],[-43.5,-106],[-44.5,-104.052],[-52.95,-92.399],[-66.975,-82.478],[-82.245,-80.438],[-80.37,-75.793],[-77.363,-65.942],[-76.791,-63.014],[-76.21,-57.904],[-83.103,-35.932],[-123.77,-18.948],[-73.345,3.069],[-70.808,2.574],[-68.739,-1.757],[-67.836,-4.571],[-65.565,-11.261],[-30.5,-14.75],[-43.5,42],[26.25,42.5],[7.49,66.783],[32.25,109],[36.749,90.147],[45.709,69.016],[62.582,46.663],[54.246,20.267],[46.6,3.337],[80.594,-5.214],[91.246,-1.198],[97.794,2.383],[98.917,1.294],[99.852,-1.128],[135.25,-8.5],[125.708,-26.974],[138,-44],[98,-58.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[3.034,-4.449],[16.823,-1.378],[5.031,3.872],[0.462,0.231],[21.428,4.584],[0,0],[0.666,-1.216],[4.246,-4.504],[5.715,-2.299],[5.72,0.653],[-1.111,-2.901],[-0.86,-3.859],[-0.167,-0.997],[-0.098,-1.735],[5.649,-6.598],[21.411,-2.755],[-17.155,-9.069],[-0.704,0.795],[-0.651,1.915],[-0.311,0.996],[-0.898,2.274],[-23.063,-16.396],[0,0],[-5.75,-25],[-1.277,0.025],[0,0],[-2.88,9.889],[-3.651,5.012],[10.017,2.955],[6.396,2.27],[-6.547,5.514],[-10.314,-2.616],[-3.35,-1.641],[-2.073,-1.239],[-0.373,0.893],[-0.383,0.957],[-26.68,-9.801],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-5.155,7.561],[-17.99,1.474],[-5.06,-3.894],[0,0],[-16.487,-3.527],[0,0],[-1.384,2.527],[-3.633,3.854],[-4.459,1.794],[-0.104,-0.025],[0.979,2.557],[0.212,0.952],[0.278,1.661],[0.431,7.668],[-6.773,7.911],[0.52,-0.052],[1.021,0.54],[0.774,-0.873],[0.296,-0.87],[0.655,-2.1],[4.108,-10.397],[32,22.75],[0,0],[6.321,27.484],[14.51,-0.283],[0,0],[2.264,-7.774],[8.41,-11.543],[-22.582,-6.663],[-16.246,-5.767],[12.051,-10.149],[3.738,0.948],[2.287,1.121],[0.436,0.261],[0.262,-0.625],[2.461,-6.155],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[78.25,-80.75],[73.886,-72.856],[41.834,-53.456],[9.4,-59.288],[3.25,-67.75],[-24.428,-71.334],[-43.5,-106],[-44.5,-104.052],[-52.95,-92.399],[-66.975,-82.478],[-82.245,-80.438],[-80.37,-75.793],[-77.363,-65.942],[-76.791,-63.014],[-76.21,-57.904],[-83.103,-35.932],[-123.77,-18.948],[-73.345,3.069],[-70.808,2.574],[-68.739,-1.757],[-67.836,-4.571],[-65.565,-11.261],[-30.5,-14.75],[-43.5,42],[26.25,42.5],[7.49,66.783],[32.25,109],[36.749,90.147],[45.709,69.016],[62.582,46.663],[54.246,20.267],[46.6,3.337],[80.594,-5.214],[91.246,-1.198],[97.794,2.383],[98.917,1.294],[99.852,-1.128],[135.25,-8.5],[125.708,-26.974],[138,-44],[98,-58.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[6.576,-5.659],[16.823,-1.378],[3.037,3.373],[0.462,0.231],[21.428,4.584],[0,0],[1.606,-0.493],[6.379,-0.15],[4.115,3.263],[0.61,5.985],[2.643,-4.357],[3.58,-3.454],[0.934,-0.694],[1.658,-0.519],[20.332,-11.776],[33.133,3.243],[3.845,-28.569],[-10.184,-9.125],[-13.769,11.742],[3.455,10.353],[-2.553,1.233],[-12,-10.25],[0,0],[-5.75,-25],[-1.277,0.025],[0,0],[-9.917,35.373],[-5.572,2.347],[10.017,2.955],[6.771,0.47],[-6.547,5.513],[-13.71,-6.513],[-3.329,-4.1],[-1.121,-3.517],[-0.608,1.375],[-0.689,1.634],[-20.509,7.623],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-11.175,9.616],[-17.99,1.474],[-3.054,-3.393],[0,0],[-16.487,-3.527],[0,0],[-3.337,1.024],[-5.457,0.128],[-3.21,-2.546],[-0.104,-0.025],[-2.33,3.841],[-0.883,0.853],[-1.556,1.156],[-0.359,0.184],[-29.08,16.843],[0.52,-0.052],[-0.284,2.112],[10.727,9.61],[1.128,-0.962],[-5.837,-17.488],[9.307,-4.497],[29.855,25.501],[0,0],[6.321,27.484],[14.51,-0.283],[0,0],[2.958,-10.549],[13.162,-5.543],[-22.582,-6.663],[-18.246,-1.267],[12.051,-10.148],[4.968,2.36],[2.273,2.8],[0.154,0.484],[0.426,-0.964],[4.433,-10.511],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[88.75,-97.25],[78.03,-87.185],[31.834,-62.956],[3.382,-67.792],[1.25,-75.25],[-24.428,-71.334],[-16,-98],[-18.556,-97.148],[-34.444,-94.375],[-49.624,-98.443],[-55.745,-110.938],[-60.113,-103.143],[-69.147,-91.312],[-71.876,-88.979],[-76.71,-86.404],[-89.332,-55.724],[-164.27,-48.448],[-98.345,6.069],[-76.458,12.569],[-61.231,52.758],[-58.695,27.899],[-67.314,4.351],[-45,0.25],[-43.5,42],[16.25,42.5],[4.49,78.783],[8.75,110],[41.917,76.127],[54.209,63.516],[78.082,46.163],[59.746,14.267],[44.6,-0.663],[88.431,-4.862],[101.124,4.888],[106.294,14.383],[107.413,12.901],[109.077,8.954],[144.25,-31.5],[127.708,-39.474],[160.5,-74.5],[105,-62.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[6.576,-5.659],[16.823,-1.378],[3.037,3.373],[0.462,0.231],[21.428,4.584],[0,0],[1.606,-0.493],[6.379,-0.15],[4.115,3.263],[0.61,5.985],[2.643,-4.357],[3.58,-3.454],[0.934,-0.694],[1.658,-0.519],[20.332,-11.776],[33.133,3.243],[3.845,-28.569],[-10.184,-9.125],[-13.769,11.742],[3.455,10.353],[-2.553,1.233],[-12,-10.25],[0,0],[-5.75,-25],[-1.277,0.025],[0,0],[-9.917,35.373],[-5.572,2.347],[10.017,2.955],[6.771,0.47],[-6.547,5.513],[-13.71,-6.513],[-3.329,-4.1],[-1.121,-3.517],[-0.608,1.375],[-0.689,1.634],[-20.509,7.623],[-1.663,13.502],[0,0],[12.529,6.747]],\"o\":[[0,0],[-11.175,9.616],[-17.99,1.474],[-3.054,-3.393],[0,0],[-16.487,-3.527],[0,0],[-3.337,1.024],[-5.457,0.128],[-3.21,-2.546],[-0.104,-0.025],[-2.33,3.841],[-0.883,0.853],[-1.556,1.156],[-0.359,0.184],[-29.08,16.843],[0.52,-0.052],[-0.284,2.112],[10.727,9.61],[1.128,-0.962],[-5.837,-17.488],[9.307,-4.497],[29.855,25.501],[0,0],[6.321,27.484],[14.51,-0.283],[0,0],[2.958,-10.549],[13.162,-5.543],[-22.582,-6.663],[-18.246,-1.267],[12.051,-10.148],[4.968,2.36],[2.273,2.8],[0.154,0.484],[0.426,-0.964],[4.433,-10.511],[-0.5,0.25],[1.788,-14.514],[0,0],[-16.25,-8.75]],\"v\":[[88.75,-97.25],[78.03,-87.185],[31.834,-62.956],[3.382,-67.792],[1.25,-75.25],[-24.428,-71.334],[-16,-98],[-18.556,-97.148],[-34.444,-94.375],[-49.624,-98.443],[-55.745,-110.938],[-60.113,-103.143],[-69.147,-91.312],[-71.876,-88.979],[-76.71,-86.404],[-89.332,-55.724],[-164.27,-48.448],[-98.345,6.069],[-76.458,12.569],[-61.231,52.758],[-58.695,27.899],[-67.314,4.351],[-45,0.25],[-43.5,42],[16.25,42.5],[4.49,78.783],[8.75,110],[41.917,76.127],[54.209,63.516],[78.082,46.163],[59.746,14.267],[44.6,-0.663],[88.431,-4.862],[101.124,4.888],[106.294,14.383],[107.413,12.901],[109.077,8.954],[144.25,-31.5],[127.708,-39.474],[160.5,-74.5],[105,-62.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[7.465,-3.73],[9.494,-1.711],[10.434,2.468],[0.496,0.248],[18.678,4.709],[0,0],[12.5,3.101],[4.308,-0.253],[10.258,-0.589],[7.995,-3.062],[-2.86,-9.619],[7.626,-7.156],[-2.372,2.169],[-0.816,-6.558],[18.692,-11.954],[27.083,2.651],[38.345,-18.319],[-11.929,-4.473],[-13.769,11.742],[7.164,4.694],[-2.553,1.233],[-12,-10.25],[0,0],[-2,-32],[-1.277,0.023],[0,0],[-9.916,35.373],[-5.572,2.347],[10.228,1.648],[6.77,0.47],[-6.547,5.513],[-8.448,-13.157],[-11.041,-9.275],[-7.457,1.55],[6.485,2.248],[-0.337,2.269],[-14.63,3.811],[3.064,13.488],[0,0],[19.515,7.873]],\"o\":[[0,0],[-8.409,5.416],[-12.425,3.974],[-10.443,-2.478],[0,0],[-16.31,-4.212],[0,0],[-14.269,-3.094],[-2.758,-0.352],[-20.912,17.818],[-0.106,-0.026],[1.295,6.297],[0.505,2.515],[3.585,-3.288],[-0.438,0.224],[-19.053,11.632],[0.52,-0.052],[-1.201,1.173],[27.092,4.521],[1.128,-0.962],[-25.805,3.601],[9.307,-4.497],[29.854,25.501],[0,0],[2.529,27.828],[15.76,-0.283],[0,0],[2.957,-10.549],[13.162,-5.543],[-29.082,-3.913],[-18.246,-1.267],[12.074,-10.168],[4.697,14.927],[5.149,4.492],[0.447,0.065],[-4.701,-1.611],[2.192,-10.162],[-0.5,0.25],[-2.766,-13.586],[0,0],[-24.947,-10.088]],\"v\":[[96.75,-101],[83.232,-93.249],[53.084,-84.456],[23.857,-78.865],[1.25,-77],[-17.678,-70.084],[-14.75,-89.5],[-24.427,-100.718],[-45.942,-116.272],[-80.088,-122.818],[-128.995,-105.438],[-115.125,-97.132],[-114.626,-81.844],[-85.236,-91.076],[-72.21,-84.404],[-88.145,-54.129],[-144.77,-54.698],[-129.845,7.069],[-87.958,19.319],[-56.981,56.758],[-33.195,24.899],[-67.314,4.351],[-41,-5],[-41.25,36.5],[8,54.25],[-18.01,87.033],[-9,103.25],[38.166,88.627],[58.709,60.266],[80.832,42.663],[59.746,14.267],[44.6,-0.663],[89.478,5.704],[111.688,8.169],[133.544,10.883],[118.18,10.063],[111.313,1.384],[135,-26.5],[133.208,-41.474],[169.25,-75.5],[118.25,-70.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[7.465,-3.73],[9.494,-1.711],[10.434,2.468],[0.496,0.248],[18.678,4.709],[0,0],[12.5,3.101],[4.308,-0.253],[10.258,-0.589],[7.995,-3.062],[-2.86,-9.619],[7.626,-7.156],[-2.372,2.169],[-0.816,-6.558],[18.692,-11.954],[27.083,2.651],[38.345,-18.319],[-11.929,-4.473],[-13.769,11.742],[7.164,4.694],[-2.553,1.233],[-12,-10.25],[0,0],[-2,-32],[-1.277,0.023],[0,0],[-9.916,35.373],[-5.572,2.347],[10.228,1.648],[6.77,0.47],[-6.547,5.513],[-8.448,-13.157],[-11.041,-9.275],[-7.457,1.55],[6.485,2.248],[-0.337,2.269],[-14.63,3.811],[3.064,13.488],[0,0],[19.515,7.873]],\"o\":[[0,0],[-8.409,5.416],[-12.425,3.974],[-10.443,-2.478],[0,0],[-16.31,-4.212],[0,0],[-14.269,-3.094],[-2.758,-0.352],[-20.912,17.818],[-0.106,-0.026],[1.295,6.297],[0.505,2.515],[3.585,-3.288],[-0.438,0.224],[-19.053,11.632],[0.52,-0.052],[-1.201,1.173],[27.092,4.521],[1.128,-0.962],[-25.805,3.601],[9.307,-4.497],[29.854,25.501],[0,0],[2.529,27.828],[15.76,-0.283],[0,0],[2.957,-10.549],[13.162,-5.543],[-29.082,-3.913],[-18.246,-1.267],[12.074,-10.168],[4.697,14.927],[5.149,4.492],[0.447,0.065],[-4.701,-1.611],[2.192,-10.162],[-0.5,0.25],[-2.766,-13.586],[0,0],[-24.947,-10.088]],\"v\":[[96.75,-101],[83.232,-93.249],[53.084,-84.456],[23.857,-78.865],[1.25,-77],[-17.678,-70.084],[-14.75,-89.5],[-24.427,-100.718],[-45.942,-116.272],[-80.088,-122.818],[-128.995,-105.438],[-115.125,-97.132],[-114.626,-81.844],[-85.236,-91.076],[-72.21,-84.404],[-88.145,-54.129],[-144.77,-54.698],[-129.845,7.069],[-87.958,19.319],[-56.981,56.758],[-33.195,24.899],[-67.314,4.351],[-41,-5],[-41.25,36.5],[8,54.25],[-18.01,87.033],[-9,103.25],[38.166,88.627],[58.709,60.266],[80.832,42.663],[59.746,14.267],[44.6,-0.663],[89.478,5.704],[111.688,8.169],[133.544,10.883],[118.18,10.063],[111.313,1.384],[135,-26.5],[133.208,-41.474],[169.25,-75.5],[118.25,-70.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[8.354,-1.801],[2.166,-2.044],[17.831,1.563],[0.529,0.264],[15.928,4.834],[0,0],[23.394,6.694],[2.237,-0.356],[16.402,-4.442],[12.745,10.938],[-8.363,-14.88],[-8.895,-19.623],[-5.678,5.031],[-3.29,-12.596],[17.052,-12.132],[21.033,2.059],[72.845,-8.069],[-13.673,0.179],[-13.769,11.742],[10.872,-0.965],[-2.553,1.233],[-12,-10.25],[0,0],[1.75,-39],[-1.277,0.021],[0,0],[-9.916,35.373],[-5.572,2.347],[10.438,0.341],[6.77,0.47],[-6.547,5.513],[-3.187,-19.8],[-18.753,-14.45],[-13.794,6.617],[13.579,3.12],[0.014,2.904],[-8.75,0],[7.792,13.474],[0,0],[26.5,9]],\"o\":[[0,0],[-5.644,1.217],[-6.861,6.474],[-17.831,-1.563],[0,0],[-16.134,-4.896],[0,0],[-25.202,-7.211],[-0.059,-0.831],[-11.189,3.03],[-0.109,-0.026],[4.92,8.753],[1.894,4.178],[8.726,-7.733],[-0.517,0.264],[-9.026,6.421],[0.52,-0.052],[-2.118,0.235],[43.458,-0.569],[1.128,-0.962],[-29.305,2.601],[9.307,-4.497],[29.854,25.501],[0,0],[-1.264,28.173],[17.01,-0.283],[0,0],[2.957,-10.549],[13.162,-5.543],[-35.582,-1.163],[-18.246,-1.267],[12.097,-10.187],[4.425,27.494],[8.025,6.184],[0.739,-0.355],[-9.828,-2.259],[-0.049,-9.814],[-0.5,0.25],[-7.321,-12.659],[0,0],[-33.644,-11.426]],\"v\":[[104.75,-104.75],[88.433,-99.312],[74.334,-105.956],[44.331,-89.937],[1.25,-78.75],[-10.928,-68.834],[-13.5,-81],[-30.298,-104.289],[-57.441,-138.169],[-97.552,-120.193],[-142.245,-126.938],[-122.137,-101.12],[-106.105,-69.377],[-98.596,-93.173],[-66.71,-95.404],[-86.958,-52.535],[-125.27,-60.948],[-161.345,8.069],[-99.458,26.069],[-52.731,60.758],[-34.695,23.899],[-67.314,4.351],[-37,-10.25],[-34,22],[-0.25,66],[-40.51,95.283],[-7.75,132.5],[45.416,109.127],[63.209,57.016],[83.582,39.163],[59.746,14.267],[44.6,-0.663],[90.525,16.27],[122.253,11.45],[160.794,7.383],[128.948,7.226],[113.549,-6.186],[125.75,-21.5],[138.708,-43.474],[178,-76.5],[131.5,-78]],\"c\":true}]},{\"t\":19}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":8,\"s\":[0,0],\"h\":1},{\"t\":9,\"s\":[100,100],\"h\":1},{\"t\":20,\"s\":[0,0],\"h\":1}],\"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 7\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[11,-15],[0,0],[44.127,-18.522],[0,0],[9,-3.5],[0,0],[36,-22],[0,0],[16,-3],[0,0],[23.689,3.883],[0,0],[27.5,26],[0,0],[18.15,29.319],[0,0],[14.5,26],[0,0],[0,15],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[-2.5,-8.5],[0,0],[-4.5,0],[0,0],[-38.5,12.5],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11,15],[0,0],[-40.5,17],[0,0],[-9,3.5],[0,0],[-22.975,14.04],[0,0],[-12.777,2.396],[0,0],[-30.5,-5],[0,0],[-23.93,-22.625],[0,0],[-13,-21],[0,0],[-14.5,-26],[0,0],[0,-15],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[0,0],[2.5,8.5],[0,0],[4.5,0],[0,0],[38.5,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[250,-50.5],[229,-61.5],[225,-21],[195.5,-0.5],[178.5,67],[131.5,56],[118.5,71],[96,69],[98,133],[36.5,118],[26,145],[4,141],[-44.5,170],[-74,133],[-119.5,114],[-132,74],[-177,53],[-179.5,17],[-222.5,-14.5],[-231.5,-51],[-235.5,-75],[-217,-142.5],[-185,-181],[-154.5,-168.5],[-125,-208],[-51,-209],[-34,-187],[-14.5,-158.5],[-8.5,-135.5],[0,-138],[21,-124.5],[56.5,-189],[127,-211.5],[168.5,-181.5],[171.5,-151],[193.5,-163]],\"c\":true}],\"e\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[14.214,-19.286],[0,0],[41.287,-25.798],[0,0],[11.786,-6.929],[0,0],[36,-22],[0,0],[18.786,-2.357],[0,0],[23.179,8.005],[0,0],[25.357,18.071],[0,0],[18.514,28.968],[0,0],[15.143,26],[0,0],[-0.162,17.483],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[-0.143,-12.143],[0,0],[-9.029,0.202],[0,0],[-43.076,16.552],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.028,14.979],[0,0],[-36.813,22.655],[0,0],[-10.984,6.334],[0,0],[-22.975,14.04],[0,0],[-22.578,2.387],[0,0],[-33.283,-12.37],[0,0],[-24.477,-16.529],[0,0],[-13.3,-20.807],[0,0],[-15.439,-26.481],[0,0],[0.214,-20.357],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[12.842,4.055],[0.769,8.596],[0,0],[9.429,-0.214],[0,0],[34,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[267.143,-47.929],[233.5,-62.786],[225.857,-24.857],[198.5,-6.929],[185.143,58.086],[129.786,51.714],[118.286,72.929],[93.214,75.857],[90.286,136.214],[31.571,124],[15.714,148],[-10.357,135.214],[-57.657,152.043],[-84.714,107.071],[-125.971,98.014],[-142.071,63.071],[-184.5,42.071],[-187.429,9.5],[-226.143,-16],[-234.5,-56.357],[-241.071,-82.071],[-231.5,-145.929],[-191.5,-180],[-156.071,-171.929],[-129,-200.5],[-51,-209],[-34.3,-192.229],[-10.643,-154],[-12.357,-130.786],[1.5,-135.643],[24.643,-121.929],[53.5,-189.729],[127,-211.5],[175.143,-185.357],[184.143,-154.857],[199.5,-167.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[14.214,-19.286],[0,0],[41.287,-25.798],[0,0],[11.786,-6.929],[0,0],[36,-22],[0,0],[18.786,-2.357],[0,0],[23.179,8.005],[0,0],[25.357,18.071],[0,0],[18.514,28.968],[0,0],[15.143,26],[0,0],[-0.162,17.483],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[-0.143,-12.143],[0,0],[-9.029,0.202],[0,0],[-43.076,16.552],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.028,14.979],[0,0],[-36.813,22.655],[0,0],[-10.984,6.334],[0,0],[-22.975,14.04],[0,0],[-22.578,2.387],[0,0],[-33.283,-12.37],[0,0],[-24.477,-16.529],[0,0],[-13.3,-20.807],[0,0],[-15.439,-26.481],[0,0],[0.214,-20.357],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[12.842,4.055],[0.769,8.596],[0,0],[9.429,-0.214],[0,0],[34,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[267.143,-47.929],[233.5,-62.786],[225.857,-24.857],[198.5,-6.929],[185.143,58.086],[129.786,51.714],[118.286,72.929],[93.214,75.857],[90.286,136.214],[31.571,124],[15.714,148],[-10.357,135.214],[-57.657,152.043],[-84.714,107.071],[-125.971,98.014],[-142.071,63.071],[-184.5,42.071],[-187.429,9.5],[-226.143,-16],[-234.5,-56.357],[-241.071,-82.071],[-231.5,-145.929],[-191.5,-180],[-156.071,-171.929],[-129,-200.5],[-51,-209],[-34.3,-192.229],[-10.643,-154],[-12.357,-130.786],[1.5,-135.643],[24.643,-121.929],[53.5,-189.729],[127,-211.5],[175.143,-185.357],[184.143,-154.857],[199.5,-167.5]],\"c\":true}],\"e\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[16.357,-22.143],[0,0],[39.393,-30.649],[0,0],[13.643,-9.214],[0,0],[36,-22],[0,0],[20.643,-1.929],[0,0],[22.84,10.752],[0,0],[23.929,12.786],[0,0],[18.757,28.734],[0,0],[15.571,26],[0,0],[-0.27,19.138],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[1.428,-14.571],[0,0],[-12.048,0.336],[0,0],[-46.126,19.253],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.046,14.966],[0,0],[-34.355,26.426],[0,0],[-12.306,8.223],[0,0],[-22.975,14.04],[0,0],[-29.112,2.382],[0,0],[-35.139,-17.283],[0,0],[-24.842,-12.466],[0,0],[-13.5,-20.679],[0,0],[-16.065,-26.802],[0,0],[0.357,-23.929],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[21.403,6.759],[-0.385,8.661],[0,0],[12.714,-0.357],[0,0],[31,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[278.571,-46.214],[236.5,-63.643],[226.429,-27.428],[200.5,-11.214],[189.571,52.143],[128.643,48.857],[118.143,74.214],[91.357,80.429],[85.143,138.357],[28.286,128],[8.857,150],[-19.929,131.357],[-66.429,140.071],[-91.857,89.786],[-130.286,87.357],[-148.786,55.786],[-189.5,34.786],[-192.714,4.5],[-228.571,-17],[-236.5,-59.929],[-244.786,-86.786],[-219.5,-148.214],[-185,-181],[-158.786,-186.714],[-125,-208],[-51,-209],[-34.5,-195.714],[-8.071,-151],[-14.929,-127.643],[2.5,-134.071],[27.071,-120.214],[51.5,-190.214],[127,-211.5],[179.571,-187.929],[192.571,-157.429],[203.5,-170.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[16.357,-22.143],[0,0],[39.393,-30.649],[0,0],[13.643,-9.214],[0,0],[36,-22],[0,0],[20.643,-1.929],[0,0],[22.84,10.752],[0,0],[23.929,12.786],[0,0],[18.757,28.734],[0,0],[15.571,26],[0,0],[-0.27,19.138],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[1.428,-14.571],[0,0],[-12.048,0.336],[0,0],[-46.126,19.253],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.046,14.966],[0,0],[-34.355,26.426],[0,0],[-12.306,8.223],[0,0],[-22.975,14.04],[0,0],[-29.112,2.382],[0,0],[-35.139,-17.283],[0,0],[-24.842,-12.466],[0,0],[-13.5,-20.679],[0,0],[-16.065,-26.802],[0,0],[0.357,-23.929],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[21.403,6.759],[-0.385,8.661],[0,0],[12.714,-0.357],[0,0],[31,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[278.571,-46.214],[236.5,-63.643],[226.429,-27.428],[200.5,-11.214],[189.571,52.143],[128.643,48.857],[118.143,74.214],[91.357,80.429],[85.143,138.357],[28.286,128],[8.857,150],[-19.929,131.357],[-66.429,140.071],[-91.857,89.786],[-130.286,87.357],[-148.786,55.786],[-189.5,34.786],[-192.714,4.5],[-228.571,-17],[-236.5,-59.929],[-244.786,-86.786],[-219.5,-148.214],[-185,-181],[-158.786,-186.714],[-125,-208],[-51,-209],[-34.5,-195.714],[-8.071,-151],[-14.929,-127.643],[2.5,-134.071],[27.071,-120.214],[51.5,-190.214],[127,-211.5],[179.571,-187.929],[192.571,-157.429],[203.5,-170.5]],\"c\":true}],\"e\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[18.5,-25],[0,0],[37.5,-35.5],[0,0],[15.5,-11.5],[0,0],[36,-22],[0,0],[22.5,-1.5],[0,0],[22.5,13.5],[0,0],[22.5,7.5],[0,0],[19,28.5],[0,0],[16,26],[0,0],[-0.378,20.793],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[3,-17],[0,0],[-15.068,0.471],[0,0],[-49.176,21.954],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.065,14.952],[0,0],[-31.897,30.196],[0,0],[-13.629,10.112],[0,0],[-22.975,14.04],[0,0],[-35.645,2.376],[0,0],[-36.994,-22.196],[0,0],[-25.207,-8.402],[0,0],[-13.7,-20.55],[0,0],[-16.691,-27.123],[0,0],[0.5,-27.5],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[29.964,9.462],[-1.54,8.725],[0,0],[16,-0.5],[0,0],[28,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[290,-44.5],[239.5,-64.5],[227,-30],[202.5,-15.5],[194,35],[127.5,46],[118,75.5],[89.5,85],[66,130],[25,132],[2,152],[-29.5,127.5],[-71,119],[-99,72.5],[-136,72.5],[-155.5,48.5],[-194.5,27.5],[-198,-0.5],[-231,-18],[-238.5,-63.5],[-248.5,-91.5],[-220.5,-150.5],[-185,-181],[-160.5,-194],[-125,-208],[-51,-209],[-44.5,-191.5],[-5.5,-148],[-17.5,-124.5],[3.5,-132.5],[29.5,-118.5],[53,-186.5],[127,-211.5],[184,-190.5],[201,-160],[207.5,-173.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[18.5,-25],[0,0],[37.5,-35.5],[0,0],[15.5,-11.5],[0,0],[36,-22],[0,0],[22.5,-1.5],[0,0],[22.5,13.5],[0,0],[22.5,7.5],[0,0],[19,28.5],[0,0],[16,26],[0,0],[-0.378,20.793],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[3,-17],[0,0],[-15.068,0.471],[0,0],[-49.176,21.954],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-11.065,14.952],[0,0],[-31.897,30.196],[0,0],[-13.629,10.112],[0,0],[-22.975,14.04],[0,0],[-35.645,2.376],[0,0],[-36.994,-22.196],[0,0],[-25.207,-8.402],[0,0],[-13.7,-20.55],[0,0],[-16.691,-27.123],[0,0],[0.5,-27.5],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[29.964,9.462],[-1.54,8.725],[0,0],[16,-0.5],[0,0],[28,-12.5],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[290,-44.5],[239.5,-64.5],[227,-30],[202.5,-15.5],[194,35],[127.5,46],[118,75.5],[89.5,85],[66,130],[25,132],[2,152],[-29.5,127.5],[-71,119],[-99,72.5],[-136,72.5],[-155.5,48.5],[-194.5,27.5],[-198,-0.5],[-231,-18],[-238.5,-63.5],[-248.5,-91.5],[-220.5,-150.5],[-185,-181],[-160.5,-194],[-125,-208],[-51,-209],[-44.5,-191.5],[-5.5,-148],[-17.5,-124.5],[3.5,-132.5],[29.5,-118.5],[53,-186.5],[127,-211.5],[184,-190.5],[201,-160],[207.5,-173.5]],\"c\":true}],\"e\":[{\"i\":[[87,6.5],[77.5,-27.5],[-34.5,-95],[-123,2],[-41.5,62.5],[7,16],[0,0],[4,-26],[0,0],[16,-8],[0,0],[15.5,-11.5],[0,0],[36,-22],[0,0],[22.5,-1.5],[0,0],[24.183,10.182],[0,0],[21.5,14.5],[0,0],[33.716,19.267],[0,0],[-8.5,17],[0,0],[-0.378,20.793],[-14.5,23.5],[-17.5,10],[0,0],[-23,6],[-23.5,-8.5],[0,0],[-16.5,-28],[0,0],[-4.5,-1.5],[0,0],[-67,2.5],[-26,2.5],[-6.5,-9.5],[0,0],[-4,10]],\"o\":[[-87,-6.5],[-77.5,27.5],[34.5,95],[123,-2],[41.5,-62.5],[-7,-16],[0,0],[-2.813,18.285],[0,0],[-33.885,16.942],[0,0],[-13.629,10.112],[0,0],[-22.975,14.04],[0,0],[-35.645,2.376],[0,0],[-19,-8],[0,0],[-22.029,-14.857],[0,0],[-24.5,-14],[0,0],[14.242,-28.485],[0,0],[0.5,-27.5],[14.5,-23.5],[17.5,-10],[0,0],[23,-6],[23.5,8.5],[29.964,9.462],[4.498,7.633],[0,0],[7.604,2.535],[0,0],[37.937,-1.416],[26,-2.5],[6.5,9.5],[0,0],[4,-10]],\"v\":[[78,-220],[-180.5,-219],[-252,35.5],[-7,228.5],[186,157.5],[290,-44.5],[224.5,-67],[234,-35],[221,-5],[191.5,22],[140.5,33.5],[134.5,62.5],[94,67],[67,108.5],[25,123.5],[-9,128.5],[-37.5,96.5],[-75,102],[-89.5,75.5],[-130.5,60.5],[-149,28],[-197.5,19],[-223,-7.5],[-226,-41],[-197.5,-68],[-232.5,-100],[-205.5,-163.5],[-185,-181],[-160.5,-194],[-125,-208],[-51,-209],[-61,-190.5],[2,-149],[7.5,-124],[15,-129.5],[22.5,-122],[99,-187.5],[127,-211.5],[184,-190.5],[214.5,-161],[230.5,-180]],\"c\":true}]},{\"t\":14}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":4,\"s\":[0,0],\"h\":1},{\"t\":5,\"s\":[100,100],\"h\":1},{\"t\":15,\"s\":[0,0],\"h\":1}],\"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 6\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[1,-9.5],[0,0],[-21.5,-37],[0,0],[0.645,-15.487],[15.925,-9.187],[0,0],[3.5,-12.5],[0,0],[12,-10.5],[0,0],[14.255,-7.878],[0,0],[20,0],[0,0],[19,12.5],[0,0],[19.5,10.5],[0,0],[7,9],[0,0],[10,25],[0,0],[-5,23],[-1.5,-41],[-168,-21],[-6,63.5],[0,0]],\"o\":[[0,0],[-1,9.5],[0,0],[13.826,23.793],[0,0],[-1,24],[-13,7.5],[0,0],[-3.5,12.5],[0,0],[-12,10.5],[0,0],[-19,10.5],[0,0],[-20,0],[0,0],[-14.768,-9.716],[0,0],[-19.5,-10.5],[0,0],[-7,-9],[0,0],[-8.798,-21.996],[0,0],[5,-23],[1.5,41],[168,21],[6,-63.5],[0,0]],\"v\":[[161,-157.5],[173.5,-131],[172,-121],[212.5,-102.5],[207,-61],[216.5,-33],[191,9.5],[164.5,15.5],[162,32],[141.5,40],[119,79],[85,84.5],[65.5,111.5],[30,117],[-11.5,139.5],[-47.5,122],[-82,114.5],[-92.5,88],[-131.5,83.5],[-141,53],[-162.5,44.5],[-165,24],[-204,-8.5],[-207,-46],[-223.5,-87.5],[-242,17],[8,203],[243.5,-65.5],[167,-155.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.125,-0.25],[0,0],[-1,-6],[0,0],[-4.5,-1.625],[0,0],[-9.75,5.375],[0,0],[-16.25,4.375],[-3.75,0.25]],\"o\":[[-8.125,0.25],[0,0],[1,6],[0,0],[4.5,1.625],[0,0],[9.75,-5.375],[0,0],[16.25,-4.375],[3.75,-0.25]],\"v\":[[-0.5,-187],[-23,-167.375],[-10,-149],[-9.625,-138.75],[0.375,-137.375],[9.25,-128.25],[20.125,-148.875],[35.5,-154.25],[55.25,-177.125],[79.125,-184.375]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[38.5,5],[17,-6],[0,0],[-11.5,-4.5],[0,0],[-20,-4.5],[-11.5,-5.5]],\"o\":[[-38.5,-5],[-17,6],[0,0],[11.5,4.5],[0,0],[20,4.5],[11.5,5.5]],\"v\":[[132,-191],[53,-187],[45.5,-179.5],[77.5,-177],[92.5,-161],[136.5,-168],[185.5,-151.5]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[21,-4.5],[25,-33.5],[-5,9.5],[-9,7],[0,0],[-7,9.5],[0,0]],\"o\":[[-21,4.5],[-25,33.5],[5,-9.5],[9,-7],[0,0],[7,-9.5],[0,0]],\"v\":[[-139,-192],[-193.5,-146],[-194,-108],[-172.5,-138],[-139,-145],[-136,-167],[-99,-184]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":3,\"s\":[0,0],\"h\":1},{\"t\":4,\"s\":[100,100],\"h\":1},{\"t\":5,\"s\":[0,0],\"h\":1}],\"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 5\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[12.25,-16.5],[0,0],[16.631,-19.006],[0,0],[15.849,-11.073],[19,10],[0,0],[29.75,18.5],[0,0],[6,12.5],[0,0],[20,16.75],[0,0],[-3.5,-52],[-102.5,8.5],[-7,40.5]],\"o\":[[0,0],[-12.25,16.5],[0,0],[-14,16],[0,0],[-18.25,12.75],[-15.507,-8.161],[0,0],[-27.525,-17.117],[0,0],[-4.653,-9.694],[0,0],[-18.362,-15.378],[0,0],[3.5,52],[102.5,-8.5],[7,-40.5]],\"v\":[[162,-55],[154.75,-6.25],[126.75,0.75],[119,51.5],[70.75,66.25],[52.75,105.75],[-8.5,109],[-24.5,83.5],[-78.25,86],[-90.75,39.25],[-114.5,24],[-114.5,-0.75],[-144.75,-8.5],[-156,-46.25],[-172,21.5],[28,163],[175.5,44]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":2,\"s\":[0,0],\"h\":1},{\"t\":3,\"s\":[100,100],\"h\":1},{\"t\":4,\"s\":[0,0],\"h\":1}],\"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 4\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-0.25,-8],[0,0],[5,-23.5],[0,0],[17.5,-17.75],[0,0],[29.25,9.25],[0,0],[16,16.75],[0,0],[-21,-66.75],[-58,20.25],[6.25,12.75]],\"o\":[[0,0],[0.25,8],[0,0],[-5,23.5],[0,0],[-17.5,17.75],[0,0],[-29.25,-9.25],[0,0],[-16,-16.75],[0,0],[14.166,45.027],[58,-20.25],[-6.25,-12.75]],\"v\":[[88.5,-67.25],[93.75,-53.5],[87.5,-42],[90.25,-11.25],[69.5,5.75],[63.75,45.25],[16.25,45.25],[-32,63.5],[-60,29.75],[-95.75,9.5],[-99.5,-34.75],[-113.5,56.5],[54,87.5],[124.75,-56.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":1,\"s\":[0,0],\"h\":1},{\"t\":2,\"s\":[100,100],\"h\":1},{\"t\":3,\"s\":[0,0],\"h\":1}],\"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 3\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[2.939,-7.795],[-59.431,-21.088],[5.5,11.875],[0,0],[12.125,-13.5],[0,0],[15.75,-5.25],[0,0],[6.125,3.375],[0,0],[7.25,4.5],[0,0],[2.5,2]],\"o\":[[0,0],[-6.765,17.941],[85.25,30.25],[-5.5,-11.875],[0,0],[-12.125,13.5],[0,0],[-15.75,5.25],[0,0],[-6.125,-3.375],[0,0],[-12.545,-7.786],[0,0],[-9.847,-7.877]],\"v\":[[-57.75,-24.625],[-70.246,-16.343],[-14,60],[70.75,-22.25],[55.625,-22],[54.375,1.75],[31.5,10.375],[16,27.75],[-3.375,20.5],[-16.875,24.5],[-22.75,15],[-37,13.25],[-42.5,-6.375],[-54.5,-10.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":0,\"s\":[0,0],\"h\":1},{\"t\":1,\"s\":[100,100],\"h\":1},{\"t\":2,\"s\":[0,0],\"h\":1}],\"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 2\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[-4.875,7.75],[5.75,-10.25],[-23.25,-9],[-24,6.5],[-8.5,17],[7,9.5],[0,0],[14,-10.125],[0,0],[13.62,2.396],[0,0],[8.5,8],[0,0]],\"o\":[[2.396,-3.809],[-5.75,10.25],[23.25,9],[24,-6.5],[8.5,-17],[-7,-9.5],[0,0],[-12.926,9.348],[0,0],[-24.875,-4.375],[0,0],[-8.5,-8],[0,0]],\"v\":[[-33.75,-25.625],[-48.25,-25.25],[-34.5,39.75],[20.25,50.5],[57,34.5],[65.5,-4],[42.25,-13.625],[38,15.625],[11.5,17.125],[-7.5,32],[-21.875,11.875],[-38.5,5.875],[-26.75,-12.375]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":-1,\"s\":[0,0],\"h\":1},{\"t\":0,\"s\":[100,100],\"h\":1},{\"t\":1,\"s\":[0,0],\"h\":1}],\"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\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,1,1,1]},\"o\":{\"a\":0,\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"}],\"ip\":0,\"op\":41,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"Shape Layer 5\",\"parent\":3,\"td\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100},\"r\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[0,0,0]},\"a\":{\"a\":0,\"k\":[0,0,0]},\"s\":{\"a\":0,\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.125,0.75],[-3.375,-2.75],[-0.25,4]],\"o\":[[-3.125,-0.75],[3.375,2.75],[0.25,-4]],\"v\":[[13.75,-112],[9.25,-104.125],[18.25,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.093,-0.022],[0.1,0.082],[0.007,-0.119]],\"o\":[[0.093,0.022],[-0.1,-0.082],[-0.007,0.119]],\"v\":[[12.141,-106.916],[12.275,-107.15],[12.007,-107.057]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 89\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5.875,0.625],[0.375,-4],[-6.875,8.125]],\"o\":[[-5.875,-0.625],[-0.375,4],[6.875,-8.125]],\"v\":[[23.5,-128.375],[13.375,-120.75],[30.375,-116.75]],\"c\":true}],\"e\":[{\"i\":[[-0.121,-0.013],[-0.008,0.082],[0.142,-0.168]],\"o\":[[0.121,0.013],[0.008,-0.082],[-0.142,0.168]],\"v\":[[25.159,-118.615],[25.367,-118.773],[25.017,-118.855]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 88\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.25],[-4.25,-0.25]],\"o\":[[-4,0.25],[4.25,0.25]],\"v\":[[218,-136.75],[217.75,-132]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[217.75,-134.375],[217.75,-134.375]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 61\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[6.75,-0.25],[-1.25,-8.5],[-5.25,4]],\"o\":[[-6.75,0.25],[1.25,8.5],[5.25,-4]],\"v\":[[149.75,-94.75],[140.25,-85.25],[161.75,-81.5]],\"c\":true}],\"e\":[{\"i\":[[-0.06,0.002],[0.011,0.076],[0.047,-0.036]],\"o\":[[0.06,-0.002],[-0.011,-0.076],[-0.047,0.036]],\"v\":[[153.029,-85.796],[153.114,-85.881],[152.922,-85.914]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 62\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.25,1],[-1.25,-4],[4.75,-1.75],[-4,-4.25],[-1.25,5],[-2.386,2.936]],\"o\":[[-3.25,-1],[1.25,4],[-4.75,1.75],[4,4.25],[1.25,-5],[3.25,-4]],\"v\":[[219.75,-128],[213.75,-121],[212.25,-112.5],[209.5,-100.5],[223.25,-109.25],[222.25,-121.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.625,1.125],[2.25,0],[2.125,0.5],[0.75,-6.375],[-4.25,0],[0,2.125],[0,0],[-1.25,0],[0,0],[-1.25,-6.25],[-2.625,7.625]],\"o\":[[-3.625,-1.125],[-2.25,0],[-2.125,-0.5],[-0.75,6.375],[4.25,0],[0,-2.125],[0,0],[1.25,0],[0,0],[1.25,6.25],[2.625,-7.625]],\"v\":[[-136.75,-94.375],[-142.5,-90.5],[-148.125,-93.375],[-155.625,-85.25],[-150.125,-76.5],[-145,-80.25],[-144.75,-84.375],[-142.75,-82.875],[-139.625,-84.25],[-144.125,-71.625],[-130.25,-79.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.625,-0.75],[-0.25,-2.875],[3.375,0],[0,-2.5],[2.875,-2.375],[-5.25,-9],[0,0],[-0.25,-1.875],[0,0],[2.875,-0.75],[0,0],[4,-4.875],[-10.625,-4.125],[-1.375,3.875],[0,0],[0,0],[0,-4],[0,0],[-8.125,-5.5],[0,0],[-7.25,3.625],[0,0],[-1.625,0.5],[0,0],[-1.125,-3],[-2.75,5.125],[0,0],[-0.625,0.75],[0,0],[-2.25,-0.5],[0,0],[-4.75,1.125],[1.375,6.75],[4.375,-1.625],[0,0],[1,0.375],[0,0],[0.375,3.25],[8.25,2.625],[6.125,-2.5],[0,0],[1.875,0.625],[0,0],[1,2.875],[0,0],[-1.875,1.375],[-0.125,3.25],[4.75,0],[0,0],[0.5,2.125],[0,0],[-1.625,0.5],[-2.375,4.75],[0,0],[0.25,2.875],[-0.375,1],[0,0],[-1.625,1.375],[3.125,2.25],[0,0],[-0.375,2.5],[4.5,0],[1,2.25],[-1.75,1.125],[-4,-0.5],[1.375,4]],\"o\":[[-6.625,0.75],[0.25,2.875],[-3.375,0],[0,2.5],[-2.875,2.375],[5.25,9],[0,0],[0.25,1.875],[0,0],[-2.875,0.75],[0,0],[-4,4.875],[10.625,4.125],[1.375,-3.875],[0,0],[0,0],[0,4],[0,0],[8.125,5.5],[0,0],[7.25,-3.625],[0,0],[1.625,-0.5],[0,0],[1.125,3],[2.75,-5.125],[0,0],[0.625,-0.75],[0,0],[2.25,0.5],[0,0],[4.75,-1.125],[-1.375,-6.75],[-4.375,1.625],[0,0],[-1,-0.375],[0,0],[-0.375,-3.25],[-8.25,-2.625],[-6.125,2.5],[0,0],[-1.875,-0.625],[0,0],[-1,-2.875],[0,0],[1.875,-1.375],[0.125,-3.25],[-4.75,0],[0,0],[-0.5,-2.125],[0,0],[1.625,-0.5],[2.375,-4.75],[0,0],[-0.25,-2.875],[0.375,-1],[0,0],[1.625,-1.375],[-3.125,-2.25],[0,0],[0.375,-2.5],[-4.5,0],[-1,-2.25],[1.75,-1.125],[4,0.5],[-1.375,-4]],\"v\":[[-178.75,-127],[-187.125,-115.5],[-190.625,-108.375],[-197.25,-100.75],[-200.875,-92.25],[-202.375,-75],[-188.75,-71],[-189.625,-67],[-188,-62.875],[-193.25,-61.75],[-197.5,-56.125],[-210.75,-52.625],[-204.625,-30.25],[-186.75,-36.625],[-179.625,-39.875],[-176.75,-37],[-181.625,-31.375],[-177.75,-26.375],[-176.5,-15.125],[-162.125,-15.5],[-152.125,-11.75],[-152,-26],[-147.625,-23.5],[-143,-27],[-143.125,-21.125],[-135.25,-18.25],[-137.625,-26],[-135,-27.375],[-132.625,-30.375],[-129,-25.25],[-126.5,-27.125],[-117.5,-16.875],[-111.625,-36.125],[-125.125,-44.25],[-127.125,-34.5],[-129.375,-36.25],[-131.625,-36.75],[-130.375,-42.875],[-140.75,-51.125],[-158.875,-50.25],[-163,-39],[-167,-40.625],[-171.625,-40.625],[-171.875,-45.875],[-177.375,-50.5],[-172.25,-50.875],[-169,-58.25],[-175.5,-64.5],[-182.125,-59.625],[-181.25,-63.125],[-183,-66.5],[-178.75,-65.875],[-171.5,-70.75],[-171.125,-80],[-168.375,-85],[-171.625,-90.125],[-171.75,-92.625],[-165.75,-92],[-166.375,-96.75],[-173.75,-96.875],[-171.125,-101],[-177.75,-106.5],[-186.125,-110],[-183.25,-114.75],[-173.75,-116.25],[-167.625,-123.875]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 63\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.25,1.188],[-1.25,-6.188],[-2.625,2.75]],\"o\":[[-7.25,-1.188],[1.25,6.188],[2.625,-2.75]],\"v\":[[201.125,-142.25],[193.062,-136.25],[208.312,-131.438]],\"c\":true}],\"e\":[{\"i\":[[-0.095,-0.016],[0.016,0.081],[0.034,-0.036]],\"o\":[[0.095,0.016],[-0.016,-0.081],[-0.034,0.036]],\"v\":[[201.378,-135.982],[201.484,-136.06],[201.284,-136.123]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 51\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.875,1.188],[-1.875,-2.688]],\"o\":[[-2.875,-1.188],[1.875,2.688]],\"v\":[[173.562,-155.062],[170.938,-151.438]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[172.75,-152.5],[172.75,-152.5]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 52\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.688,0.875],[-1.5,-6.312],[-2.562,2.5]],\"o\":[[-7.688,-0.875],[1.5,6.312],[2.562,-2.5]],\"v\":[[159.062,-160.125],[148.938,-152.875],[164.562,-151.812]],\"c\":true}],\"e\":[{\"i\":[[-0.024,-0.003],[0.005,0.02],[0.008,-0.008]],\"o\":[[0.024,0.003],[-0.005,-0.02],[-0.008,0.008]],\"v\":[[157.276,-153.761],[157.308,-153.784],[157.258,-153.788]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 53\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.625,0.062],[1.212,-1.167],[2.188,-0.688],[-1.5,-4.375],[-2.875,1.938],[0,2.375]],\"o\":[[-1.625,-0.062],[-1.688,1.625],[-2.188,0.688],[1.5,4.375],[2.875,-1.938],[0,-2.375]],\"v\":[[173.75,-77.062],[171.25,-73.375],[166.375,-72.875],[162.75,-65],[174.125,-64.25],[176.625,-72.312]],\"c\":true}],\"e\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}],\"e\":[{\"i\":[[-0.038,-0.04],[-0.095,0],[-0.023,0.068],[0.098,0.095],[0.087,-0.059],[0,-0.072]],\"o\":[[0.034,0.036],[0.049,0],[0.022,-0.066],[-0.101,-0.097],[-0.087,0.059],[0,0.072]],\"v\":[[170.572,-68.07],[170.758,-68.019],[170.943,-68.159],[170.902,-68.428],[170.595,-68.451],[170.5,-68.244]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 54\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3,0.125],[-3.812,-5.375],[-0.562,2.688]],\"o\":[[-2.788,-0.116],[3.812,5.375],[0.562,-2.688]],\"v\":[[159.688,-49.25],[155.625,-42.188],[167.062,-44.438]],\"c\":true}],\"e\":[{\"i\":[[-0.083,-0.003],[0.105,0.149],[0.016,-0.074]],\"o\":[[0.077,0.003],[-0.105,-0.149],[-0.016,0.074]],\"v\":[[159.72,-42.919],[159.832,-43.114],[159.516,-43.052]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 55\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.812,0.688],[-2.688,-1.938]],\"o\":[[-1.812,-0.688],[2.688,1.938]],\"v\":[[168.375,-53.875],[167.312,-49.5]],\"c\":true}],\"e\":[{\"i\":[[0.061,0.023],[-0.091,-0.065]],\"o\":[[-0.061,-0.023],[0.091,0.065]],\"v\":[[167.439,-51.157],[167.403,-51.01]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 56\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.5,0.5],[-1.625,-5],[-1.75,4.625]],\"o\":[[-3.5,-0.5],[1.625,5],[1.75,-4.625]],\"v\":[[-39.5,-143.5],[-46.75,-133.25],[-34.5,-134.125]],\"c\":true}],\"e\":[{\"i\":[[0.14,0.02],[-0.065,-0.2],[-0.07,0.185]],\"o\":[[-0.14,-0.02],[0.065,0.2],[0.07,-0.185]],\"v\":[[-40.52,-136.42],[-40.81,-136.01],[-40.32,-136.045]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 57\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.638,-0.147],[-0.879,-2.418],[-0.879,1.759]],\"o\":[[-2.638,0.147],[0.879,2.418],[0.879,-1.759]],\"v\":[[-74.793,-156.267],[-77.871,-151.504],[-71.129,-152.31]],\"c\":true}],\"e\":[{\"i\":[[-0.18,0.01],[0.06,0.165],[0.06,-0.12]],\"o\":[[0.18,-0.01],[-0.06,-0.165],[-0.06,0.12]],\"v\":[[-74.48,-152.51],[-74.27,-152.835],[-74.73,-152.78]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 58\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,0.75],[-2,-3.125],[-0.5,2.375]],\"o\":[[-3.875,-0.75],[2,3.125],[0.5,-2.375]],\"v\":[[-160.125,-91],[-164.25,-84.75],[-156.5,-85.875]],\"c\":true}],\"e\":[{\"i\":[[0.526,0.102],[-0.272,-0.424],[-0.068,0.323]],\"o\":[[-0.526,-0.102],[0.272,0.424],[0.068,-0.323]],\"v\":[[-160.989,-87.273],[-161.549,-86.424],[-160.497,-86.577]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 59\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5,0.75],[-6.875,-6.125],[-1.25,3.875]],\"o\":[[-5,-0.75],[6.875,6.125],[1.25,-3.875]],\"v\":[[-153,-135.375],[-157,-126.875],[-142.5,-128.625]],\"c\":true}],\"e\":[{\"i\":[[-0.304,-0.046],[0.418,0.372],[0.076,-0.235]],\"o\":[[0.304,0.046],[-0.418,-0.372],[-0.076,0.235]],\"v\":[[-152.536,-128.016],[-152.293,-128.532],[-153.174,-128.426]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 60\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.75,-4.5],[-9.375,-3.625],[-3.125,2.375],[1.156,-5.286],[4.256,-4.745],[-5.106,-1.885],[2.75,7.875],[0.572,6.865]],\"o\":[[-8.75,4.5],[9.375,3.625],[2.994,-2.275],[-0.875,4],[-3.139,3.5],[8.125,3],[-2.75,-7.875],[-0.875,-10.5]],\"v\":[[142.375,-96.125],[143.75,-76.875],[160.75,-77.625],[169.5,-75.625],[163.494,-72.88],[164.5,-60.625],[177.375,-75],[167.75,-84]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.25,0],[0,0],[3.75,1.375],[8,-3.5],[0,0],[1.5,-1],[0,0],[3.75,-3.625],[0.5,-14.875],[0,0],[2.75,-1.75],[0,0],[5.5,-7],[-16.125,-2.875],[0,0],[-0.25,-2.375],[0,0],[-7.125,-3],[0,0],[-7.25,2.75],[0,0],[-5.125,1.5],[0,0],[-2,-0.5],[0,0],[-6,-0.75],[2.5,14.875],[0,0],[14.75,-1.75],[0,0],[0.75,2.125],[0,0],[-1.25,4.25],[0,0],[-1.75,4.25],[0,0],[-1.625,0],[0,0],[-2.125,-2.5],[0,0],[-2.75,0],[-3.375,4.625],[5.5,5.125],[0,0],[1.625,-0.25],[1.125,-1.75],[0,0],[1.875,2.375],[0,0],[2.625,2.75],[4.125,-0.625],[0,0],[-0.75,1.125],[0,0],[-2.375,-0.375],[-2.625,2.375],[0.625,1.75],[0,0],[-4.75,0.125],[-0.25,5.5]],\"o\":[[-8.25,0],[0,0],[-3.75,-1.375],[-8,3.5],[0,0],[-1.5,1],[0,0],[-3.75,3.625],[-0.5,14.875],[0,0],[-2.75,1.75],[0,0],[-5.5,7],[16.125,2.875],[0,0],[0.25,2.375],[0,0],[7.125,3],[0,0],[7.25,-2.75],[0,0],[5.125,-1.5],[0,0],[2,0.5],[0,0],[6,0.75],[-2.5,-14.875],[0,0],[-14.75,1.75],[0,0],[-0.75,-2.125],[0,0],[1.25,-4.25],[0,0],[1.75,-4.25],[0,0],[1.625,0],[0,0],[2.125,2.5],[0,0],[2.75,0],[3.375,-4.625],[-5.5,-5.125],[0,0],[-1.625,0.25],[-1.125,1.75],[0,0],[-1.875,-2.375],[0,0],[-2.625,-2.75],[-4.125,0.625],[0,0],[0.75,-1.125],[0,0],[2.375,0.375],[2.625,-2.375],[-0.625,-1.75],[0,0],[4.75,-0.125],[0.25,-5.5]],\"v\":[[-156.875,-136.875],[-163.125,-128.875],[-166.375,-126.5],[-182.625,-128.625],[-189,-113.125],[-191.875,-112.75],[-190.875,-110.125],[-197.125,-106.875],[-206,-80.375],[-189.875,-63.375],[-196,-63.125],[-198.75,-59],[-213.5,-53.875],[-203.375,-26.5],[-183.125,-35.875],[-184,-30.5],[-182,-25],[-177.75,-11.625],[-163.875,-11.5],[-150.875,-8.875],[-144.875,-18.875],[-136.25,-15.5],[-132.625,-26.5],[-129.875,-22.375],[-126.5,-22.875],[-119.75,-15.875],[-109.25,-33.625],[-127,-46.75],[-150.625,-54.75],[-165.5,-43.125],[-168.25,-46.625],[-171.625,-48.625],[-166,-56.125],[-168.75,-64.875],[-163.75,-71.25],[-166.375,-80.625],[-161.75,-80.5],[-158.5,-82.875],[-155.625,-73.5],[-147.5,-71.25],[-141.875,-66.625],[-131.5,-73.375],[-133.125,-94.125],[-142.875,-95.5],[-146.375,-98.25],[-153.375,-95.125],[-160.625,-93.125],[-162.125,-98.625],[-168.75,-99],[-166.875,-106.25],[-178.5,-108.875],[-184.125,-111.375],[-179.5,-112.5],[-177.625,-115.25],[-172.875,-113.25],[-165,-114.25],[-161.125,-123.375],[-160.125,-126.5],[-150.875,-123.375],[-140.125,-129]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.562,5.875],[1.562,-4.125],[2.188,-1.562],[-2.312,-2],[-3.5,2.688]],\"o\":[[-3.562,-5.875],[-1.562,4.125],[-2.188,1.562],[1.731,1.497],[3.5,-2.688]],\"v\":[[-33.688,-142.125],[-45.938,-140.688],[-51.562,-135.688],[-50.375,-129.562],[-37.25,-129.438]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.375,0.5],[-2.312,-3.25],[1.438,-4.312],[-6.438,-1.875],[-1.75,1.375],[2.062,2.25],[0.75,2.188],[1.312,1.062],[0,0],[-0.438,6.375]],\"o\":[[-4.375,-0.5],[2.312,3.25],[-1.438,4.312],[6.438,1.875],[1.75,-1.375],[-2.062,-2.25],[-0.75,-2.188],[-1.312,-1.062],[0,0],[0.438,-6.375]],\"v\":[[-74.688,-160],[-83.312,-150],[-81.938,-142.625],[-76.062,-127.5],[-61.812,-128.312],[-61.188,-133.625],[-67,-137.75],[-68.812,-144.188],[-75.938,-145.812],[-66.562,-153.812]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.25,0.875],[1.375,-4],[0,0],[0,-7.375],[-2.5,3.5],[0,0],[-2.5,8.125]],\"o\":[[-5.25,-0.875],[-1.375,4],[0,0],[0,7.375],[2.5,-3.5],[0,0],[2.5,-8.125]],\"v\":[[22,-130],[12.5,-123.75],[13.875,-115.75],[5.125,-105.125],[20,-101.125],[21.625,-110.75],[33,-118.5]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.875,1.75],[-5.5,-6],[-1.875,0.375],[0,0],[-0.5,-3.25],[0,0],[0,-13.75],[-1.375,4.5],[1.5,4.5],[-1.125,3.25],[3.75,3.75],[0,0]],\"o\":[[-7.875,-1.75],[5.5,6],[1.875,-0.375],[0,0],[0.5,3.25],[0,0],[0,13.75],[1.375,-4.5],[-1.5,-4.5],[1.125,-3.25],[-3.75,-3.75],[0,0]],\"v\":[[200.875,-143.625],[191.75,-133.625],[210.625,-128.75],[214.875,-129.625],[210.625,-122.375],[213.125,-116.75],[203.125,-103.875],[223.5,-103.875],[225,-116.5],[224.875,-126],[220.25,-137.375],[211.5,-137.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3,1.375],[-1,-7.375],[-3.125,0.875],[-2.25,-1.5],[0.125,4.125],[4.125,1]],\"o\":[[-3,-1.375],[1,7.375],[3.125,-0.875],[2.25,1.5],[-0.125,-4.125],[-4.125,-1]],\"v\":[[157,-162.875],[145.75,-154.125],[159.125,-148.75],[168.625,-148],[180.25,-151.75],[167.25,-160.75]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.375,0.875],[-0.625,-3],[1,1.75],[1.375,-6.875],[-6.125,2.375],[-2.75,1.125]],\"o\":[[-2.375,-0.875],[0.625,3],[-1,-1.75],[-1.375,6.875],[6.125,-2.375],[2.343,-0.958]],\"v\":[[169.25,-55.5],[166,-51.75],[162.25,-49.875],[152.75,-45.875],[164.75,-40.25],[169.875,-48.75]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 50\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[8.75,-0.625],[-7.375,-13.5],[-1.25,4.75]],\"o\":[[-8.75,0.625],[7.375,13.5],[1.25,-4.75]],\"v\":[[67.875,-134.75],[59.875,-116.375],[83.375,-117.75]],\"c\":true}],\"e\":[{\"i\":[[-0.034,0.002],[0.029,0.053],[0.005,-0.018]],\"o\":[[0.034,-0.002],[-0.029,-0.053],[-0.005,0.018]],\"v\":[[68.565,-119.064],[68.596,-119.136],[68.505,-119.13]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 41\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,1.125],[-2,-11.25],[-3.875,7]],\"o\":[[-6.75,-1.125],[2,11.25],[3.875,-7]],\"v\":[[196.25,-47.625],[186.125,-30.125],[205.125,-28.5]],\"c\":true}],\"e\":[{\"i\":[[0.237,0.04],[-0.07,-0.396],[-0.136,0.246]],\"o\":[[-0.237,-0.04],[0.07,0.396],[0.136,-0.246]],\"v\":[[196.552,-34.298],[196.195,-33.683],[196.864,-33.626]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 42\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.966,1.57],[0.343,-4.457],[-2.555,0.983]],\"o\":[[-2.966,-1.57],[-0.349,4.536],[4.536,-1.745]],\"v\":[[189.772,-1.472],[181.224,4.896],[188.464,10.217]],\"c\":true}],\"e\":[{\"i\":[[-0.214,-0.113],[-0.025,0.322],[0.184,-0.071]],\"o\":[[0.214,0.113],[0.025,-0.327],[-0.327,0.126]],\"v\":[[186.733,4.48],[187.35,4.02],[186.827,3.636]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 43\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.625,0.375],[-6.125,-6],[-1.25,4.375]],\"o\":[[-6.625,-0.375],[6.125,6],[1.25,-4.375]],\"v\":[[103.625,-133.75],[98.25,-121.5],[114.75,-125]],\"c\":true}],\"e\":[{\"i\":[[0.222,0.013],[-0.206,-0.201],[-0.042,0.147]],\"o\":[[-0.222,-0.013],[0.206,0.201],[0.042,-0.147]],\"v\":[[104.048,-125.112],[103.867,-124.701],[104.421,-124.819]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 44\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,0.625],[-3.875,-8.375],[-2.375,6.375]],\"o\":[[-6.75,-0.625],[3.875,8.375],[2.375,-6.375]],\"v\":[[211.625,-85.875],[201,-73.625],[220.375,-75.625]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.003],[-0.019,-0.041],[-0.012,0.031]],\"o\":[[-0.033,-0.003],[0.019,0.041],[0.012,-0.031]],\"v\":[[209.946,-75.924],[209.894,-75.864],[209.988,-75.874]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 45\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.25,0.625],[-3.375,-1.25]],\"o\":[[-3.25,-0.625],[3.375,1.25]],\"v\":[[-193,-116.125],[-194.625,-111.375]],\"c\":true}],\"e\":[{\"i\":[[-0.061,-0.012],[0.064,0.024]],\"o\":[[0.061,0.012],[-0.064,-0.024]],\"v\":[[-193.892,-113.387],[-193.861,-113.476]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 46\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.5,0.375],[-4.375,-3.875],[-0.125,3]],\"o\":[[-3.5,-0.375],[4.375,3.875],[0.125,-3]],\"v\":[[-60.625,-146.5],[-63.25,-139],[-55.25,-142.25]],\"c\":true}],\"e\":[{\"i\":[[0.298,0.032],[-0.372,-0.33],[-0.011,0.255]],\"o\":[[-0.298,-0.032],[0.372,0.33],[0.011,-0.255]],\"v\":[[-61.311,-141.468],[-61.535,-140.83],[-60.854,-141.106]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 47\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[4.462,1.05],[-3.413,-4.375],[-1.575,3.413]],\"o\":[[-4.463,-1.05],[3.412,4.375],[1.575,-3.412]],\"v\":[[1.113,-129.537],[-4.837,-120.788],[5.925,-120.613]],\"c\":true}],\"e\":[{\"i\":[[-0.071,-0.017],[0.054,0.069],[0.025,-0.054]],\"o\":[[0.071,0.017],[-0.054,-0.069],[-0.025,0.054]],\"v\":[[-0.399,-123.404],[-0.304,-123.543],[-0.475,-123.546]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 48\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.375,0.375],[-3.375,-4.125],[0,2.625]],\"o\":[[-2.375,-0.375],[3.375,4.125],[0,-2.625]],\"v\":[[135.875,-163.625],[132.125,-156.5],[141.5,-158.875]],\"c\":true}],\"e\":[{\"i\":[[0.077,0.012],[-0.109,-0.133],[0,0.085]],\"o\":[[-0.077,-0.012],[0.109,0.133],[0,-0.085]],\"v\":[[135.149,-158.363],[135.028,-158.133],[135.331,-158.21]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 49\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.07,-0.047],[-3.875,-7.25],[0,0],[-0.25,-4],[-5.875,-1.875],[0,2.75],[-3.25,1.25],[5.75,7.5],[5.333,-2.828],[0,0],[2.959,3.893]],\"o\":[[-8.25,0.125],[3.875,7.25],[0,0],[0.25,4],[5.875,1.875],[0,-2.75],[3.25,-1.25],[-2.966,-3.868],[-5.007,2.656],[0,0],[-1.754,-2.308]],\"v\":[[-1.25,-134.125],[-8.75,-118.75],[5.375,-113.5],[2.625,-104.875],[12.625,-92.75],[23.625,-105.625],[30.375,-111.5],[33.875,-127.875],[16.728,-131.431],[10.125,-120.875],[8.81,-131.165]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,1.375],[0.625,-3.5],[3.625,2.5],[7.5,-0.375],[-3.75,-9],[-9,1.125],[-5.875,-0.75],[-12.625,5.5]],\"o\":[[-10.25,-1.375],[-0.625,3.5],[-3.625,-2.5],[-7.5,0.375],[3.75,9],[9,-1.125],[5.875,0.75],[12.625,-5.5]],\"v\":[[104.875,-137.125],[93,-131.875],[82.875,-127.75],[68.75,-136.625],[55.375,-118.25],[76.875,-109.75],[90.125,-122],[112.5,-117.625]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.125,0.75],[-1.25,-11.375],[-3.25,-2.375],[1,-0.5],[3.5,-14.25],[-10.25,4],[0.625,3.75],[-2.125,4.25],[-2.125,4.5],[0.625,10]],\"o\":[[-5.125,-0.75],[1.25,11.375],[3.25,2.375],[-1,0.5],[-3.5,14.25],[10.25,-4],[-0.625,-3.75],[2.125,-4.25],[2.125,-4.5],[-0.625,-10]],\"v\":[[195.375,-51.125],[186.5,-34.25],[191.625,-20.25],[195.25,-14.75],[177,5.625],[187.75,17.625],[197.5,0.625],[194.125,-9.875],[201,-18],[205.375,-37.75]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.891,-8.168],[-9.875,-6.125],[0,0],[-1.625,-4.75],[0,0],[1,-1.625],[0,0],[7.125,-5.25],[-10.375,-0.375],[-2.875,5],[0,0],[-1.5,5.375],[8.735,11.767]],\"o\":[[-10,7.5],[9.875,6.125],[0,0],[1.625,4.75],[0,0],[-1,1.625],[0,0],[-5.73,4.222],[10.375,0.375],[2.875,-5],[0,0],[1.5,-5.375],[-9,-12.125]],\"v\":[[133.875,-97.5],[136.75,-75.875],[160,-72],[158.125,-61.125],[166.125,-57.375],[164,-54.875],[164,-51.625],[152.75,-52.125],[157.625,-36.375],[173.25,-47],[170.125,-58.25],[178.75,-64.125],[173,-84.375]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[13.632,3.84],[0,0],[8.75,1.375],[-6.25,-4],[-2.625,-2],[-12,-1.125],[-3.75,1.625],[0.375,-2.5],[-9.625,-3.125],[-1.875,-2.875],[1.875,-11.875],[1.875,-2.875],[-6.875,-5.625],[-1.75,8],[3.5,0.625],[-2.75,0.75],[-1.5,24.5],[6.125,1.375],[1.25,5.875]],\"o\":[[-17.75,-5],[0,0],[-8.75,-1.375],[6.25,4],[2.625,2],[12,1.125],[3.75,-1.625],[-0.375,2.5],[9.625,3.125],[1.875,2.875],[-1.875,11.875],[-1.875,2.875],[6.875,5.625],[1.75,-8],[-3.5,-0.625],[2.75,-0.75],[1.5,-24.5],[-6.125,-1.375],[-1.25,-5.875]],\"v\":[[164.25,-163.375],[141.75,-158.125],[134.625,-163.625],[133.5,-156.125],[141.25,-153.75],[157.625,-145.375],[180,-145.625],[185.625,-140.125],[194.75,-129],[209.375,-125.5],[199.75,-106.375],[203.625,-88.5],[201.625,-69.875],[221.125,-75.5],[211.5,-88.875],[210.625,-94.5],[228.375,-119.75],[199.625,-145.125],[183.5,-151.125]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[12.125,1.25],[0,0],[6.875,-5.375],[0,0],[3,-1],[0,0],[6.125,-21.125],[0,0],[3,-8.875],[-12.25,-6.25],[0,0],[0,-2.875],[-8.625,-4.75],[0,0],[-13,0.5],[0,0],[-5.75,0],[0,0],[-6.125,-0.625],[0.5,12.25],[13.625,7.375],[0,0],[0.875,2.875],[0,0],[-4.25,-1.125],[-3.75,0.875],[-2.5,9],[5.375,8.75],[1.75,-3.625],[0,0],[1.75,3.625],[0,0],[-4.5,3.5],[0,0],[-2,-0.5],[-3.125,6.5]],\"o\":[[-12.125,-1.25],[0,0],[-6.875,5.375],[0,0],[-3,1],[0,0],[-6.125,21.125],[0,0],[-3,8.875],[12.25,6.25],[0,0],[0,2.875],[8.625,4.75],[0,0],[13,-0.5],[0,0],[5.75,0],[0,0],[6.125,0.625],[-0.5,-12.25],[-13.625,-7.375],[0,0],[-0.875,-2.875],[0,0],[4.25,1.125],[3.75,-0.875],[2.5,-9],[-5.375,-8.75],[-1.75,3.625],[0,0],[-1.75,-3.625],[0,0],[4.5,-3.5],[0,0],[2,0.5],[3.125,-6.5]],\"v\":[[-153,-138.25],[-168.25,-132.75],[-185.25,-129.625],[-190,-114.875],[-194.75,-116.375],[-196,-112.625],[-211.25,-93.125],[-200.625,-63.375],[-218.375,-54.375],[-207.625,-23.625],[-184.375,-28.125],[-189.5,-19.5],[-181.625,-9.375],[-167.875,-6.5],[-154.625,-3.25],[-143.25,-14.625],[-137.125,-11.375],[-129.625,-15],[-121.75,-9],[-107.875,-28.125],[-130.625,-56.25],[-162.375,-53.875],[-158.25,-61.75],[-159.125,-71],[-150.25,-65.875],[-137,-65.25],[-127.375,-76.875],[-131.125,-100.875],[-147.875,-103.375],[-158.875,-95.625],[-159.75,-104.5],[-170.625,-110.5],[-161.875,-112.625],[-160,-124.125],[-153.375,-120.625],[-138.625,-126.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.5,2.75],[-1.5,-15.5],[-9.25,-0.375],[-1,1.375],[-6.25,0],[-1,4.5],[5.75,0.875],[1.875,-3.875],[0.5,2.25],[3.375,1.75],[0.75,-2],[0,0],[1.875,1.25],[0,0],[-2,3.875]],\"o\":[[-6.5,-2.75],[1.5,15.5],[9.25,0.375],[1,-1.375],[6.25,0],[1,-4.5],[-5.75,-0.875],[-1.875,3.875],[-0.5,-2.25],[-3.375,-1.75],[-0.75,2],[0,0],[-1.875,-1.25],[0,0],[2,-3.875]],\"v\":[[-72,-161.625],[-86.75,-140.75],[-69.25,-125.625],[-54.625,-131.875],[-47.125,-125.375],[-29.5,-135.625],[-38.75,-148.375],[-50.25,-140.625],[-55.375,-139.625],[-56.375,-146.25],[-65.5,-146.375],[-66.125,-140.875],[-69.125,-145.875],[-74.375,-147.125],[-64.875,-150.375]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 40\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.25,3],[-4,-4.25]],\"o\":[[-6.25,-3],[4,4.25]],\"v\":[[118.75,-151.25],[115,-144]],\"c\":true}],\"e\":[{\"i\":[[0.431,0.207],[-0.276,-0.293]],\"o\":[[-0.431,-0.207],[0.276,0.293]],\"v\":[[118.052,-147.293],[117.793,-146.793]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 29\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,0.75],[-3.5,-4.75],[-4.5,6.5]],\"o\":[[-5.75,-0.75],[3.5,4.75],[4.5,-6.5]],\"v\":[[138,-25.75],[132.5,-13],[144,-16.75]],\"c\":true}],\"e\":[{\"i\":[[-0.442,-0.058],[0.269,0.365],[0.346,-0.5]],\"o\":[[0.442,0.058],[-0.269,-0.365],[-0.346,0.5]],\"v\":[[138.808,-16.731],[139.231,-17.712],[138.346,-17.423]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 30\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.75,-2.25],[-8,-4.5],[0,6]],\"o\":[[-4.75,2.25],[8,4.5],[0,-6]],\"v\":[[92.25,65.25],[88.75,79.25],[106.75,69]],\"c\":true}],\"e\":[{\"i\":[[0.057,-0.027],[-0.096,-0.054],[0,0.072]],\"o\":[[-0.057,0.027],[0.096,0.054],[0,-0.072]],\"v\":[[93.732,73.277],[93.69,73.446],[93.907,73.322]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 31\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.5,1.25],[-6.75,-3.25]],\"o\":[[-6.5,-1.25],[6.75,3.25]],\"v\":[[-89,-175],[-90.75,-166]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-90,-169.5],[-90,-169.5]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 32\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[15,1],[-2.5,-10.75],[-4,5.25]],\"o\":[[-15,-1],[2.5,10.75],[4,-5.25]],\"v\":[[-111,-164.5],[-126.75,-146.5],[-100.25,-147]],\"c\":true}],\"e\":[{\"i\":[[-1.241,-0.083],[0.207,0.889],[0.331,-0.434]],\"o\":[[1.241,0.083],[-0.207,-0.889],[-0.331,0.434]],\"v\":[[-112.759,-149.477],[-111.457,-150.966],[-113.648,-150.925]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 33\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,-1.75],[-15.5,-8.5],[5.75,4.5]],\"o\":[[-5.75,1.75],[15.5,8.5],[-5.75,-4.5]],\"v\":[[129.5,37.25],[129,63],[147,42.75]],\"c\":true}],\"e\":[{\"i\":[[-0.037,0.011],[0.099,0.054],[-0.037,-0.029]],\"o\":[[0.037,-0.011],[-0.099,-0.054],[0.037,0.029]],\"v\":[[133.148,53.604],[133.151,53.439],[133.037,53.568]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 34\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[7.75,2.5],[-5.25,-4.5],[-0.25,5.5]],\"o\":[[-7.75,-2.5],[5.25,4.5],[0.25,-5.5]],\"v\":[[162.75,15.25],[154.25,31],[168.5,26]],\"c\":true}],\"e\":[{\"i\":[[-0.901,-0.291],[0.61,0.523],[0.029,-0.64]],\"o\":[[0.901,0.291],[-0.61,-0.523],[-0.029,0.64]],\"v\":[[159.401,25.157],[160.39,23.326],[158.733,23.907]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 35\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.25,2.5],[-2.625,-2.625]],\"o\":[[-3.898,-1.856],[2.625,2.625]],\"v\":[[-154.5,5.25],[-157.75,12.375]],\"c\":true}],\"e\":[{\"i\":[[-0.177,-0.084],[0.088,0.088]],\"o\":[[0.131,0.063],[-0.088,-0.088]],\"v\":[[-154.823,9.33],[-154.713,9.09]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 36\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.25],[-4.25,-7],[-0.125,7.5]],\"o\":[[-4.125,-1.25],[4.25,7],[0.125,-7.5]],\"v\":[[-147.5,25.5],[-150.5,40.875],[-132.875,46.5]],\"c\":true}],\"e\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":29,\"s\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}],\"e\":[{\"i\":[[-0.109,-0.033],[0.112,0.184],[0.003,-0.197]],\"o\":[[0.109,0.033],[-0.112,-0.184],[-0.003,0.197]],\"v\":[[-147.757,38.288],[-147.612,37.988],[-147.997,38.012]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 37\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.625],[-5.375,-9.5],[-3.625,10.125]],\"o\":[[-4.125,-1.625],[5.375,9.5],[3.625,-10.125]],\"v\":[[-101.25,-11.75],[-109.75,5.75],[-95.5,2.375]],\"c\":true}],\"e\":[{\"i\":[[0.177,0.07],[-0.231,-0.409],[-0.156,0.435]],\"o\":[[-0.177,-0.07],[0.231,0.409],[0.156,-0.435]],\"v\":[[-103.403,0.392],[-103.769,1.144],[-103.156,0.999]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 38\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.5,4.25],[-3.75,-9],[-2.75,-6.75],[-4.25,3.75],[0,0],[-2,10.25],[10.75,-2]],\"o\":[[-4.108,-1.838],[3.75,9],[2.75,6.75],[4.25,-3.75],[0,0],[2,-10.25],[-10.75,2]],\"v\":[[-3.25,-137.75],[-13.75,-121.75],[1.75,-100.5],[18,-91.5],[29,-107.5],[39,-118.5],[17.75,-135.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[22.75,-5.5],[0,0],[10.5,-18.5],[0,0],[-13,-24.25],[0,0],[-8,-6.75],[0,0],[-8,-0.25],[-9,0],[-6.25,-7.5],[-0.75,24.25],[0,0],[-3.75,9],[13.75,7.25],[4.75,3.5],[0,0],[-3.25,3.5],[0,0],[-3.25,8.75]],\"o\":[[-22.75,5.5],[0,0],[-10.5,18.5],[0,0],[13,24.25],[0,0],[8,6.75],[0,0],[8,0.25],[9,0],[6.25,7.5],[0.75,-24.25],[0,0],[3.75,-9],[-13.75,-7.25],[-4.75,-3.5],[0,0],[3.25,-3.5],[0,0],[3.25,-8.75]],\"v\":[[-169.75,-138.25],[-197.25,-118.5],[-212.5,-103.5],[-213.5,-68.75],[-219,-29.75],[-191.5,-20],[-188,-8],[-170,-3.25],[-158.75,2.75],[-137.75,-5.5],[-127.25,-5],[-105.25,-26],[-135.25,-61.25],[-126,-71.75],[-135,-105.75],[-154.5,-105.25],[-166.25,-107],[-157,-110.5],[-154,-118.25],[-134.75,-129.25]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10,5.75],[4,-7.5],[-13.5,-6.25],[-6.25,-2],[-7.75,3.25],[5.5,7],[4.25,-4.75],[0,0],[0,1.75],[0,0]],\"o\":[[-10,-5.75],[-4,7.5],[13.5,6.25],[6.25,2],[7.75,-3.25],[-5.5,-7],[-4.25,4.75],[0,0],[0,-1.75],[0,0]],\"v\":[[-68,-162.75],[-87,-154],[-79.5,-124.75],[-52.75,-123],[-32.25,-128.25],[-31,-147.25],[-48.75,-147.5],[-54.25,-139.75],[-54,-146],[-62.75,-151]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.75,3.5],[-1.25,-13.5],[0,0],[4.5,-9.75],[-5,-2.75],[-4.5,10.75],[-4,6],[0.5,8.5]],\"o\":[[-5.75,-3.5],[1.25,13.5],[0,0],[-1.977,4.283],[5,2.75],[4.5,-10.75],[4,-6],[-0.5,-8.5]],\"v\":[[199.5,-52.75],[182.25,-35.75],[190.75,-18],[174.75,2],[174.75,22.25],[199.25,8.25],[200.75,-12.5],[208,-33.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[16.25,6.75],[8.5,-13.25],[-7.5,-1],[0,0],[-2.5,-3.25],[0,0],[2.75,-9.25],[-10.75,3],[-2.75,14.25]],\"o\":[[-16.25,-6.75],[-8.5,13.25],[7.5,1],[0,0],[2.5,3.25],[0,0],[-2.75,9.25],[10.75,-3],[2.75,-14.25]],\"v\":[[163.25,-98.75],[124,-91.5],[139,-69.75],[152.75,-68],[152.5,-60.25],[159.25,-56.5],[144.5,-48.25],[158.75,-34.25],[180.5,-58]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[18,5.5],[0,0],[5.75,0.25],[-7.25,-7.5],[-9,-1.5],[0,0],[-6.75,-1.75],[0,0],[0,-10.5],[-17.75,8],[0,0],[6.5,27.25],[0,0]],\"o\":[[-18,-5.5],[0,0],[-5.75,-0.25],[7.25,7.5],[9,1.5],[0,0],[6.75,1.75],[0,0],[0,10.5],[17.75,-8],[0,0],[-6.5,-27.25],[0,0]],\"v\":[[164.75,-171.5],[142.5,-162.75],[132.75,-168],[129.5,-153.5],[155,-140.75],[180.25,-137.5],[194.25,-126],[204.25,-122.5],[193,-85.5],[215,-65.5],[219,-91.25],[232.25,-129.25],[186.25,-152.25]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.75,1.75],[0,0],[7.5,0.75],[3,-12.25],[-16.75,1.75],[-7.606,-2.48],[1.25,11.75]],\"o\":[[-17.527,-2.61],[0,0],[-5.855,-0.586],[-3.154,12.879],[16.75,-1.75],[11.5,3.75],[-0.954,-8.963]],\"v\":[[103.5,-145.75],[86.5,-129.75],[71.25,-138],[51.75,-125],[75,-107],[95.5,-115.25],[120,-128.25]],\"c\":true}},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 39\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.125,0.5],[-5.125,-1.625]],\"o\":[[-8.125,-0.5],[6.076,1.926]],\"v\":[[-91.625,-69.375],[-94.25,-62.5]],\"c\":true}],\"e\":[{\"i\":[[-0.375,-0.023],[0.237,0.075]],\"o\":[[0.375,0.023],[-0.28,-0.089]],\"v\":[[-91.625,-65.033],[-91.504,-65.35]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 27\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.25,-0.25],[-2.75,-10.5],[-2.125,6.25]],\"o\":[[-8.25,0.25],[2.75,10.5],[2.125,-6.25]],\"v\":[[-87.875,-94.125],[-98.25,-78.125],[-76.25,-80.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-87.562,-81],[-87.562,-81],[-87.562,-81]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 28\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.375],[-3.5,-5.125],[-0.625,4.5]],\"o\":[[-4,0.375],[3.5,5.125],[0.625,-4.5]],\"v\":[[-3.25,137.625],[-8.125,148],[4.125,143.25]],\"c\":true}],\"e\":[{\"i\":[[-0.092,0.009],[0.08,0.117],[0.014,-0.103]],\"o\":[[0.092,-0.009],[-0.08,-0.117],[-0.014,0.103]],\"v\":[[-3.442,145.361],[-3.33,145.123],[-3.611,145.232]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 26\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.506,2.794],[2.343,-6.218],[-5.137,0.09],[-0.541,3.424]],\"o\":[[-4.506,-2.794],[-2.343,6.218],[5.137,-0.09],[0.541,-3.424]],\"v\":[[-25.506,127.416],[-38.032,130.119],[-29.471,141.384],[-21.631,137.509]],\"c\":true}],\"e\":[{\"i\":[[-0.029,-0.018],[-0.015,0.04],[0.033,-0.001],[0.003,-0.022]],\"o\":[[0.029,0.018],[0.015,-0.04],[-0.033,0.001],[-0.003,0.022]],\"v\":[[-30.721,132.722],[-30.64,132.704],[-30.695,132.631],[-30.746,132.656]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 24\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.75,-1.625],[3.625,2],[-1,-3.625],[-1.212,0.387],[-1.56,-1.97],[-4.625,5.875],[1.75,2]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.343,1.244],[2.318,-0.74],[2.375,3],[4.625,-5.875],[-1.75,-2]],\"v\":[[-6.25,134.625],[-15.875,144.875],[-21,149.25],[-18.483,150.129],[-11.375,149.125],[5.125,147.625],[5,134.875]],\"c\":true}],\"e\":[{\"i\":[[4.75,-1.625],[3.625,2],[-0.625,-2.625],[-1.142,0.534],[-2.013,-0.633],[-5.5,-0.625],[0.923,5.539]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.177,0.742],[1.405,-0.656],[4.375,1.375],[3.107,0.353],[-0.75,-4.5]],\"v\":[[-5.125,140.125],[-13.375,145.375],[-19.125,147.375],[-16.356,148.417],[-12,146.375],[-3,150.75],[3.75,144.375]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 25\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.125,0.625],[-2.5,-2.5]],\"o\":[[-2.125,-0.625],[2.5,2.5]],\"v\":[[-79.625,43.625],[-81.125,46.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-80.562,46.125],[-80.562,46.125]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":23,\"s\":[0,0],\"h\":1}],\"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 14\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,2.25],[-2.25,-1.75]],\"o\":[[-4.25,-2.25],[2.25,1.75]],\"v\":[[-45.75,26.5],[-48.25,32]],\"c\":true}],\"e\":[{\"i\":[[0.236,0.125],[-0.125,-0.097]],\"o\":[[-0.236,-0.125],[0.125,0.097]],\"v\":[[-45.986,28.861],[-46.125,29.167]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 13\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3,-1.25],[-3,-5],[-7.75,1.75],[2,4.75]],\"o\":[[-3,1.25],[3,5],[7.75,-1.75],[-2,-4.75]],\"v\":[[-46.5,-2.25],[-52.5,8.25],[-39.75,18],[-31.5,2.5]],\"c\":true}],\"e\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}],\"e\":[{\"i\":[[-0.024,0.007],[0.005,0.025],[0.034,-0.008],[-0.009,-0.021]],\"o\":[[0.022,-0.007],[-0.004,-0.022],[-0.034,0.008],[0.009,0.021]],\"v\":[[-41.551,8.163],[-41.524,8.107],[-41.583,8.074],[-41.616,8.143]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 12\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,3],[0,-5.75],[-2.75,2.5]],\"o\":[[-4.25,-3],[0,5.75],[2.75,-2.5]],\"v\":[[121.75,-3.75],[113.5,0.75],[127.75,4.5]],\"c\":true}],\"e\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.023],[0,-0.044],[-0.021,0.019]],\"o\":[[-0.033,-0.023],[0,0.044],[0.021,-0.019]],\"v\":[[120.96,-0.289],[120.88,-0.242],[120.974,-0.207]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 11\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.5,-3.75],[0,0],[-4.5,-10.75],[-4,6.75],[7,7.5]],\"o\":[[-4.5,3.75],[0,0],[4.5,10.75],[4,-6.75],[-7,-7.5]],\"v\":[[75,14],[73.5,24],[70,39.25],[96.5,37.5],[94.75,14.5]],\"c\":true}],\"e\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}],\"e\":[{\"i\":[[0.032,-0.026],[0,0],[-0.032,-0.06],[-0.028,0.048],[0.049,0.053]],\"o\":[[-0.032,0.026],[0,0],[0.039,0.072],[0.028,-0.048],[-0.049,-0.053]],\"v\":[[87.186,24.88],[87.145,24.941],[87.158,25.053],[87.337,25.046],[87.325,24.884]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 10\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,1.25],[0,-5.75],[-5.75,8.5]],\"o\":[[-4.25,-1.25],[0,5.75],[5.75,-8.5]],\"v\":[[55.25,97.75],[44.25,114],[57.25,114]],\"c\":true}],\"e\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[53.375,111.25],[53.375,111.25],[53.375,111.25]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 15\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,-3.5],[-2.75,-8.75],[-8.25,-0.25],[4.75,14.75]],\"o\":[[-4.25,3.5],[2.75,8.75],[8.25,0.25],[-4.75,-14.75]],\"v\":[[-38.75,60],[-44.25,76.25],[-23.25,92.75],[-6.5,67]],\"c\":true}],\"e\":[{\"i\":[[0.07,-0.058],[-0.046,-0.145],[-0.137,-0.004],[0.079,0.244]],\"o\":[[-0.07,0.058],[0.046,0.145],[0.137,0.004],[-0.079,-0.244]],\"v\":[[-24.613,72.416],[-24.704,72.685],[-24.356,72.959],[-24.079,72.532]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 16\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[10,-2.5],[-7.25,-12.5],[-2.25,7]],\"o\":[[-10,2.5],[7.25,12.5],[2.25,-7]],\"v\":[[-78.25,74.5],[-88.75,93],[-67,89.75]],\"c\":true}],\"e\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}],\"e\":[{\"i\":[[-0.08,0.016],[0.058,0.078],[0.018,-0.044]],\"o\":[[0.08,-0.016],[-0.058,-0.078],[-0.018,0.044]],\"v\":[[-98.362,72.463],[-98.308,72.349],[-98.482,72.37]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 17\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.5,3],[-3.5,-5]],\"o\":[[-2.5,-3],[3.5,5]],\"v\":[[-119.5,57],[-124,63.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-122.25,61.125],[-122.25,61.125]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 18\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[9.5,-2.75],[2.5,-5],[0,0],[-7.25,-6.75],[-2,3.5],[0,0],[4,11]],\"o\":[[-9.5,2.75],[-2.5,5],[0,0],[7.25,6.75],[2,-3.5],[0,0],[-4,-11]],\"v\":[[-88.25,-97.75],[-104.5,-86.75],[-104.25,-71.5],[-104,-54],[-77,-59.5],[-76,-71.75],[-65.75,-92.5]],\"c\":true}],\"e\":[{\"i\":[[7.293,-2.111],[1.244,-4.107],[0,0],[-5.566,-5.182],[-1.293,4.188],[0,0],[3.071,8.444]],\"o\":[[-7.293,2.111],[-2.682,8.857],[0,0],[5.566,5.182],[2.519,-8.159],[0,0],[-3.071,-8.444]],\"v\":[[-90.843,-93.802],[-100.568,-86.607],[-95.626,-73.15],[-94.684,-64.466],[-82.707,-65.938],[-86.189,-72.842],[-76.821,-86.021]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 19\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3.967,1.543],[1.763,-7.714],[-2.94,1.96],[-6.391,2.204],[1.543,3.526],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-1.763,7.714],[6.612,-4.408],[2.668,-0.92],[-1.543,-3.526],[-0.441,-6.391]],\"v\":[[-11,-75.637],[-25.987,-66.38],[-13.645,-56.021],[-2.184,-52.275],[4.207,-59.107],[-5.049,-66.16]],\"c\":true}],\"e\":[{\"i\":[[3.967,1.543],[2.081,-7.714],[-4.12,1.96],[-6.467,-1.97],[2.293,4.357],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-2.081,7.714],[7.176,-3.414],[4.184,1.275],[-1.792,-3.406],[-0.441,-6.391]],\"v\":[[-9,-74.887],[-20.737,-69.38],[-10.395,-61.021],[-3.684,-56.025],[0.957,-62.107],[-4.549,-65.16]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 20\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[5.342,-0.929],[0.697,-7.896],[-9.754,4.645],[1.858,4.877]],\"o\":[[-5.342,0.929],[-0.697,7.896],[9.754,-4.645],[-1.858,-4.877]],\"v\":[[-151.777,-175.317],[-171.053,-161.846],[-149.686,-159.291],[-134.358,-173.923]],\"c\":true}],\"e\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}],\"e\":[{\"i\":[[0.034,-0.006],[0.004,-0.051],[-0.063,0.03],[0.012,0.031]],\"o\":[[-0.034,0.006],[-0.004,0.051],[0.063,-0.03],[-0.012,-0.031]],\"v\":[[-151.107,-165.155],[-151.177,-165.071],[-151.063,-165.011],[-151.017,-165.113]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 21\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4,-1.5],[-3,-8.25],[-4,-4.25],[0,0],[-4.25,-1.5],[0,0],[-12.5,8.75],[1.75,4],[15.25,-3.5],[0,0],[0,2.75],[0,0],[2.75,4.25]],\"o\":[[-4.521,1.695],[3,8.25],[4,4.25],[0,0],[4.25,1.5],[0,0],[12.5,-8.75],[-1.75,-4],[-15.25,3.5],[0,0],[0,-2.75],[0,0],[-2.75,-4.25]],\"v\":[[-46,102.5],[-47,128.25],[-35.5,146.25],[-26,150.5],[-15,160.5],[-5.75,156.75],[17.25,151.5],[34.75,132],[13,122.25],[-7.25,130.75],[-13.75,125.25],[-19.25,118.75],[-29.75,108.25]],\"c\":true}],\"e\":[{\"i\":[[1.993,-1.84],[-1.905,-5.238],[-3.64,-0.695],[0,0],[-2.699,-0.952],[0,0],[-9.612,4.283],[0.773,2.662],[9.683,-2.222],[0,0],[0.478,1.68],[0,0],[5.489,2.259]],\"o\":[[-3.975,3.671],[1.905,5.238],[3.728,0.712],[0,0],[2.699,0.952],[0,0],[8.85,-3.944],[-1.501,-5.17],[-9.683,2.222],[0,0],[-1.685,-5.922],[0,0],[-2.972,-1.223]],\"v\":[[-39.001,120.963],[-41.876,136.567],[-30.654,145.384],[-24.249,146.403],[-21.183,152.192],[-13.817,149.998],[0.041,151.703],[8.727,139.881],[-4.524,133.503],[-14.769,142.26],[-16.097,133.355],[-19.963,125.496],[-27.75,120.322]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 22\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[15,-6],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[3.5,1.75],[4.25,2.75],[0,0],[-1.5,14],[0,0],[3.5,17.25],[0,0],[-7,3.25],[0,0],[-3.5,0],[0,0],[-7.75,-0.75],[0,0],[-7.75,-5],[0,0],[-9,-1.5],[0.75,-2.5],[-6,1.75],[-8.25,0.75],[0,0],[-10.75,8.5],[0,0],[-2.25,3],[-3.5,-4.25],[-8,2.25],[-9,-4.5],[0,0],[13.75,3.5],[6.75,-10.75],[-9.25,-8.25],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-3.5,7.25],[0,0],[2.75,-8.25],[12.25,-5.25],[0,0],[6.5,-5],[4,-1.5],[4.5,-9.25],[-5.25,-1.25],[-4,5.5],[0,0],[-4.25,5.25],[0,0],[-24.5,19.75],[0,6.75],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[3.75,-1],[0,0],[7.25,1],[0,0],[3,-6],[0,0],[5,-1.25],[0,0],[5,1.25],[0,0],[7.25,4],[0,0],[4.75,4.5],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-15,6],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[-3.5,-1.75],[-4.25,-2.75],[0,0],[1.5,-14],[0,0],[-3.5,-17.25],[0,0],[7,-3.25],[0,0],[3.5,0],[0,0],[7.75,0.75],[0,0],[7.75,5],[0,0],[9,1.5],[-0.75,2.5],[6,-1.75],[8.25,-0.75],[0,0],[10.75,-8.5],[0,0],[2.25,-3],[3.5,4.25],[8,-2.25],[9,4.5],[0,0],[-13.75,-3.5],[-6.75,10.75],[9.25,8.25],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[3.5,-7.25],[0,0],[-2.75,8.25],[-12.25,5.25],[0,0],[-6.5,5],[-4,1.5],[-4.5,9.25],[5.25,1.25],[4,-5.5],[0,0],[4.25,-5.25],[0,0],[24.5,-19.75],[0,-6.75],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-3.75,1],[0,0],[-7.25,-1],[0,0],[-3,6],[0,0],[-5,1.25],[0,0],[-5,-1.25],[0,0],[-7.25,-4],[0,0],[-4.75,-4.5],[0,0]],\"v\":[[-71.75,-184],[-104.5,-167],[-132.75,-157],[-141.75,-147.5],[-191,-134],[-209.5,-120.75],[-230.25,-101],[-231.25,-77.75],[-234.5,-26.5],[-200.25,11.5],[-171.25,22.25],[-154.25,27.25],[-150.25,49],[-124.5,54.75],[-142,32.25],[-123.75,32.5],[-100,41.5],[-100,33.25],[-111.5,22],[-116.25,14.75],[-105,-11.5],[-113.5,-43.75],[-112,-88.5],[-126.5,-111.75],[-114.25,-118],[-109.25,-131.75],[-101.5,-134.5],[-96.25,-137.75],[-75,-130],[-54,-125.5],[-47.5,-110.25],[-30.5,-105.75],[-17.25,-93.75],[-4.5,-84.5],[10.5,-85],[34.25,-85],[51.75,-89.75],[71,-92.5],[87,-106.25],[107.5,-111.25],[120.25,-110.5],[141,-104.5],[164.5,-106.5],[174.75,-87.75],[157.5,-99.75],[112.5,-94],[114.25,-62],[134.5,-48.5],[129,-36],[123.25,-19.25],[130.75,-5.5],[146.75,-18.75],[162.5,-33.5],[169.5,-45.75],[176.25,-22.75],[149.5,-4.25],[127.75,20.75],[110,31.5],[90,51.25],[70,73.75],[66,92],[108,69.25],[116,51],[136.5,46.75],[140,31.75],[182.75,18.5],[204.75,-20.25],[204.75,-46],[222.25,-67.75],[230,-86],[239.25,-114.5],[218.75,-141],[199.25,-148.5],[171.5,-176.75],[145.25,-176.75],[130,-176.75],[120.25,-165.25],[100.25,-163.75],[87.75,-159.75],[66,-157.25],[67.25,-142.25],[44.5,-126.75],[28,-126],[15.5,-131.5],[3.75,-132.75],[-4.25,-139.75],[-10.75,-139.75],[-23,-156.5],[-41.75,-163.75]],\"c\":true}],\"e\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[23.666,-4.733],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[-5.753,-0.846],[-3.456,-2.925],[0,0],[1.106,18.528],[0,0],[3.5,17.25],[0,0],[-3.451,6.903],[3.486,4.183],[-8.825,5.711],[0,0],[-16.259,-12.646],[0,0],[-8,1.75],[0,0],[-6.965,-5.894],[-3.973,-8.513],[-6,-2],[-5.96,5.754],[0,0],[-13.621,1.513],[0,0],[-10.021,4.432],[0.095,5.505],[-4.5,0],[-42.5,-3],[0,0],[13.324,4.877],[6.75,-10.75],[-33.25,-3.5],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-11,4],[0,0],[-3.25,-10.25],[12.25,-5.25],[0,0],[11.302,-9.247],[4,-1.5],[4.5,-9.25],[-9.5,-6],[-4.5,16.75],[0,0],[-10.5,11.25],[0,0],[-24.5,19.75],[2.75,9.25],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[11.616,-4.937],[0,0],[7.25,1],[0,0],[5.447,-3.915],[0,0],[11.597,-4.481],[0,0],[10.556,4.59],[0,0],[9.25,-0.75],[0,0],[15.169,11.507],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-35,7],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[8.5,1.25],[6.5,5.5],[9.25,-0.25],[-2,-33.5],[0,0],[-3.5,-17.25],[0,0],[4.75,-9.5],[0,0],[8.5,-5.5],[0,0],[4.5,3.5],[0,0],[9.01,-1.971],[0,0],[9.75,8.25],[3.5,7.5],[5.929,1.976],[7.25,-7],[0,0],[13.5,-1.5],[0,0],[13,-5.75],[-0.25,-14.5],[8.31,0],[38.666,2.729],[0,0],[-28,-10.25],[-6.75,10.75],[12.326,1.298],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[7.566,-2.751],[0,0],[2.628,8.29],[-12.25,5.25],[0,0],[-11,9],[-4,1.5],[-4.5,9.25],[4.563,2.882],[0.598,-2.226],[0,0],[11.75,-12.589],[0,0],[24.5,-19.75],[-5.632,-18.945],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-10,4.25],[0,0],[-7.25,-1],[0,0],[-8,5.75],[0,0],[-11,4.25],[0,0],[-11.5,-5],[0,0],[-8.253,0.669],[0,0],[-14.5,-11],[0,0]],\"v\":[[-83.75,-180],[-106.5,-171],[-126.25,-164],[-135.25,-146.5],[-164.5,-144.5],[-202,-120.75],[-220.75,-106],[-216.75,-74.25],[-227.5,-34],[-194.25,-8],[-173.75,2.75],[-154.25,21.25],[-148.75,44],[-131,50.75],[-148,20.25],[-149.75,2],[-140,1.5],[-132.5,5.25],[-122.5,5],[-104.25,14.25],[-91,-8.5],[-123.5,-62.25],[-121.5,-95.5],[-144,-115.75],[-131.75,-121.5],[-126.25,-136.75],[-105.5,-137.5],[-91.75,-152.25],[-83.5,-123.5],[-68,-117.5],[-47.5,-118.25],[-20.5,-132.25],[-12.25,-114.25],[-1,-97],[14,-83],[29.75,-101.5],[45.75,-114.25],[71,-101],[93.5,-105.25],[114,-111.25],[122.25,-128.5],[127.5,-147.5],[173.5,-133],[185.25,-81.25],[164.5,-102.25],[118,-91],[145.25,-64.5],[142.5,-51.5],[139,-35.5],[130.75,-23.25],[137.25,-11.5],[145.75,-28.25],[169,-33.5],[181,-56.25],[179.25,-25.25],[168,3.75],[145.75,30.25],[127,39.5],[114.5,60.75],[84.5,62.75],[85.5,84],[113.5,68.25],[115,68],[142.5,57.75],[149,34.75],[191.75,18.5],[210.75,-34.75],[199.25,-56],[224.25,-60.75],[225.5,-92.5],[236.75,-118],[220.25,-147],[188.75,-156.5],[169,-173.75],[140.25,-167.75],[127,-169.75],[121.25,-157.25],[106.75,-156.75],[106.25,-156.75],[88.5,-152.75],[83.25,-137.75],[59.5,-139.25],[46.5,-119],[31.5,-134],[12.75,-138.75],[-4.25,-139.75],[-18.25,-134.75],[-30.5,-154],[-51.75,-154.25]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 23\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.75,2.5],[2.75,-6.625],[-6.375,0],[-2.875,6.25]],\"o\":[[-3.75,-2.5],[-2.75,6.625],[6.375,0],[2.875,-6.25]],\"v\":[[61.125,-3.375],[45.375,4.375],[45.875,20.625],[61.375,9.375]],\"c\":true}],\"e\":[{\"i\":[[0.499,0.333],[0.366,-0.881],[-0.848,0],[-0.382,0.831]],\"o\":[[-0.499,-0.333],[-0.366,0.881],[0.848,0],[0.382,-0.831]],\"v\":[[49.836,-0.797],[47.741,-0.199],[48.339,1.63],[50.368,0.799]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":15,\"s\":[0,0],\"h\":1},{\"t\":16,\"s\":[100,100],\"h\":1},{\"t\":20,\"s\":[0,0],\"h\":1}],\"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 9\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[18.934,5.164],[12.016,-5.06],[0,0],[7.451,1.765],[5.645,-0.226],[8.945,-6.665],[0,0],[3.262,5.811],[4.317,4.176],[8.725,3.611],[3.199,1.087],[3.063,0.78],[3.171,0.415],[1.81,-0.109],[0,0],[1.157,0.458],[3.871,0.977],[29.142,-11.922],[4.627,-7.197],[0.375,-1.333],[0,0],[13,-29.5],[0,0],[-23,-39],[0,0],[-16,-9],[-7.135,-0.67],[-1.267,-0.023],[0,0],[-0.432,-0.986],[-0.407,-0.855],[-0.265,-0.527],[-0.148,-0.286],[-1.643,-2.364],[-1.437,-1.437],[-3.036,-1.535],[-0.155,-0.076],[-0.051,-0.025],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-30,23],[0,0],[-20,9.5],[0,0],[-7,12],[-0.795,3.115],[-0.216,2.726],[0.096,1.897],[0,0],[-29.425,54.272],[0,0],[-3.315,6.41],[4.925,18.605],[0,0],[6.451,10.777]],\"o\":[[-22.018,-6.005],[-8.995,3.788],[0,0],[-4.31,-1.021],[-8.324,0.333],[-25.5,19],[0,0],[-2.036,-3.627],[-4.834,-4.676],[-3.662,-1.515],[-3.671,-1.247],[-4.464,-1.138],[-4.901,-0.642],[-1.06,0.064],[0,0],[-1.686,-0.668],[-12.803,-3.233],[-26.494,10.838],[-1.791,2.785],[-0.265,0.943],[0,0],[-13,29.5],[0,0],[23,39],[0,0],[9.867,5.55],[2.536,0.238],[0.949,0.017],[0,0],[0.264,0.602],[0.224,0.471],[0.137,0.273],[1.119,2.164],[1.214,1.747],[5.421,5.421],[0.248,0.125],[0.075,0.037],[0.045,0.022],[0,0],[0,0],[8,12],[0,0],[12.5,5],[0,0],[30,-23],[0,0],[20,-9.5],[0,0],[1.684,-2.887],[0.783,-3.067],[0.263,-3.309],[-0.078,-1.551],[0,0],[22.5,-41.5],[0,0],[4.007,-7.746],[-9,-34],[0,0],[-6.242,-10.429]],\"v\":[[164.5,-192],[111.719,-188.32],[97.5,-180.5],[85.228,-184.887],[70.084,-186.417],[43.5,-177],[18,-143.5],[13.904,-153.572],[4.567,-165.607],[-15.5,-178.5],[-25.791,-182.386],[-35.892,-185.402],[-47.344,-187.652],[-57.41,-188.155],[-59,-188],[-60.761,-188.751],[-69.176,-191.415],[-135,-185.5],[-177.205,-156.264],[-180.194,-149.959],[-180.5,-148.5],[-230.5,-120],[-236,-60.5],[-227,9],[-170.5,50],[-138,87],[-109.8,95.157],[-103.974,95.496],[-102.5,95.5],[-101.838,97.075],[-100.828,99.282],[-100.095,100.783],[-99.667,101.622],[-95.49,108.635],[-91.5,113.5],[-73.449,125.529],[-72.842,125.833],[-72.654,125.925],[-72.548,125.977],[-72.5,126],[-70,157],[-44,176.5],[-28.5,196.5],[-1.5,193.5],[47.5,178.5],[72,132.5],[116.5,127],[132.5,101],[170.5,81],[174.143,71.85],[175.569,63.021],[175.689,54.963],[175.5,52.5],[245.5,6],[237.5,-64.5],[244.608,-73.882],[247,-113],[208.5,-144.5],[200.629,-164.834]],\"c\":true}],\"e\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}],\"e\":[{\"i\":[[8.864,2.813],[7.079,-1.354],[0,0],[13.094,-1.21],[-0.018,-0.843],[5.661,-2.668],[0,0],[17.71,1.266],[12.336,3.848],[0.25,0.75],[9.83,8.017],[0.562,0.657],[25.725,4.726],[9.831,-6.216],[0,0],[-3.032,3.853],[0.747,8.445],[15.471,-6.395],[-7.536,-6.601],[-7.961,-1.468],[0,0],[21.655,-23.881],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.08,3.361],[7.074,6.982],[0,0],[-14.244,-1.531],[-5.859,-7.626],[1.287,-2.776],[3.373,-0.392],[0.886,-6.879],[-1.961,-1.267],[-3.784,12.826],[-2.09,4.283],[-1.499,-0.451],[-0.354,-4.451],[0,0],[-12.5,-20.75],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-6.505,6.505],[0,0],[-20.995,16.055],[-8.207,7.28],[-0.548,0.003],[-6.236,1.925],[0,0],[-27.024,42.787],[0,0],[-9.085,17.825],[3.883,14.669],[0,0],[8.143,11.01]],\"o\":[[-13.759,-4.366],[-19.726,3.772],[0,0],[-8.945,0.827],[-0.018,-0.593],[-21.75,10.25],[0,0],[0.019,-0.088],[-13.81,-4.307],[0,-0.25],[-11.414,-9.308],[-0.688,-0.593],[-15.588,-2.864],[-11.425,7.224],[0,0],[3.287,-4.177],[-0.537,-6.071],[-17.147,7.088],[5.403,4.732],[6.094,1.124],[0,0],[-26.75,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[1.698,-2.743],[-5.053,-4.987],[0,0],[12.035,1.294],[4.522,5.885],[-0.856,1.846],[-10.422,1.211],[-1.075,8.345],[12,7.75],[0.432,-1.463],[1.255,-2.571],[3.219,0.968],[0.518,6.518],[0,0],[8.593,14.264],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[6.5,-6.5],[0,0],[6.447,-4.93],[7.537,-6.685],[1.977,-0.948],[9.61,-2.967],[0,0],[12,-19],[0,0],[6.894,-13.526],[-9,-34],[0,0],[-4.511,-6.1]],\"v\":[[166,-182],[142.226,-178.772],[118.5,-165.75],[104.445,-167.327],[90.018,-161.407],[69.5,-161.5],[61.75,-141],[32.731,-125.412],[11.06,-137.943],[-10.25,-140],[-20.586,-156.942],[-42.062,-164.657],[-72.225,-184.726],[-105.941,-167.407],[-135.75,-154],[-143.677,-157.193],[-127.997,-171.695],[-157.25,-175],[-173.153,-153.482],[-148.789,-155.532],[-149,-149.25],[-215.5,-124.5],[-231.25,-78.25],[-217.75,-1.25],[-155,30],[-140.25,62],[-112.259,65.765],[-115.824,47.268],[-128.5,39],[-102.285,44.956],[-77.909,55.814],[-69.342,69.609],[-76.446,71.481],[-95.214,83.819],[-87.5,98.25],[-64.716,90.174],[-64.128,77.554],[-56.682,75.116],[-49.105,84.318],[-52.5,97.5],[-46,142.75],[-29,152.25],[-20.5,164.5],[-4,161.25],[18.5,154.5],[42,124],[58,116.25],[59.5,98.75],[93,83.75],[108.207,71.72],[123.048,55.997],[136.065,57.709],[151.75,42.25],[204,5.75],[209.5,-42.75],[227.03,-63.49],[244.75,-108.75],[200.25,-150],[181.607,-169.76]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[-28,-15.25],[0,0],[-15.75,9.5],[0,0],[-10.5,-4.25],[0,0],[-0.25,-4.75],[0,0],[6,0],[0,0],[10.25,-9.5],[-1.75,-8],[0,0],[10.25,-0.75],[0,0],[2,10.5],[0,0],[17.75,4.5],[5,-3.5],[0,0],[2.5,4],[0,0],[-0.75,7.5],[-4.25,8.75]],\"o\":[[0,0],[28,15.25],[0,0],[15.75,-9.5],[0,0],[10.5,4.25],[0,0],[0.25,4.75],[0,0],[-6,0],[0,0],[-10.25,9.5],[1.75,8],[0,0],[-10.25,0.75],[0,0],[-2,-10.5],[0,0],[-17.75,-4.5],[-5,3.5],[0,0],[-2.5,-4],[0,0],[0.75,-7.5],[4.25,-8.75]],\"v\":[[-50.5,-75.25],[-29.75,-39.75],[19.25,-34.75],[50.75,-41.75],[69,-59.75],[91,-37.75],[107,-23.75],[99.75,-11.75],[99.75,1.25],[84.75,-4.75],[76,-0.25],[55.25,0.5],[42,23],[45,39.5],[19,35.25],[-10.25,39],[-9,14.75],[-18.25,-1.5],[-32.25,-27.5],[-63.25,-21.75],[-71.25,-6.25],[-73.5,-14.75],[-83,-20.25],[-66.5,-33.75],[-62.25,-65.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.074,0.04],[0,0],[0.041,-0.025],[0,0],[0.028,0.011],[0,0],[0.001,0.012],[0,0],[-0.016,0],[0,0],[-0.027,0.025],[0.005,0.021],[0,0],[-0.027,0.002],[0,0],[-0.005,-0.028],[0,0],[-0.047,-0.012],[-0.013,0.009],[0,0],[-0.007,-0.011],[0,0],[0.002,-0.02],[0.011,-0.023]],\"o\":[[0,0],[-0.074,-0.04],[0,0],[-0.041,0.025],[0,0],[-0.028,-0.011],[0,0],[-0.001,-0.012],[0,0],[0.016,0],[0,0],[0.027,-0.025],[-0.005,-0.021],[0,0],[0.027,-0.002],[0,0],[0.005,0.028],[0,0],[0.047,0.012],[0.013,-0.009],[0,0],[0.007,0.011],[0,0],[-0.002,0.02],[-0.011,0.023]],\"v\":[[12.164,-17.724],[12.11,-17.817],[11.981,-17.831],[11.898,-17.812],[11.85,-17.765],[11.792,-17.823],[11.75,-17.86],[11.769,-17.891],[11.769,-17.925],[11.809,-17.91],[11.832,-17.921],[11.886,-17.923],[11.921,-17.983],[11.913,-18.026],[11.982,-18.015],[12.059,-18.025],[12.055,-17.961],[12.08,-17.918],[12.116,-17.85],[12.198,-17.865],[12.219,-17.906],[12.225,-17.883],[12.25,-17.869],[12.207,-17.833],[12.195,-17.75]],\"c\":true}]},{\"t\":15}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.125,0.057],[0,0],[0.038,-0.016],[0,0],[0.063,-0.035],[0,0],[0.061,0.023],[0,0.05],[-0.003,0.025],[0,0],[-0.031,0.004],[0,0],[-0.05,0.025],[-0.01,0.057],[0,0],[0.019,0.048],[0,0],[-0.02,0.051],[0,0],[-0.023,-0.034],[0,0],[0.009,-0.101],[-0.038,0.016],[0,0],[-0.02,-0.019],[0,0],[-0.023,-0.047],[0,0],[-0.128,0.007],[0.003,0.025],[0,0],[-0.034,-0.034],[0,0],[0.023,-0.09],[0.028,-0.051]],\"o\":[[0,0],[-0.125,-0.057],[0,0],[-0.038,0.016],[0,0],[-0.063,0.035],[0,0],[-0.061,-0.023],[0,-0.05],[0.003,-0.025],[0,0],[0.031,-0.004],[0,0],[0.05,-0.025],[0.01,-0.057],[0,0],[-0.019,-0.048],[0,0],[0.02,-0.051],[0,0],[0.023,0.034],[0,0],[-0.009,0.101],[0.038,-0.016],[0,0],[0.02,0.019],[0,0],[0.023,0.047],[0,0],[0.128,-0.007],[-0.003,-0.025],[0,0],[0.034,0.034],[0,0],[-0.023,0.09],[-0.028,0.051]],\"v\":[[10.723,4.496],[10.612,4.271],[10.433,4.229],[10.313,4.238],[10.272,4.29],[10.125,4.315],[10.008,4.395],[9.924,4.296],[9.791,4.147],[9.848,4.052],[9.857,4.001],[9.965,4.025],[10.049,3.991],[10.096,4.034],[10.198,3.937],[10.14,3.873],[10.166,3.78],[10.11,3.706],[10.186,3.612],[10.239,3.5],[10.262,3.579],[10.317,3.614],[10.183,3.708],[10.38,3.802],[10.459,3.77],[10.479,3.809],[10.529,3.832],[10.527,3.971],[10.573,4.06],[10.699,4.128],[10.841,4.044],[10.832,4],[10.877,4.079],[10.959,4.13],[10.826,4.268],[10.787,4.449]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}],\"e\":[{\"i\":[[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,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]],\"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],[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]],\"v\":[[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4]],\"c\":true}]},{\"t\":16}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.022,0.041],[0,0],[-0.044,0.022],[0,0],[0.015,-0.081]],\"o\":[[0,0],[-0.022,-0.041],[0,0],[0.044,-0.022],[0,0],[-0.015,0.081]],\"v\":[[-66.087,51.996],[-66.157,51.959],[-66.25,51.904],[-66.168,51.885],[-66.083,51.8],[-66.106,51.881]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.004,-0.043],[0,0],[0.045,0.015],[0,0],[-0.034,0.023]],\"o\":[[0,0],[-0.004,0.052],[0,0],[-0.053,-0.018],[0,0],[0.061,-0.041]],\"v\":[[-54.598,33.581],[-54.607,33.711],[-54.571,33.906],[-54.697,33.794],[-54.742,33.729],[-54.698,33.67]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-0.005,-0.001],[-0.001,0.001],[0,0],[0.001,-0.002],[-0.023,-0.015],[0,0],[-0.005,0.008],[0,0.002],[0,0],[-0.003,0],[-0.007,0.006],[-0.004,0.003],[0,0],[-0.013,-0.005],[0,0],[-0.004,-0.006],[0,0],[0.005,-0.009],[0,-0.003],[0,0],[0.001,0],[0.004,0],[0.009,-0.004],[0,0.006],[0.002,-0.004],[0.005,-0.01],[-0.003,-0.004],[0,0],[0.002,-0.006],[0,0],[0.004,-0.006],[0.001,-0.002],[0,0],[0,-0.001],[0,-0.001],[0,0],[0,0],[0,0],[0,0],[0.002,0.006],[0,0],[0.001,0.01],[0.007,-0.001],[0,0],[0.005,0.001],[0.002,0],[0,0],[0.011,0.017],[0.013,0],[0,0],[0.001,-0.006],[0,0],[0,0],[0.007,0.006],[0,0],[0.003,0.005],[0,0],[-0.003,0.011],[0,0],[-0.003,0.009]],\"o\":[[0,0],[0.004,0.001],[0,0],[0,0],[-0.003,0.008],[0.03,0.019],[0,0],[0.004,-0.005],[0,-0.001],[0,0],[0.008,-0.001],[0.005,-0.004],[0.003,-0.003],[0,0],[0.013,0.005],[0,0],[0.004,0.006],[0,0],[-0.002,0.004],[0,0.003],[0,0],[-0.002,0],[-0.008,-0.001],[-0.016,0.006],[0,-0.006],[-0.002,0.004],[-0.005,0.01],[0.003,0.004],[0,0],[-0.002,0.006],[0,0],[-0.001,0.002],[0,0],[0,0.001],[-0.001,0.001],[0,0],[0,0],[0,0],[0,0],[0.001,-0.004],[-0.003,-0.008],[0,0],[-0.001,-0.01],[-0.007,0.001],[0,0],[-0.004,-0.001],[-0.001,0],[0,0],[-0.011,-0.017],[-0.013,0],[0,0],[-0.001,0.006],[0,0],[-0.002,-0.003],[-0.008,-0.007],[0,0],[-0.003,-0.005],[0,0],[0.003,-0.011],[0,0],[0.003,-0.009]],\"v\":[[9.302,5.518],[9.307,5.522],[9.313,5.52],[9.314,5.52],[9.312,5.523],[9.33,5.564],[9.367,5.573],[9.388,5.572],[9.393,5.561],[9.393,5.559],[9.397,5.559],[9.43,5.551],[9.444,5.539],[9.449,5.534],[9.467,5.558],[9.489,5.572],[9.493,5.589],[9.5,5.591],[9.487,5.608],[9.484,5.618],[9.484,5.623],[9.483,5.623],[9.475,5.622],[9.446,5.625],[9.436,5.626],[9.418,5.64],[9.425,5.65],[9.425,5.67],[9.433,5.678],[9.419,5.695],[9.417,5.709],[9.408,5.717],[9.404,5.723],[9.404,5.725],[9.402,5.727],[9.401,5.73],[9.401,5.731],[9.4,5.732],[9.4,5.731],[9.401,5.73],[9.401,5.71],[9.393,5.695],[9.404,5.677],[9.38,5.667],[9.365,5.671],[9.358,5.664],[9.345,5.663],[9.345,5.663],[9.338,5.62],[9.305,5.602],[9.292,5.614],[9.285,5.622],[9.291,5.642],[9.291,5.641],[9.277,5.621],[9.263,5.613],[9.258,5.599],[9.25,5.588],[9.277,5.575],[9.283,5.553],[9.294,5.531]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.5,-3.25],[-8.083,-4.093],[0,0],[5.225,-1.81],[-10.076,-17.051],[0,0],[-4.25,6.5],[2.192,7.761],[0,0],[-5.285,-1.77],[-9.617,3.023],[-7.065,13.364],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[-2.345,-3.979],[0,0],[5.1,-5.315],[-0.891,1.119],[11,-1],[5.076,-2.343],[0.981,-0.196],[0.317,-9.834],[-6,-5.75],[0,0],[3.117,-4.572],[0,0],[3.315,-5.461],[0.004,-0.142],[3.538,3.662],[6.177,1.037],[7.159,1.756],[6.076,4.663],[0,0],[0.268,2.167],[-1.669,-1.529],[-12.757,3.744],[0,0],[0.5,8.5],[6,4.75],[0,0],[12.25,3.25],[4.665,8.641],[0,0],[1.804,17.317],[11,0],[0,0],[-1.078,-4.792],[0,0],[7.696,-4.137],[11.048,13.67],[0,0],[6.716,15.802],[0,0],[-8.75,8.5],[0,0],[-1.848,8.102]],\"o\":[[0,0],[2.721,1.179],[6.999,3.545],[0,0],[-9.722,3.368],[6.5,11],[0,0],[2.56,-3.915],[-1.447,-5.123],[0,0],[7.507,2.515],[7.991,-2.512],[7.121,-13.47],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.767,3.043],[3.627,6.153],[0,0],[-7.721,8.046],[4.699,-5.902],[-14.287,1.299],[-3.25,1.5],[0.5,0.25],[-0.25,7.75],[3.254,3.118],[0,0],[-7.5,11],[0,0],[-2.732,4.499],[0.001,0.02],[-4.471,-4.629],[-6.724,-1.129],[-4.847,-1.189],[-10.206,-7.834],[0,0],[-0.293,-2.368],[7.64,6.999],[6.682,-1.961],[0,0],[-0.5,-8.5],[-4.614,-3.652],[0,0],[-9.452,-2.508],[-1.955,-3.621],[0,0],[-1.25,-12],[-11,0],[0,0],[2.25,10],[0,0],[-9.622,5.171],[-5.56,-6.88],[0,0],[-8.5,-20],[0,0],[7.177,-6.972],[0,0],[3.25,-14.25]],\"v\":[[-55.25,-99],[-38,-102.5],[-26.499,-92.295],[-11,-85.75],[-16.181,-80.022],[-27.25,-57.5],[-9,-52.75],[9.75,-54],[-3.88,-73.713],[3.25,-80.5],[12.303,-78.912],[49.75,-76],[79.565,-93.114],[107.75,-102.75],[96.5,-67],[114.75,-52],[127.75,-39.5],[127.25,-24.75],[114,-12],[109.472,3.722],[125.5,11],[112.338,18.324],[99.729,37.643],[91,9.5],[73.5,13.5],[70.25,20.75],[65.5,31.5],[72.75,46.5],[94,43],[67.25,65.25],[56,93.25],[44.25,104.75],[39.746,121.392],[31.212,126.088],[14.486,118.584],[-9.366,124.723],[-25.155,109.278],[-43.5,97.5],[-45.859,91.202],[-40.39,89.001],[-14.5,94],[-3.25,84.5],[1.25,73.75],[-7.5,59],[-18.75,57.25],[-30.75,52.25],[-41.665,32.609],[-37.25,20.25],[-30.25,5.25],[-46.25,-5.25],[-58.5,-0.75],[-59.25,8],[-49.313,14.25],[-53.696,28.137],[-92.25,33.5],[-107.75,19],[-104.5,-19.25],[-112,-57.25],[-88.75,-44.25],[-72,-69.5],[-65.5,-81.75]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.04,-0.009],[-0.019,-0.009],[0.026,-0.016],[0.026,-0.028],[0,0],[0.019,0.068]],\"o\":[[0.04,0.009],[0.019,0.009],[-0.026,0.016],[-0.026,0.028],[0,0],[-0.016,-0.058]],\"v\":[[-51.449,39.759],[-51.357,39.815],[-51.332,39.874],[-51.435,39.914],[-51.509,40],[-51.533,39.818]],\"c\":true}],\"e\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}],\"e\":[{\"i\":[[-5.84,0.724],[-2.429,-1.796],[2.794,-3.365],[2.214,-5.016],[0,0],[8.09,15.052]],\"o\":[[5.84,-0.724],[5.929,4.383],[-2.794,3.365],[-2.214,5.016],[0,0],[-4.108,-7.644]],\"v\":[[-62.831,35.704],[-44.679,38.617],[-41.313,54.729],[-46.827,64.288],[-57.43,67.573],[-72.59,55.198]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.104,-0.071],[0.086,0.038],[0.145,0.005],[0,0],[0.014,0.093],[0,0],[-0.123,0.023],[0,0]],\"o\":[[0.12,0.081],[-0.035,-0.016],[-0.145,-0.005],[0,0],[-0.014,-0.093],[0,0],[0.123,-0.023],[0,0]],\"v\":[[-82.663,-101.709],[-82.586,-101.615],[-82.846,-101.602],[-83.042,-101.565],[-83.224,-101.565],[-83.137,-101.671],[-82.993,-101.705],[-82.858,-101.698]],\"c\":true}],\"e\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}],\"e\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}],\"e\":[{\"i\":[[-8.912,-4.564],[3.5,-16.5],[11.5,-1],[0,0],[2,7.25],[0,0],[-9.5,3],[0,0]],\"o\":[[10.25,5.25],[-3.5,16.5],[-11.5,1],[0,0],[-2,-7.25],[0,0],[9.5,-3],[0,0]],\"v\":[[-83.5,-123],[-54.25,-109.75],[-90,-99.5],[-111.75,-81],[-115,-103.5],[-125.75,-114.5],[-109.25,-119],[-99,-126]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[5.5,0],[-3.75,-7.75],[-5,5.25],[3.5,2]],\"o\":[[-5.5,0],[3.75,7.75],[5,-5.25],[-3.5,-2]],\"v\":[[64.25,-40.75],[59,-26.75],[76.25,-25.75],[74.25,-37.75]],\"c\":true}],\"e\":[{\"i\":[[-0.106,0],[0.072,0.149],[0.096,-0.101],[-0.067,-0.038]],\"o\":[[0.106,0],[-0.072,-0.149],[-0.096,0.101],[0.067,0.038]],\"v\":[[72.077,-31.166],[72.178,-31.435],[71.846,-31.454],[71.885,-31.224]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":13,\"s\":[0,0],\"h\":1},{\"t\":14,\"s\":[100,100],\"h\":1},{\"t\":21,\"s\":[0,0],\"h\":1}],\"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 8\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-40.51,7.147],[0,0],[-17.338,-13.577],[0,0],[-8.296,0],[0,0],[-26.663,15.973],[0,0],[-33.95,-10.778],[0,0],[-21.615,-37.512],[0,0],[8.98,-29.643],[0,0],[16.078,-18.847],[0,0],[19.91,-14.379],[0,0],[9.955,-9.125],[0,0],[16.722,-12.243],[0,0],[18.514,-5.056],[0,0],[9.125,-0.553],[0,0],[18.949,11.815],[0,0],[16.315,12.72],[0,0],[23.953,16.773],[0,0],[11.973,13.619],[0,0],[6.913,32.077],[0,0],[-4.701,15.209],[0,0],[-10.231,17.145],[0,0],[-9.402,7.743],[0,0]],\"o\":[[43.349,-7.648],[0,0],[17.031,13.336],[0,0],[3.739,0],[0,0],[17.54,-10.508],[0,0],[33.43,10.613],[0,0],[16.117,27.97],[0,0],[-7.619,25.151],[0,0],[-16.113,18.888],[0,0],[-19.91,14.379],[0,0],[-9.955,9.125],[0,0],[-16.624,12.172],[0,0],[-14.931,4.078],[0,0],[-9.125,0.553],[0,0],[-22.801,-14.217],[0,0],[-16.315,-12.72],[0,0],[-19.543,-13.685],[0,0],[-14.781,-16.813],[0,0],[-6.913,-32.077],[0,0],[4.701,-15.209],[0,0],[10.231,-17.145],[0,0],[9.402,-7.743],[0,0]],\"v\":[[-122.349,-200.852],[-67.036,-197.802],[-29.531,-189.336],[-8.428,-159.127],[5.686,-161.605],[12.864,-156.627],[42.96,-187.992],[81.916,-196.269],[137.57,-196.113],[183.871,-164.877],[232.883,-120.97],[241.361,-65.366],[240.52,-14.357],[219.652,17.144],[204.113,62.612],[179.151,78.022],[158.805,108.917],[131.471,116.361],[108.784,144.6],[82.14,158.301],[67.624,177.828],[43.385,190.688],[24.986,203.556],[3.47,204.704],[-15.345,210.947],[-32.448,201.14],[-56.949,189.685],[-78.783,151.211],[-100.318,142.161],[-117.198,116.933],[-155.953,98.227],[-179.067,65.84],[-206.973,51.381],[-217.527,16.527],[-241.967,-19.72],[-239.542,-62.358],[-241.872,-94.094],[-219.588,-110.856],[-217.027,-145.422],[-189.511,-163.714],[-181.673,-176.147],[-165.9,-178.912]],\"c\":true}],\"e\":[{\"i\":[[-41.027,10.852],[0,0],[-32.19,-17.46],[0,0],[-0.18,0.259],[0,0],[-27.898,13.394],[0,0],[-45.894,-13.697],[0,0],[-15.016,-36.577],[0,0],[5.71,-33.936],[0,0],[21.4,-13.403],[0,0],[17.976,-16.121],[0,0],[10.092,-8.239],[0,0],[19.309,-16.744],[0,0],[19.25,-9.223],[0,0],[12.239,3.847],[0,0],[15.375,17.378],[0,0],[11.519,13.671],[0,0],[24.516,15.038],[0,0],[12.163,12.071],[0,0],[6.597,28.03],[0,0],[-1.353,14.044],[0,0],[-16.709,12.856],[0,0],[-8.214,8.547],[0,0]],\"o\":[[44.248,-11.704],[0,0],[18.544,10.058],[0,0],[-0.18,0.259],[0,0],[18.352,-8.811],[0,0],[38.632,11.53],[0,0],[13.202,32.158],[0,0],[-3.833,22.781],[0,0],[-19.873,12.446],[0,0],[-19.185,17.206],[0,0],[-19.586,15.988],[0,0],[-11.367,9.857],[0,0],[-14.319,6.86],[0,0],[-20.345,-6.395],[0,0],[-17.652,-19.952],[0,0],[-13.005,-15.434],[0,0],[-20.002,-12.269],[0,0],[-15.015,-14.901],[0,0],[-6.597,-28.03],[0,0],[1.428,-14.823],[0,0],[14.517,-11.169],[0,0],[11.131,-11.582],[0,0]],\"v\":[[-115.248,-190.796],[-59.008,-190.107],[-10.81,-172.04],[19.517,-144.869],[19.18,-146.759],[19.528,-146.795],[54.253,-183.013],[96.25,-182.982],[162.394,-192.803],[206.803,-147.766],[248.798,-114.658],[238.601,-66.134],[250.833,-17.781],[241.164,16.728],[212.1,46.403],[176.142,53.42],[165.685,84.794],[131.081,97.874],[119.086,124.512],[72.746,132.43],[64.367,162.143],[42.534,175.875],[17.75,190.723],[-3.557,191.818],[-24.655,195.895],[-44.198,175.545],[-65.375,158.622],[-72.314,125.748],[-87.019,114.329],[-103.831,93.1],[-142.713,85.645],[-170.687,49.612],[-206.339,36.512],[-226.657,9.999],[-241.335,-25.987],[-238.074,-63.029],[-240.428,-90.677],[-234.051,-113.839],[-215.291,-138.856],[-184.468,-150.252],[-177.631,-164.918],[-158.245,-175.028]],\"c\":true}]},{\"t\":14}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[3.25,0],[0,0],[-0.5,-7],[0,0],[-5.5,-1.25],[0,0],[-2.5,7.75],[0,0],[6,0],[0,0],[1.75,-2.75],[0.75,5.5]],\"o\":[[0,0],[-3.25,0],[0,0],[0.5,7],[0,0],[5.5,1.25],[0,0],[2.5,-7.75],[0,0],[-6,0],[0,0],[-1.75,2.75],[-0.75,-5.5]],\"v\":[[10.25,-12.5],[2.5,-9.25],[-3.25,-9],[0.25,6.25],[-1.5,20],[11.5,22.25],[20.75,27.75],[24.75,15],[41.75,-3],[30.75,-6.75],[20.75,-8.25],[21.5,1.25],[9,-1.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.108,0],[0,0],[0.017,0.197],[0,0],[0.183,0.035],[0,0],[0.083,-0.219],[0,0],[-0.2,0],[0,0],[-0.058,0.078],[-0.025,-0.155]],\"o\":[[0,0],[0.108,0],[0,0],[-0.017,-0.197],[0,0],[-0.183,-0.035],[0,0],[-0.083,0.219],[0,0],[0.2,0],[0,0],[0.058,-0.078],[0.025,0.155]],\"v\":[[19.55,8.193],[19.808,8.101],[20,8.094],[19.883,7.664],[19.942,7.276],[19.508,7.212],[19.2,7.057],[19.067,7.417],[18.5,7.925],[18.867,8.03],[19.2,8.073],[19.175,7.805],[19.592,7.882]],\"c\":true}]},{\"t\":10}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.064,0.03],[0.037,0.036],[0,0],[0.094,-0.005],[0,0],[0.034,-0.041],[0,0],[0.003,-0.023],[0,0],[-0.014,0],[0,0],[-0.057,0.03],[0,0],[-0.022,0.001],[0,0],[-0.007,-0.022]],\"o\":[[0.064,-0.03],[-0.037,-0.036],[0,0],[-0.094,0.005],[0,0],[-0.034,0.041],[0,0],[-0.003,0.023],[0,0],[0.014,0],[0,0],[0.057,-0.03],[0,0],[0.022,-0.001],[0,0],[0.007,0.022]],\"v\":[[15.686,3.128],[15.702,2.98],[15.653,2.842],[15.507,2.878],[15.377,2.865],[15.343,2.944],[15.269,2.975],[15.272,3.015],[15.25,3.072],[15.283,3.074],[15.344,3.115],[15.374,3.045],[15.463,3.052],[15.501,3.031],[15.54,3.041],[15.561,3.087]],\"c\":true}],\"e\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}],\"e\":[{\"i\":[[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]],\"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]],\"v\":[[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14]],\"c\":true}]},{\"t\":11}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.059,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.17],[0,0],[0.193,-0.003],[0,0],[0.094,-0.181],[0,0],[0.023,-0.059],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.059,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.17],[0,0],[-0.193,0.003],[0,0],[-0.094,0.182],[0,0],[-0.023,0.059],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.749],[28.945,-0.819],[29.012,-0.842],[28.992,-0.998],[29.214,-0.945],[29.346,-0.951],[29.434,-0.854],[29.583,-0.851],[29.697,-0.796],[29.706,-0.898],[29.75,-0.989],[29.607,-1.244],[29.601,-1.501],[29.279,-1.434],[28.971,-1.472],[28.901,-1.229],[28.582,-1.1],[28.523,-1.015],[28.5,-0.878],[28.775,-0.939]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.058,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.169],[0,0],[0.193,-0.003],[0,0],[0.093,-0.181],[0,0],[0.023,-0.058],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.058,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.169],[0,0],[-0.193,0.003],[0,0],[-0.093,0.181],[0,0],[-0.023,0.058],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.75],[28.946,-0.82],[29.013,-0.843],[28.992,-0.998],[29.214,-0.946],[29.345,-0.951],[29.433,-0.855],[29.582,-0.852],[29.696,-0.797],[29.704,-0.899],[29.748,-0.989],[29.605,-1.243],[29.599,-1.5],[29.278,-1.433],[28.972,-1.471],[28.902,-1.229],[28.584,-1.1],[28.525,-1.016],[28.502,-0.878],[28.776,-0.94]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.008,0.004],[0,0],[0.014,0.026],[-0.085,0.002],[0,0],[-0.017,0.014],[0,0],[-0.057,0.004],[0,0],[-0.053,-0.011],[0,0],[-0.001,0.014],[0,0],[0.033,0.05],[0,0],[0.033,0],[0,0],[0.115,-0.02],[0,0],[0,-0.02],[0,0],[-0.036,-0.017]],\"o\":[[0,0],[0.008,-0.004],[0,0],[-0.014,-0.026],[0.085,-0.002],[0,0],[0.017,-0.014],[0,0],[0.057,-0.004],[0,0],[0.053,0.011],[0,0],[0.001,-0.014],[0,0],[-0.033,-0.05],[0,0],[-0.033,0],[0,0],[-0.075,0.013],[0,0],[0,0.02],[0,0],[0.036,0.017]],\"v\":[[26.605,7.051],[26.632,7.031],[26.664,7.016],[26.567,6.967],[26.642,6.901],[26.718,6.986],[26.756,6.951],[26.803,6.935],[26.798,6.874],[26.844,6.92],[26.938,6.911],[27.037,6.945],[27.032,6.916],[27.044,6.884],[26.995,6.819],[26.969,6.667],[26.891,6.689],[26.783,6.666],[26.64,6.844],[26.501,6.807],[26.516,6.85],[26.501,6.926],[26.536,6.975]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.003,0.001],[0,0],[0.005,0.009],[-0.029,0.001],[0,0],[-0.006,0.005],[0,0],[-0.02,0.001],[0,0],[-0.018,-0.004],[0,0],[0,0.005],[0,0],[0.011,0.017],[0,0],[0.011,0],[0,0],[0.039,-0.007],[0,0],[0,-0.007],[0,0],[-0.012,-0.006]],\"o\":[[0,0],[0.003,-0.001],[0,0],[-0.005,-0.009],[0.029,-0.001],[0,0],[0.006,-0.005],[0,0],[0.02,-0.001],[0,0],[0.018,0.004],[0,0],[0,-0.005],[0,0],[-0.011,-0.017],[0,0],[-0.011,0],[0,0],[-0.026,0.005],[0,0],[0,0.007],[0,0],[0.012,0.006]],\"v\":[[21.286,5.989],[21.295,5.982],[21.306,5.977],[21.273,5.96],[21.299,5.937],[21.324,5.966],[21.338,5.955],[21.353,5.949],[21.352,5.928],[21.368,5.944],[21.4,5.941],[21.434,5.953],[21.432,5.943],[21.436,5.932],[21.419,5.91],[21.41,5.858],[21.384,5.865],[21.347,5.857],[21.298,5.918],[21.25,5.906],[21.255,5.92],[21.25,5.946],[21.262,5.963]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.005,0.026],[0,0],[0.02,0],[0,0],[-0.02,-0.025]],\"o\":[[0,0],[0.005,-0.026],[0,0],[-0.02,0],[0,0],[0.02,0.025]],\"v\":[[27.221,7.084],[27.23,7.031],[27.25,6.977],[27.211,6.996],[27.148,6.996],[27.199,7.032]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.002,0.009],[0,0],[0.007,0],[0,0],[-0.007,-0.009]],\"o\":[[0,0],[0.002,-0.009],[0,0],[-0.007,0],[0,0],[0.007,0.009]],\"v\":[[21.497,6],[21.499,5.982],[21.506,5.964],[21.493,5.97],[21.472,5.97],[21.489,5.982]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[-0.003,0.012],[0,0],[0.022,0],[0.014,0.004],[0,0],[0.003,0.01],[0,0],[0.024,0],[0,0],[0.014,-0.007],[0.002,-0.008],[0.01,0],[0,0],[0.005,0],[0,0],[0,-0.004],[0,0],[-0.008,-0.008],[0,0],[-0.02,0.013],[0,0],[-0.031,-0.014]],\"o\":[[0,0],[0.003,-0.012],[0,0],[-0.022,0],[-0.014,-0.004],[0,0],[-0.003,-0.01],[0,0],[-0.024,0],[0,0],[-0.005,0.003],[-0.002,0.008],[-0.01,0],[0,0],[-0.005,0],[0,0],[0,0.004],[0,0],[0.008,0.008],[0,0],[0.02,-0.013],[0,0],[0.031,0.014]],\"v\":[[25.23,5.825],[25.239,5.785],[25.25,5.763],[25.219,5.77],[25.184,5.766],[25.175,5.744],[25.16,5.728],[25.156,5.675],[25.117,5.683],[25.085,5.675],[25.081,5.703],[25.071,5.72],[25.057,5.731],[25.039,5.727],[25.029,5.729],[25,5.727],[25.005,5.742],[25.006,5.77],[25.026,5.786],[25.049,5.806],[25.084,5.775],[25.132,5.769],[25.183,5.773]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-8],[0,0],[-14.75,0],[-9.75,-2.5],[0,0],[-1.75,-6.75],[0,0],[-16.75,0],[0,0],[-9.75,4.75],[-1.5,5.75],[-7,0],[0,0],[-3.75,0],[0,0],[0,3],[0,0],[5.5,5.75],[0,0],[13.75,-9],[0,0],[21.25,9.5]],\"o\":[[0,0],[-2.25,8],[0,0],[14.75,0],[9.75,2.5],[0,0],[1.75,6.75],[0,0],[16.75,0],[0,0],[3.554,-1.731],[1.5,-5.75],[7,0],[0,0],[3.75,0],[0,0],[0,-3],[0,0],[-5.5,-5.75],[0,0],[-13.75,9],[0,0],[-21.25,-9.5]],\"v\":[[-56.25,-68.75],[-62.75,-41.25],[-70,-26.25],[-49,-31.25],[-24.5,-28.25],[-18.5,-13],[-8.5,-2.25],[-5.75,34.25],[21,28.75],[42.75,34],[45.5,14.75],[52.5,3.5],[62.5,-4.25],[74.25,-1.75],[81.5,-2.75],[101.25,-1.5],[98,-11.5],[97,-31],[83.5,-42],[68,-55.5],[44,-34.5],[10.5,-30.25],[-24.25,-33]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0.047,-0.026],[-0.06,-0.047],[0.011,0.108]],\"o\":[[-0.047,0.026],[0.06,0.047],[-0.011,-0.108]],\"v\":[[55.32,-24.341],[55.305,-24.172],[55.495,-24.267]],\"c\":true}],\"e\":[{\"i\":[[5.5,-3],[-7,-5.5],[1.25,12.5]],\"o\":[[-5.5,3],[7,5.5],[-1.25,-12.5]],\"v\":[[61,-42.5],[59.25,-23],[81.25,-34]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[-0.106,0.009],[0.124,0.008]],\"o\":[[0.106,-0.009],[-0.066,-0.004]],\"v\":[[39.106,-21.324],[39.124,-21.43]],\"c\":true}],\"e\":[{\"i\":[[6,-0.5],[-7.002,-0.467]],\"o\":[[-6,0.5],[3.75,0.25]],\"v\":[[33.75,-23.75],[32.75,-17.75]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.173,-0.02],[0.061,0.133],[0.041,-0.122]],\"o\":[[0.173,0.02],[-0.061,-0.133],[-0.041,0.122]],\"v\":[[15.411,-2.936],[15.564,-3.202],[15.166,-3.171]],\"c\":true}],\"e\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}],\"e\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}],\"e\":[{\"i\":[[0.726,0.085],[-0.256,-0.555],[-0.171,0.512]],\"o\":[[-0.726,-0.085],[0.256,0.555],[0.171,-0.512]],\"v\":[[15.476,0.335],[14.835,1.445],[16.5,1.317]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":8,\"s\":[0,0],\"h\":1},{\"t\":9,\"s\":[100,100],\"h\":1},{\"t\":14,\"s\":[0,0],\"h\":1}],\"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 7\",\"np\":11,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.527,-15.381],[0,0],[-16.592,-17.145],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-13.448,7.664],[0,0],[-17.698,10.784],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-3.871,25.993],[0,0],[8.117,32.855],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[14.031,8.836],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[9.314,9.861],[0,0],[16.592,17.145],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[15.014,-8.556],[0,0],[17.698,-10.784],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[3.871,-25.993],[0,0],[-10.383,-42.03],[0,0],[-33.95,-10.778],[0,0],[-26.662,15.973],[0,0],[-8.296,0],[0,0],[-18.634,-11.735],[0,0]],\"v\":[[-121.849,-206.352],[-161.4,-175.412],[-182.173,-172.147],[-193.511,-153.214],[-214.027,-135.922],[-218.088,-102.356],[-229.872,-81.594],[-235.542,-46.858],[-241.467,0.28],[-222.027,33.027],[-205.473,58.881],[-178.067,73.84],[-160.953,112.227],[-121.198,125.433],[-113.318,152.661],[-89.783,163.211],[-64.949,195.685],[-25.948,210.14],[-11.345,221.447],[9.97,215.704],[36.986,213.556],[40.385,184.688],[78.624,178.828],[104.64,145.801],[121.784,144.1],[126.971,127.861],[160.805,114.917],[180.651,77.022],[213.113,53.612],[225.152,8.645],[241.52,-22.857],[229.361,-60.866],[232.883,-107.97],[180.871,-152.377],[142.07,-197.613],[82.916,-185.269],[39.46,-183.492],[17.864,-151.627],[4.686,-158.605],[-5.428,-154.127],[-28.031,-182.836],[-68.036,-192.302]],\"c\":true}],\"e\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.781,-16.813],[0,0],[-19.543,-13.685],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-14.931,4.078],[0,0],[-16.624,12.172],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-7.619,25.151],[0,0],[16.117,27.97],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[17.031,13.336],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[11.973,13.619],[0,0],[23.953,16.773],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[18.514,-5.056],[0,0],[16.722,-12.243],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[8.98,-29.643],[0,0],[-21.615,-37.512],[0,0],[-33.95,-10.778],[0,0],[-26.663,15.973],[0,0],[-8.296,0],[0,0],[-17.338,-13.577],[0,0]],\"v\":[[-122.349,-200.852],[-165.9,-178.912],[-181.673,-176.147],[-189.511,-163.714],[-217.027,-145.422],[-219.588,-110.856],[-241.872,-94.094],[-239.542,-62.358],[-241.967,-19.72],[-217.527,16.527],[-206.973,51.381],[-179.067,65.84],[-155.953,98.227],[-117.198,116.933],[-100.318,142.161],[-78.783,151.211],[-56.949,189.685],[-32.448,201.14],[-15.345,210.947],[3.47,204.704],[24.986,203.556],[43.385,190.688],[67.624,177.828],[82.14,158.301],[108.784,144.6],[131.471,116.361],[158.805,108.917],[179.151,78.022],[204.113,62.612],[219.652,17.144],[240.52,-14.357],[241.361,-65.366],[232.883,-120.97],[183.871,-164.877],[137.57,-196.113],[81.916,-196.269],[42.96,-187.992],[12.864,-156.627],[5.686,-161.605],[-8.428,-159.127],[-29.531,-189.336],[-67.036,-197.802]],\"c\":true}]},{\"t\":9}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":4,\"s\":[0,0],\"h\":1},{\"t\":5,\"s\":[100,100],\"h\":1},{\"t\":9,\"s\":[0,0],\"h\":1}],\"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 6\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[37,-3.75],[0,0],[8.5,-7],[0,0],[9.25,-15.5],[0,0],[4.25,-13.75],[0,0],[-6.25,-29],[0,0],[-8.75,-18.25],[0,0],[-15,-15.5],[0,0],[-14.75,-11.5],[0,0],[-22.25,-9.75],[0,0],[-8.25,0.5],[0,0],[-13.25,4.5],[0,0],[-16,9.75],[0,0],[-9,8.25],[0,0],[-18,13],[0,0],[-12.25,18.75],[0,0],[-3.5,23.5],[0,0],[11.75,28.25],[0,0],[26,19],[0,0],[35,-6.25],[0,0],[7.5,0],[0,0],[8.75,8],[0,0]],\"o\":[[-37,3.75],[0,0],[-8.5,7],[0,0],[-9.25,15.5],[0,0],[-4.25,13.75],[0,0],[6.25,29],[0,0],[8.75,18.25],[0,0],[15,15.5],[0,0],[14.75,11.5],[0,0],[22.25,9.75],[0,0],[8.25,-0.5],[0,0],[13.25,-4.5],[0,0],[16,-9.75],[0,0],[9,-8.25],[0,0],[18,-13],[0,0],[12.25,-18.75],[0,0],[3.5,-23.5],[0,0],[-11.75,-28.25],[0,0],[-26,-19],[0,0],[-35,6.25],[0,0],[-7.5,0],[0,0],[-8.75,-8],[0,0]],\"v\":[[-99.5,-183.25],[-144.75,-160.25],[-156.75,-157.75],[-167,-144.25],[-186,-125],[-196,-93.75],[-205.75,-79.5],[-205,-49],[-209,-10],[-186,18.25],[-185.5,47.5],[-155.75,77.75],[-145.25,100.25],[-107.5,125.75],[-94.5,146.75],[-68.25,159],[-46.25,175.25],[-13.25,184.25],[-0.5,189.5],[14.25,182.5],[33.25,178.75],[53.5,163.5],[72.25,157.75],[91.25,141],[106.75,136.75],[125,118],[147,106.75],[166.75,74.75],[185.25,56.75],[199.75,17],[215,-16],[213.5,-58.5],[209,-104.25],[178.25,-134],[149.5,-164.5],[91.5,-177.75],[49.5,-177.5],[13.25,-150.5],[4.5,-155],[-6,-150.5],[-18.75,-164.25],[-40,-171]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":3,\"s\":[0,0],\"h\":1},{\"t\":4,\"s\":[100,100],\"h\":1},{\"t\":5,\"s\":[0,0],\"h\":1}],\"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 5\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[28.5,3],[0,0],[22.75,-14.5],[0,0],[6.75,-23.75],[0,0],[-1.75,-23.5],[0,0],[-7.25,-11.75],[0,0],[-10.5,-8.25],[0,0],[-9.75,-8.75],[0,0],[-14,-6.5],[0,0],[-5.5,-2.75],[0,0],[-14.75,4.5],[0,0],[-14.5,6],[0,0],[-20,14.25],[0,0],[-6.5,15],[0,0],[-1.75,21],[0,0],[9.5,20.75],[0,0],[6.75,5.5],[0,0],[14.75,3.75],[0,0],[24.5,-4.5],[0,0],[4.5,1],[0,0]],\"o\":[[-28.5,-3],[0,0],[-22.75,14.5],[0,0],[-6.75,23.75],[0,0],[1.75,23.5],[0,0],[7.25,11.75],[0,0],[10.5,8.25],[0,0],[9.75,8.75],[0,0],[14,6.5],[0,0],[5.5,2.75],[0,0],[14.75,-4.5],[0,0],[14.5,-6],[0,0],[20,-14.25],[0,0],[6.5,-15],[0,0],[1.75,-21],[0,0],[-9.5,-20.75],[0,0],[-6.75,-5.5],[0,0],[-14.75,-3.75],[0,0],[-24.5,4.5],[0,0],[-4.5,-1],[0,0]],\"v\":[[-42.25,-141.75],[-83.5,-133],[-116.75,-124.25],[-131.75,-102],[-157,-69.5],[-155.75,-47.25],[-164,-6.75],[-151.25,18.75],[-146,44.75],[-134.75,55.5],[-123.25,79.5],[-110,85.5],[-98.5,104.25],[-79.75,113],[-61.75,129.75],[-42.75,132.5],[-32,141],[-13.5,141.75],[8,140.25],[26.75,131.25],[56.75,125.75],[73,110.75],[101,97.5],[129,67.25],[146,41.5],[153.25,14],[165.25,-17.25],[160.75,-52.5],[154.25,-91],[134.5,-109.75],[126.75,-123.75],[115.25,-125.25],[93,-140],[68,-140.5],[30.5,-141.5],[12,-124],[2.5,-126.5],[-8.75,-123.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":2,\"s\":[0,0],\"h\":1},{\"t\":3,\"s\":[100,100],\"h\":1},{\"t\":4,\"s\":[0,0],\"h\":1}],\"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 4\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,-3],[5.5,-1.75],[0,0],[26.75,0.25],[0,0],[9,-17.25],[0,0],[-3.25,-19.25],[0,0],[-8.5,-9.25],[0,0],[-14.75,-9.5],[0,0],[-18.5,2.75],[0,0],[-13,5],[0,0],[-9.5,16.5],[0,0],[-7,16.25],[0,0],[12.75,16.25],[0,0],[20.25,11.75],[0,0]],\"o\":[[-10.25,3],[-5.5,1.75],[0,0],[-26.75,-0.25],[0,0],[-9,17.25],[0,0],[3.25,19.25],[0,0],[8.5,9.25],[0,0],[14.75,9.5],[0,0],[18.5,-2.75],[0,0],[13,-5],[0,0],[9.5,-16.5],[0,0],[7,-16.25],[0,0],[-12.75,-16.25],[0,0],[-20.25,-11.75],[0,0]],\"v\":[[19,-97],[2.25,-85.75],[-4.75,-87.5],[-31.75,-96.5],[-64.5,-83],[-93.75,-63.5],[-99,-34.75],[-108,-0.5],[-99.5,20.5],[-90,53],[-70.5,62.5],[-54,82],[-35.75,87.5],[2.25,92],[18.5,84],[45,82.5],[60.25,69.25],[86.75,55.5],[91,28.75],[106.25,7.75],[108.75,-25.25],[105.5,-54.75],[88.25,-66.75],[70.25,-88.5],[41.25,-89.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":1,\"s\":[0,0],\"h\":1},{\"t\":2,\"s\":[100,100],\"h\":1},{\"t\":3,\"s\":[0,0],\"h\":1}],\"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 3\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.87,0.318],[0,0],[20.098,-10.357],[0,0],[5.5,-10.375],[0,0],[-8.375,-17.375],[0,0],[-8.75,-6.625],[0,0],[-14.875,0.5],[0,0],[-11.625,3.5],[0,0],[-5.25,9],[0,0],[-0.5,17.375],[0,0],[6.125,8],[0,0],[6.625,3.125],[0,0]],\"o\":[[-11.625,-0.375],[0,0],[-20.375,10.5],[0,0],[-6.558,12.37],[0,0],[8.156,16.92],[0,0],[8.75,6.625],[0,0],[14.875,-0.5],[0,0],[11.625,-3.5],[0,0],[5.25,-9],[0,0],[0.447,-15.518],[0,0],[-6.125,-8],[0,0],[-6.625,-3.125],[0,0]],\"v\":[[8.125,-57.25],[-3.75,-46.75],[-37.5,-48.875],[-42.125,-21.75],[-60.5,-21.125],[-51.125,-5.25],[-59.625,20.25],[-38.875,28.25],[-38.125,46.875],[-22.25,41.625],[-2.75,53.625],[14.375,40.375],[32.125,45.625],[39.25,36],[55.625,28.5],[51.5,13.25],[65.625,-9.125],[55.25,-22.5],[55.75,-41.125],[38.625,-40.25],[34,-53.75],[19.25,-44.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":0,\"s\":[0,0],\"h\":1},{\"t\":1,\"s\":[100,100],\"h\":1},{\"t\":2,\"s\":[0,0],\"h\":1}],\"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 2\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.875,-2.25],[0,0],[3.375,-4.5],[0,0],[0.125,-15.625],[0,0],[-9.125,-7.125],[0,0],[-15.809,5.312],[0,0],[-1.625,15],[0,0],[13.75,8.375],[0,0]],\"o\":[[-8.37,1.586],[0,0],[-3.375,4.5],[0,0],[-0.125,15.625],[0,0],[11.114,8.678],[0,0],[15.625,-5.25],[0,0],[1.625,-15],[0,0],[-13.75,-8.375],[0,0]],\"v\":[[-14.875,-37.75],[-24.5,-27.25],[-33.625,-26.25],[-34.25,-17.875],[-45.25,-2.625],[-35.5,15],[-28.5,33.25],[-8,35.75],[16.125,36.75],[33.125,23.875],[46.125,4.625],[40.625,-13.5],[28.625,-36],[3.625,-36]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":-1,\"s\":[0,0],\"h\":1},{\"t\":0,\"s\":[100,100],\"h\":1},{\"t\":1,\"s\":[0,0],\"h\":1}],\"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\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[3.5,2.75],[-1.75,-4]],\"o\":[[-3.5,-2.75],[1.75,4]],\"v\":[[-0.25,-62.25],[-4.625,-57.5]],\"c\":true}],\"e\":[{\"i\":[[0.045,0.036],[-0.023,-0.052]],\"o\":[[-0.045,-0.036],[0.023,0.052]],\"v\":[[-1.545,-59.289],[-1.602,-59.227]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 64\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.625,0.625],[-2.75,-7.125],[0.125,4.875]],\"o\":[[-4.625,-0.625],[2.75,7.125],[-0.125,-4.875]],\"v\":[[-11.875,-74.5],[-18,-64.625],[-5,-67.375]],\"c\":true}],\"e\":[{\"i\":[[0.036,0.005],[-0.022,-0.056],[0.001,0.038]],\"o\":[[-0.036,-0.005],[0.022,0.056],[-0.001,-0.038]],\"v\":[[-12.805,-66.377],[-12.853,-66.299],[-12.751,-66.321]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 65\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[1.312,0.875],[-2.438,-1.75]],\"o\":[[-1.312,-0.875],[2.438,1.75]],\"v\":[[218.25,-117.562],[217.062,-114.812]],\"c\":true}],\"e\":[{\"i\":[[0.017,0.011],[-0.031,-0.022]],\"o\":[[-0.017,-0.011],[0.031,0.022]],\"v\":[[217.108,-115.773],[217.093,-115.738]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 66\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.625,0],[-2.438,-5.312],[-1.062,4.125]],\"o\":[[-3.625,0],[2.438,5.312],[1.062,-4.125]],\"v\":[[216.062,-112.125],[210.375,-102.812],[220.562,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.05,0],[0.033,0.073],[0.015,-0.057]],\"o\":[[0.05,0],[-0.033,-0.073],[-0.015,0.057]],\"v\":[[214.764,-104.712],[214.842,-104.84],[214.702,-104.779]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 67\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.062,0.25],[-0.375,-3.5],[-1.062,2.438]],\"o\":[[-3.062,-0.25],[0.375,3.5],[1.062,-2.438]],\"v\":[[218.875,-126.688],[214.938,-120.812],[222.062,-122.188]],\"c\":true}],\"e\":[{\"i\":[[-0.067,-0.005],[0.008,0.077],[0.023,-0.053]],\"o\":[[0.067,0.005],[-0.008,-0.077],[-0.023,0.053]],\"v\":[[218.843,-122.025],[218.929,-122.154],[218.773,-122.124]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 68\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[2.25,-0.75],[-4,-4],[1,5.375]],\"o\":[[-2.25,0.75],[4,4],[-1,-5.375]],\"v\":[[-158.75,-23.375],[-159.25,-13.5],[-151.25,-18.875]],\"c\":true}],\"e\":[{\"i\":[[0.267,-0.089],[-0.475,-0.475],[0.119,0.638]],\"o\":[[-0.267,0.089],[0.475,0.475],[-0.119,-0.638]],\"v\":[[-156.987,-17.646],[-157.047,-16.475],[-156.097,-17.112]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 69\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.5,0.75],[-2.625,-4.375],[-0.625,4.625]],\"o\":[[-4.5,-0.75],[2.625,4.375],[0.625,-4.625]],\"v\":[[-174.375,-63],[-179.875,-56.375],[-169.875,-58.25]],\"c\":true}],\"e\":[{\"i\":[[-0.255,-0.042],[0.149,0.248],[0.035,-0.262]],\"o\":[[0.255,0.042],[-0.149,-0.248],[-0.035,0.262]],\"v\":[[-175.96,-57.585],[-175.649,-57.96],[-176.215,-57.854]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 70\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,1.25],[-3.25,-3]],\"o\":[[-3.125,-1.25],[3.25,3]],\"v\":[[-168.625,-97.625],[-170.375,-92.875]],\"c\":true}],\"e\":[{\"i\":[[0.24,0.096],[-0.25,-0.231]],\"o\":[[-0.24,-0.096],[0.25,0.231]],\"v\":[[-169.49,-94.625],[-169.625,-94.26]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 71\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.125,1.125],[-2.125,-3.25]],\"o\":[[-4.125,-1.125],[2.125,3.25]],\"v\":[[-174.75,-46.25],[-177.75,-41.25]],\"c\":true}],\"e\":[{\"i\":[[-0.223,-0.061],[0.115,0.176]],\"o\":[[0.223,0.061],[-0.115,-0.176]],\"v\":[[-175.277,-42.495],[-175.115,-42.765]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 72\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4,1.75],[-2.375,-2.5],[1.875,-2.125],[-6,2],[0,3.875]],\"o\":[[-4,-1.75],[2.375,2.5],[-1.875,2.125],[6,-2],[0,-3.875]],\"v\":[[-135.25,-91.25],[-140.375,-86.375],[-140.625,-79],[-138.5,-73],[-131.875,-84]],\"c\":true}],\"e\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}],\"e\":[{\"i\":[[-0.226,-0.099],[0.134,0.142],[-0.106,0.12],[0.34,-0.113],[0,-0.219]],\"o\":[[0.226,0.099],[-0.134,-0.142],[0.106,-0.12],[-0.34,0.113],[0,0.219]],\"v\":[[-138.024,-81.476],[-137.733,-81.752],[-137.719,-82.17],[-137.84,-82.509],[-138.215,-81.887]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 73\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.375,0.5],[-0.875,-5.875],[-0.25,4]],\"o\":[[-3.375,-0.5],[0.875,5.875],[0.25,-4]],\"v\":[[-149.375,-91.5],[-154,-81.25],[-144.25,-83.75]],\"c\":true}],\"e\":[{\"i\":[[0.272,0.04],[-0.07,-0.473],[-0.02,0.322]],\"o\":[[-0.272,-0.04],[0.07,0.473],[0.02,-0.322]],\"v\":[[-149.432,-84.316],[-149.805,-83.491],[-149.02,-83.693]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 74\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.25,0.5],[-1.625,-3.375],[0,2.75]],\"o\":[[-3.25,-0.5],[1.625,3.375],[0,-2.75]],\"v\":[[-139,-26.125],[-141.625,-19.5],[-134.5,-20.625]],\"c\":true}],\"e\":[{\"i\":[[-0.464,-0.071],[0.232,0.482],[0,-0.393]],\"o\":[[0.464,0.071],[-0.232,-0.482],[0,0.393]],\"v\":[[-138.857,-20.696],[-138.482,-21.643],[-139.5,-21.482]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 75\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,0.25],[-4.125,-0.5]],\"o\":[[-3.125,-0.25],[4.125,0.5]],\"v\":[[-129.25,-31.375],[-128.25,-26.5]],\"c\":true}],\"e\":[{\"i\":[[-0.379,-0.03],[0.5,0.061]],\"o\":[[0.379,0.03],[-0.5,-0.061]],\"v\":[[-128.129,-28.502],[-128.25,-29.093]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 76\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.875,0.25],[-6.125,-10.5],[0.875,9.875]],\"o\":[[-4.875,-0.25],[6.084,10.43],[-0.875,-9.875]],\"v\":[[-121.25,-44.375],[-123.25,-23.75],[-111.875,-31.25]],\"c\":true}],\"e\":[{\"i\":[[-0.298,-0.015],[0.375,0.643],[-0.054,-0.605]],\"o\":[[0.298,0.015],[-0.373,-0.639],[0.054,0.605]],\"v\":[[-120.122,-28.029],[-120,-29.292],[-120.696,-28.833]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 77\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[5.75,-0.125],[-1.25,-3.625],[-1.125,5.25]],\"o\":[[-5.75,0.125],[1.25,3.625],[1.125,-5.25]],\"v\":[[-177,-126.875],[-183.875,-117.875],[-168.5,-120.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-176.25,-120.625],[-176.25,-120.625],[-176.25,-120.625]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 78\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.625,-0.125],[0,0],[2.46,-4.038],[-3.208,-3.921],[0,0],[-1.375,10.5],[0,0],[1.065,4.639]],\"o\":[[-7.625,0.125],[0,0],[-2.228,3.658],[6.75,8.25],[0,0],[1.375,-10.5],[0,0],[-1.75,-7.625]],\"v\":[[-188.125,-106.125],[-193.75,-93.625],[-201.198,-89.718],[-200.125,-76],[-187.5,-73.625],[-172.875,-75.25],[-176.25,-88],[-173.375,-97.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.863,4.079],[-1.375,-8.125],[-4.25,1],[0,0],[-4.5,1.875],[4,3.25]],\"o\":[[-3.875,-3.25],[1.375,8.125],[4.25,-1],[0,0],[4.5,-1.875],[-4,-3.25]],\"v\":[[-151.125,-47.625],[-158.375,-39.375],[-148.75,-28.875],[-144.125,-31.75],[-136.75,-31.875],[-134.625,-46.375]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[1.75,2.5],[5,-5.25],[0,0],[-10.625,-1.875]],\"o\":[[-1.75,-2.5],[-5,5.25],[0,0],[10.625,1.875]],\"v\":[[-161.625,-32],[-173.25,-37],[-175,-28.625],[-168,-17]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,-1.5],[0,0],[4.75,-10.25],[-6.625,-1],[-1,4.5],[0,0],[0.625,8.5]],\"o\":[[-4.25,1.5],[0,0],[-4.75,10.25],[6.625,1],[1,-4.5],[0,0],[-0.625,-8.5]],\"v\":[[-191.5,-60.125],[-195.25,-53.5],[-209.625,-48.125],[-199.625,-31.75],[-188.125,-37.75],[-187.875,-44.875],[-180.125,-53.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 79\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,0],[4.5,2],[-1,-6.25],[-4,1.875],[-1.5,3.375]],\"o\":[[-4.25,0],[-4.5,-2],[1,6.25],[4,-1.875],[1.5,-3.375]],\"v\":[[-138.375,-45.625],[-149,-44.5],[-155.5,-36.75],[-144.5,-33.75],[-135.5,-35.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.625,1.25],[1.125,-4.875],[-1.75,-1.5],[0,0],[0,0],[3.625,-9.5],[-6.5,2.125],[-2.75,-2.5],[0.875,6.125],[0,0],[-0.125,3.625]],\"o\":[[-2.625,-1.25],[-1.125,4.875],[1.75,1.5],[0,0],[0,0],[-3.625,9.5],[6.5,-2.125],[2.75,2.5],[-0.875,-6.125],[0,0],[0.125,-3.625]],\"v\":[[-180.375,-103.75],[-191.375,-101.375],[-190,-93.25],[-185.875,-91.375],[-186.5,-89.125],[-199.625,-86.875],[-189.875,-74.875],[-181.5,-72.75],[-174.5,-78.875],[-179.25,-88.75],[-175.75,-97.125]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.243,-1.321],[0,0],[0,0],[4.125,0.25],[-2.125,-8.75],[-3.375,3],[0,0],[-1.529,-0.888],[0.5,4.75]],\"o\":[[-6.75,2.75],[0,0],[0,0],[-4.125,-0.25],[2.125,8.75],[3.375,-3],[0,0],[3.875,2.25],[-0.5,-4.75]],\"v\":[[-189,-58.75],[-191.25,-50.375],[-191.25,-50.125],[-199.75,-52.625],[-208.375,-40.375],[-192.75,-35.625],[-192,-46.125],[-188.875,-48.875],[-181.75,-53.375]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.125,0],[-0.375,-4.875],[-7,0.375],[1.5,4]],\"o\":[[-3.125,0],[0.375,4.875],[7,-0.375],[-1.5,-4]],\"v\":[[-168.25,-36.375],[-174,-29.875],[-166,-19.5],[-161.75,-30.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":28,\"s\":[0,0],\"h\":1},{\"t\":29,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 80\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,-0.75],[-2.625,-1.375],[0,4]],\"o\":[[-3.375,0.75],[2.625,1.375],[0,-4]],\"v\":[[-149.875,-43],[-151.625,-34.25],[-140.625,-37.875]],\"c\":true}],\"e\":[{\"i\":[[-0.036,0.016],[0.023,0.017],[0.003,-0.039]],\"o\":[[0.035,-0.016],[-0.03,-0.023],[-0.004,0.049]],\"v\":[[-147.285,-38.411],[-147.278,-38.502],[-147.371,-38.464]],\"c\":true}]},{\"t\":37}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":37,\"s\":[0,0],\"h\":1}],\"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 81\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,-1.25],[-3.625,-2.375],[2.25,3.125]],\"o\":[[-3.875,1.25],[3.625,2.375],[-2.25,-3.125]],\"v\":[[-168.875,-33.875],[-169.875,-23.625],[-163.625,-30.375]],\"c\":true}],\"e\":[{\"i\":[[0.04,-0.013],[-0.037,-0.024],[0.023,0.032]],\"o\":[[-0.04,0.013],[0.037,0.024],[-0.023,-0.032]],\"v\":[[-167.46,-27.678],[-167.463,-27.584],[-167.398,-27.653]],\"c\":true}]},{\"t\":36}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":36,\"s\":[0,0],\"h\":1}],\"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 82\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,0.625],[-3.75,-1.875]],\"o\":[[-3.375,-0.625],[3.75,1.875]],\"v\":[[-187,-58.125],[-187.875,-52.75]],\"c\":true}],\"e\":[{\"i\":[[0.105,0.02],[-0.117,-0.059]],\"o\":[[-0.105,-0.02],[0.117,0.059]],\"v\":[[-187.605,-54.916],[-187.633,-54.748]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 83\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.5,0.875],[-5.5,-5.875],[0.875,4]],\"o\":[[-4.5,-0.875],[5.5,5.875],[-0.875,-4]],\"v\":[[-200,-50.25],[-204.125,-37.625],[-192.375,-45.25]],\"c\":true}],\"e\":[{\"i\":[[-0.132,-0.026],[0.179,0.154],[-0.003,-0.12]],\"o\":[[0.132,0.026],[-0.128,-0.11],[0.004,0.139]],\"v\":[[-201.803,-42.273],[-201.682,-42.643],[-201.997,-42.496]],\"c\":true}]},{\"t\":39}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":39,\"s\":[0,0],\"h\":1}],\"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 84\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.375,0.875],[-2,-1.75]],\"o\":[[-2.375,-0.875],[2,1.75]],\"v\":[[-178.25,-80.5],[-180.375,-75.875]],\"c\":true}],\"e\":[{\"i\":[[0.183,0.067],[-0.154,-0.135]],\"o\":[[-0.183,-0.067],[0.154,0.135]],\"v\":[[-179.058,-77.962],[-179.221,-77.606]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 85\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.625,1.125],[-4.25,-5.5],[-2.125,4.125]],\"o\":[[-4.625,-1.125],[4.25,5.5],[2.125,-4.125]],\"v\":[[-191.75,-89.5],[-196.875,-79.375],[-186.875,-80.75]],\"c\":true}],\"e\":[{\"i\":[[-0.097,-0.024],[0.089,0.115],[0.045,-0.087]],\"o\":[[0.097,0.024],[-0.089,-0.115],[-0.045,0.087]],\"v\":[[-192.962,-82.098],[-192.839,-82.31],[-193.08,-82.289]],\"c\":true}]},{\"t\":38}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":38,\"s\":[0,0],\"h\":1}],\"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 86\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.346,0.324],[-2.993,-3.154],[-0.566,2.346]],\"o\":[[-2.346,-0.324],[2.993,3.154],[0.566,-2.346]],\"v\":[[-182.926,-100.581],[-185.757,-95],[-179.691,-95.647]],\"c\":true}],\"e\":[{\"i\":[[0.03,0.004],[-0.039,-0.041],[-0.007,0.03]],\"o\":[[-0.03,-0.004],[0.039,0.041],[0.007,-0.03]],\"v\":[[-183.924,-96.43],[-183.961,-96.357],[-183.882,-96.366]],\"c\":true}]},{\"t\":35}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":35,\"s\":[0,0],\"h\":1}],\"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 87\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.94,0.03,0.33,1]},\"o\":{\"a\":0,\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"}],\"ip\":0,\"op\":41,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"Shape Layer 1\",\"tt\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100},\"r\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[960,540,0]},\"a\":{\"a\":0,\"k\":[0,0,0]},\"s\":{\"a\":0,\"k\":[179.722,179.722,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.125,0.75],[-3.375,-2.75],[-0.25,4]],\"o\":[[-3.125,-0.75],[3.375,2.75],[0.25,-4]],\"v\":[[13.75,-112],[9.25,-104.125],[18.25,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.093,-0.022],[0.1,0.082],[0.007,-0.119]],\"o\":[[0.093,0.022],[-0.1,-0.082],[-0.007,0.119]],\"v\":[[12.141,-106.916],[12.275,-107.15],[12.007,-107.057]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 89\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5.875,0.625],[0.375,-4],[-6.875,8.125]],\"o\":[[-5.875,-0.625],[-0.375,4],[6.875,-8.125]],\"v\":[[23.5,-128.375],[13.375,-120.75],[30.375,-116.75]],\"c\":true}],\"e\":[{\"i\":[[-0.121,-0.013],[-0.008,0.082],[0.142,-0.168]],\"o\":[[0.121,0.013],[0.008,-0.082],[-0.142,0.168]],\"v\":[[25.159,-118.615],[25.367,-118.773],[25.017,-118.855]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 88\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.25],[-4.25,-0.25]],\"o\":[[-4,0.25],[4.25,0.25]],\"v\":[[218,-136.75],[217.75,-132]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[217.75,-134.375],[217.75,-134.375]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 61\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[6.75,-0.25],[-1.25,-8.5],[-5.25,4]],\"o\":[[-6.75,0.25],[1.25,8.5],[5.25,-4]],\"v\":[[149.75,-94.75],[140.25,-85.25],[161.75,-81.5]],\"c\":true}],\"e\":[{\"i\":[[-0.06,0.002],[0.011,0.076],[0.047,-0.036]],\"o\":[[0.06,-0.002],[-0.011,-0.076],[-0.047,0.036]],\"v\":[[153.029,-85.796],[153.114,-85.881],[152.922,-85.914]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 62\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.25,1],[-1.25,-4],[4.75,-1.75],[-4,-4.25],[-1.25,5],[-2.386,2.936]],\"o\":[[-3.25,-1],[1.25,4],[-4.75,1.75],[4,4.25],[1.25,-5],[3.25,-4]],\"v\":[[219.75,-128],[213.75,-121],[212.25,-112.5],[209.5,-100.5],[223.25,-109.25],[222.25,-121.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.625,1.125],[2.25,0],[2.125,0.5],[0.75,-6.375],[-4.25,0],[0,2.125],[0,0],[-1.25,0],[0,0],[-1.25,-6.25],[-2.625,7.625]],\"o\":[[-3.625,-1.125],[-2.25,0],[-2.125,-0.5],[-0.75,6.375],[4.25,0],[0,-2.125],[0,0],[1.25,0],[0,0],[1.25,6.25],[2.625,-7.625]],\"v\":[[-136.75,-94.375],[-142.5,-90.5],[-148.125,-93.375],[-155.625,-85.25],[-150.125,-76.5],[-145,-80.25],[-144.75,-84.375],[-142.75,-82.875],[-139.625,-84.25],[-144.125,-71.625],[-130.25,-79.75]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.625,-0.75],[-0.25,-2.875],[3.375,0],[0,-2.5],[2.875,-2.375],[-5.25,-9],[0,0],[-0.25,-1.875],[0,0],[2.875,-0.75],[0,0],[4,-4.875],[-10.625,-4.125],[-1.375,3.875],[0,0],[0,0],[0,-4],[0,0],[-8.125,-5.5],[0,0],[-7.25,3.625],[0,0],[-1.625,0.5],[0,0],[-1.125,-3],[-2.75,5.125],[0,0],[-0.625,0.75],[0,0],[-2.25,-0.5],[0,0],[-4.75,1.125],[1.375,6.75],[4.375,-1.625],[0,0],[1,0.375],[0,0],[0.375,3.25],[8.25,2.625],[6.125,-2.5],[0,0],[1.875,0.625],[0,0],[1,2.875],[0,0],[-1.875,1.375],[-0.125,3.25],[4.75,0],[0,0],[0.5,2.125],[0,0],[-1.625,0.5],[-2.375,4.75],[0,0],[0.25,2.875],[-0.375,1],[0,0],[-1.625,1.375],[3.125,2.25],[0,0],[-0.375,2.5],[4.5,0],[1,2.25],[-1.75,1.125],[-4,-0.5],[1.375,4]],\"o\":[[-6.625,0.75],[0.25,2.875],[-3.375,0],[0,2.5],[-2.875,2.375],[5.25,9],[0,0],[0.25,1.875],[0,0],[-2.875,0.75],[0,0],[-4,4.875],[10.625,4.125],[1.375,-3.875],[0,0],[0,0],[0,4],[0,0],[8.125,5.5],[0,0],[7.25,-3.625],[0,0],[1.625,-0.5],[0,0],[1.125,3],[2.75,-5.125],[0,0],[0.625,-0.75],[0,0],[2.25,0.5],[0,0],[4.75,-1.125],[-1.375,-6.75],[-4.375,1.625],[0,0],[-1,-0.375],[0,0],[-0.375,-3.25],[-8.25,-2.625],[-6.125,2.5],[0,0],[-1.875,-0.625],[0,0],[-1,-2.875],[0,0],[1.875,-1.375],[0.125,-3.25],[-4.75,0],[0,0],[-0.5,-2.125],[0,0],[1.625,-0.5],[2.375,-4.75],[0,0],[-0.25,-2.875],[0.375,-1],[0,0],[1.625,-1.375],[-3.125,-2.25],[0,0],[0.375,-2.5],[-4.5,0],[-1,-2.25],[1.75,-1.125],[4,0.5],[-1.375,-4]],\"v\":[[-178.75,-127],[-187.125,-115.5],[-190.625,-108.375],[-197.25,-100.75],[-200.875,-92.25],[-202.375,-75],[-188.75,-71],[-189.625,-67],[-188,-62.875],[-193.25,-61.75],[-197.5,-56.125],[-210.75,-52.625],[-204.625,-30.25],[-186.75,-36.625],[-179.625,-39.875],[-176.75,-37],[-181.625,-31.375],[-177.75,-26.375],[-176.5,-15.125],[-162.125,-15.5],[-152.125,-11.75],[-152,-26],[-147.625,-23.5],[-143,-27],[-143.125,-21.125],[-135.25,-18.25],[-137.625,-26],[-135,-27.375],[-132.625,-30.375],[-129,-25.25],[-126.5,-27.125],[-117.5,-16.875],[-111.625,-36.125],[-125.125,-44.25],[-127.125,-34.5],[-129.375,-36.25],[-131.625,-36.75],[-130.375,-42.875],[-140.75,-51.125],[-158.875,-50.25],[-163,-39],[-167,-40.625],[-171.625,-40.625],[-171.875,-45.875],[-177.375,-50.5],[-172.25,-50.875],[-169,-58.25],[-175.5,-64.5],[-182.125,-59.625],[-181.25,-63.125],[-183,-66.5],[-178.75,-65.875],[-171.5,-70.75],[-171.125,-80],[-168.375,-85],[-171.625,-90.125],[-171.75,-92.625],[-165.75,-92],[-166.375,-96.75],[-173.75,-96.875],[-171.125,-101],[-177.75,-106.5],[-186.125,-110],[-183.25,-114.75],[-173.75,-116.25],[-167.625,-123.875]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 63\",\"np\":3,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.25,1.188],[-1.25,-6.188],[-2.625,2.75]],\"o\":[[-7.25,-1.188],[1.25,6.188],[2.625,-2.75]],\"v\":[[201.125,-142.25],[193.062,-136.25],[208.312,-131.438]],\"c\":true}],\"e\":[{\"i\":[[-0.095,-0.016],[0.016,0.081],[0.034,-0.036]],\"o\":[[0.095,0.016],[-0.016,-0.081],[-0.034,0.036]],\"v\":[[201.378,-135.982],[201.484,-136.06],[201.284,-136.123]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 51\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.875,1.188],[-1.875,-2.688]],\"o\":[[-2.875,-1.188],[1.875,2.688]],\"v\":[[173.562,-155.062],[170.938,-151.438]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[172.75,-152.5],[172.75,-152.5]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 52\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[7.688,0.875],[-1.5,-6.312],[-2.562,2.5]],\"o\":[[-7.688,-0.875],[1.5,6.312],[2.562,-2.5]],\"v\":[[159.062,-160.125],[148.938,-152.875],[164.562,-151.812]],\"c\":true}],\"e\":[{\"i\":[[-0.024,-0.003],[0.005,0.02],[0.008,-0.008]],\"o\":[[0.024,0.003],[-0.005,-0.02],[-0.008,0.008]],\"v\":[[157.276,-153.761],[157.308,-153.784],[157.258,-153.788]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 53\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.625,0.062],[1.212,-1.167],[2.188,-0.688],[-1.5,-4.375],[-2.875,1.938],[0,2.375]],\"o\":[[-1.625,-0.062],[-1.688,1.625],[-2.188,0.688],[1.5,4.375],[2.875,-1.938],[0,-2.375]],\"v\":[[173.75,-77.062],[171.25,-73.375],[166.375,-72.875],[162.75,-65],[174.125,-64.25],[176.625,-72.312]],\"c\":true}],\"e\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[0.436,0.457],[1.089,0],[0.261,-0.784],[-1.133,-1.089],[-1.002,0.675],[0,0.828]],\"o\":[[-0.391,-0.41],[-0.566,0],[-0.253,0.758],[1.162,1.117],[1.002,-0.675],[0,-0.828]],\"v\":[[172.797,-70.595],[170.663,-71.183],[168.528,-69.571],[169.008,-66.478],[172.536,-66.217],[173.625,-68.591]],\"c\":true}],\"e\":[{\"i\":[[-0.038,-0.04],[-0.095,0],[-0.023,0.068],[0.098,0.095],[0.087,-0.059],[0,-0.072]],\"o\":[[0.034,0.036],[0.049,0],[0.022,-0.066],[-0.101,-0.097],[-0.087,0.059],[0,0.072]],\"v\":[[170.572,-68.07],[170.758,-68.019],[170.943,-68.159],[170.902,-68.428],[170.595,-68.451],[170.5,-68.244]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 54\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3,0.125],[-3.812,-5.375],[-0.562,2.688]],\"o\":[[-2.788,-0.116],[3.812,5.375],[0.562,-2.688]],\"v\":[[159.688,-49.25],[155.625,-42.188],[167.062,-44.438]],\"c\":true}],\"e\":[{\"i\":[[-0.083,-0.003],[0.105,0.149],[0.016,-0.074]],\"o\":[[0.077,0.003],[-0.105,-0.149],[-0.016,0.074]],\"v\":[[159.72,-42.919],[159.832,-43.114],[159.516,-43.052]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 55\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[1.812,0.688],[-2.688,-1.938]],\"o\":[[-1.812,-0.688],[2.688,1.938]],\"v\":[[168.375,-53.875],[167.312,-49.5]],\"c\":true}],\"e\":[{\"i\":[[0.061,0.023],[-0.091,-0.065]],\"o\":[[-0.061,-0.023],[0.091,0.065]],\"v\":[[167.439,-51.157],[167.403,-51.01]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 56\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.5,0.5],[-1.625,-5],[-1.75,4.625]],\"o\":[[-3.5,-0.5],[1.625,5],[1.75,-4.625]],\"v\":[[-39.5,-143.5],[-46.75,-133.25],[-34.5,-134.125]],\"c\":true}],\"e\":[{\"i\":[[0.14,0.02],[-0.065,-0.2],[-0.07,0.185]],\"o\":[[-0.14,-0.02],[0.065,0.2],[0.07,-0.185]],\"v\":[[-40.52,-136.42],[-40.81,-136.01],[-40.32,-136.045]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 57\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.638,-0.147],[-0.879,-2.418],[-0.879,1.759]],\"o\":[[-2.638,0.147],[0.879,2.418],[0.879,-1.759]],\"v\":[[-74.793,-156.267],[-77.871,-151.504],[-71.129,-152.31]],\"c\":true}],\"e\":[{\"i\":[[-0.18,0.01],[0.06,0.165],[0.06,-0.12]],\"o\":[[0.18,-0.01],[-0.06,-0.165],[-0.06,0.12]],\"v\":[[-74.48,-152.51],[-74.27,-152.835],[-74.73,-152.78]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 58\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,0.75],[-2,-3.125],[-0.5,2.375]],\"o\":[[-3.875,-0.75],[2,3.125],[0.5,-2.375]],\"v\":[[-160.125,-91],[-164.25,-84.75],[-156.5,-85.875]],\"c\":true}],\"e\":[{\"i\":[[0.526,0.102],[-0.272,-0.424],[-0.068,0.323]],\"o\":[[-0.526,-0.102],[0.272,0.424],[0.068,-0.323]],\"v\":[[-160.989,-87.273],[-161.549,-86.424],[-160.497,-86.577]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 59\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[5,0.75],[-6.875,-6.125],[-1.25,3.875]],\"o\":[[-5,-0.75],[6.875,6.125],[1.25,-3.875]],\"v\":[[-153,-135.375],[-157,-126.875],[-142.5,-128.625]],\"c\":true}],\"e\":[{\"i\":[[-0.304,-0.046],[0.418,0.372],[0.076,-0.235]],\"o\":[[0.304,0.046],[-0.418,-0.372],[-0.076,0.235]],\"v\":[[-152.536,-128.016],[-152.293,-128.532],[-153.174,-128.426]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 60\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.75,-4.5],[-9.375,-3.625],[-3.125,2.375],[1.156,-5.286],[4.256,-4.745],[-5.106,-1.885],[2.75,7.875],[0.572,6.865]],\"o\":[[-8.75,4.5],[9.375,3.625],[2.994,-2.275],[-0.875,4],[-3.139,3.5],[8.125,3],[-2.75,-7.875],[-0.875,-10.5]],\"v\":[[142.375,-96.125],[143.75,-76.875],[160.75,-77.625],[169.5,-75.625],[163.494,-72.88],[164.5,-60.625],[177.375,-75],[167.75,-84]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[8.25,0],[0,0],[3.75,1.375],[8,-3.5],[0,0],[1.5,-1],[0,0],[3.75,-3.625],[0.5,-14.875],[0,0],[2.75,-1.75],[0,0],[5.5,-7],[-16.125,-2.875],[0,0],[-0.25,-2.375],[0,0],[-7.125,-3],[0,0],[-7.25,2.75],[0,0],[-5.125,1.5],[0,0],[-2,-0.5],[0,0],[-6,-0.75],[2.5,14.875],[0,0],[14.75,-1.75],[0,0],[0.75,2.125],[0,0],[-1.25,4.25],[0,0],[-1.75,4.25],[0,0],[-1.625,0],[0,0],[-2.125,-2.5],[0,0],[-2.75,0],[-3.375,4.625],[5.5,5.125],[0,0],[1.625,-0.25],[1.125,-1.75],[0,0],[1.875,2.375],[0,0],[2.625,2.75],[4.125,-0.625],[0,0],[-0.75,1.125],[0,0],[-2.375,-0.375],[-2.625,2.375],[0.625,1.75],[0,0],[-4.75,0.125],[-0.25,5.5]],\"o\":[[-8.25,0],[0,0],[-3.75,-1.375],[-8,3.5],[0,0],[-1.5,1],[0,0],[-3.75,3.625],[-0.5,14.875],[0,0],[-2.75,1.75],[0,0],[-5.5,7],[16.125,2.875],[0,0],[0.25,2.375],[0,0],[7.125,3],[0,0],[7.25,-2.75],[0,0],[5.125,-1.5],[0,0],[2,0.5],[0,0],[6,0.75],[-2.5,-14.875],[0,0],[-14.75,1.75],[0,0],[-0.75,-2.125],[0,0],[1.25,-4.25],[0,0],[1.75,-4.25],[0,0],[1.625,0],[0,0],[2.125,2.5],[0,0],[2.75,0],[3.375,-4.625],[-5.5,-5.125],[0,0],[-1.625,0.25],[-1.125,1.75],[0,0],[-1.875,-2.375],[0,0],[-2.625,-2.75],[-4.125,0.625],[0,0],[0.75,-1.125],[0,0],[2.375,0.375],[2.625,-2.375],[-0.625,-1.75],[0,0],[4.75,-0.125],[0.25,-5.5]],\"v\":[[-156.875,-136.875],[-163.125,-128.875],[-166.375,-126.5],[-182.625,-128.625],[-189,-113.125],[-191.875,-112.75],[-190.875,-110.125],[-197.125,-106.875],[-206,-80.375],[-189.875,-63.375],[-196,-63.125],[-198.75,-59],[-213.5,-53.875],[-203.375,-26.5],[-183.125,-35.875],[-184,-30.5],[-182,-25],[-177.75,-11.625],[-163.875,-11.5],[-150.875,-8.875],[-144.875,-18.875],[-136.25,-15.5],[-132.625,-26.5],[-129.875,-22.375],[-126.5,-22.875],[-119.75,-15.875],[-109.25,-33.625],[-127,-46.75],[-150.625,-54.75],[-165.5,-43.125],[-168.25,-46.625],[-171.625,-48.625],[-166,-56.125],[-168.75,-64.875],[-163.75,-71.25],[-166.375,-80.625],[-161.75,-80.5],[-158.5,-82.875],[-155.625,-73.5],[-147.5,-71.25],[-141.875,-66.625],[-131.5,-73.375],[-133.125,-94.125],[-142.875,-95.5],[-146.375,-98.25],[-153.375,-95.125],[-160.625,-93.125],[-162.125,-98.625],[-168.75,-99],[-166.875,-106.25],[-178.5,-108.875],[-184.125,-111.375],[-179.5,-112.5],[-177.625,-115.25],[-172.875,-113.25],[-165,-114.25],[-161.125,-123.375],[-160.125,-126.5],[-150.875,-123.375],[-140.125,-129]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.562,5.875],[1.562,-4.125],[2.188,-1.562],[-2.312,-2],[-3.5,2.688]],\"o\":[[-3.562,-5.875],[-1.562,4.125],[-2.188,1.562],[1.731,1.497],[3.5,-2.688]],\"v\":[[-33.688,-142.125],[-45.938,-140.688],[-51.562,-135.688],[-50.375,-129.562],[-37.25,-129.438]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.375,0.5],[-2.312,-3.25],[1.438,-4.312],[-6.438,-1.875],[-1.75,1.375],[2.062,2.25],[0.75,2.188],[1.312,1.062],[0,0],[-0.438,6.375]],\"o\":[[-4.375,-0.5],[2.312,3.25],[-1.438,4.312],[6.438,1.875],[1.75,-1.375],[-2.062,-2.25],[-0.75,-2.188],[-1.312,-1.062],[0,0],[0.438,-6.375]],\"v\":[[-74.688,-160],[-83.312,-150],[-81.938,-142.625],[-76.062,-127.5],[-61.812,-128.312],[-61.188,-133.625],[-67,-137.75],[-68.812,-144.188],[-75.938,-145.812],[-66.562,-153.812]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.25,0.875],[1.375,-4],[0,0],[0,-7.375],[-2.5,3.5],[0,0],[-2.5,8.125]],\"o\":[[-5.25,-0.875],[-1.375,4],[0,0],[0,7.375],[2.5,-3.5],[0,0],[2.5,-8.125]],\"v\":[[22,-130],[12.5,-123.75],[13.875,-115.75],[5.125,-105.125],[20,-101.125],[21.625,-110.75],[33,-118.5]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.875,1.75],[-5.5,-6],[-1.875,0.375],[0,0],[-0.5,-3.25],[0,0],[0,-13.75],[-1.375,4.5],[1.5,4.5],[-1.125,3.25],[3.75,3.75],[0,0]],\"o\":[[-7.875,-1.75],[5.5,6],[1.875,-0.375],[0,0],[0.5,3.25],[0,0],[0,13.75],[1.375,-4.5],[-1.5,-4.5],[1.125,-3.25],[-3.75,-3.75],[0,0]],\"v\":[[200.875,-143.625],[191.75,-133.625],[210.625,-128.75],[214.875,-129.625],[210.625,-122.375],[213.125,-116.75],[203.125,-103.875],[223.5,-103.875],[225,-116.5],[224.875,-126],[220.25,-137.375],[211.5,-137.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3,1.375],[-1,-7.375],[-3.125,0.875],[-2.25,-1.5],[0.125,4.125],[4.125,1]],\"o\":[[-3,-1.375],[1,7.375],[3.125,-0.875],[2.25,1.5],[-0.125,-4.125],[-4.125,-1]],\"v\":[[157,-162.875],[145.75,-154.125],[159.125,-148.75],[168.625,-148],[180.25,-151.75],[167.25,-160.75]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.375,0.875],[-0.625,-3],[1,1.75],[1.375,-6.875],[-6.125,2.375],[-2.75,1.125]],\"o\":[[-2.375,-0.875],[0.625,3],[-1,-1.75],[-1.375,6.875],[6.125,-2.375],[2.343,-0.958]],\"v\":[[169.25,-55.5],[166,-51.75],[162.25,-49.875],[152.75,-45.875],[164.75,-40.25],[169.875,-48.75]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 50\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[8.75,-0.625],[-7.375,-13.5],[-1.25,4.75]],\"o\":[[-8.75,0.625],[7.375,13.5],[1.25,-4.75]],\"v\":[[67.875,-134.75],[59.875,-116.375],[83.375,-117.75]],\"c\":true}],\"e\":[{\"i\":[[-0.034,0.002],[0.029,0.053],[0.005,-0.018]],\"o\":[[0.034,-0.002],[-0.029,-0.053],[-0.005,0.018]],\"v\":[[68.565,-119.064],[68.596,-119.136],[68.505,-119.13]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 41\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,1.125],[-2,-11.25],[-3.875,7]],\"o\":[[-6.75,-1.125],[2,11.25],[3.875,-7]],\"v\":[[196.25,-47.625],[186.125,-30.125],[205.125,-28.5]],\"c\":true}],\"e\":[{\"i\":[[0.237,0.04],[-0.07,-0.396],[-0.136,0.246]],\"o\":[[-0.237,-0.04],[0.07,0.396],[0.136,-0.246]],\"v\":[[196.552,-34.298],[196.195,-33.683],[196.864,-33.626]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 42\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.966,1.57],[0.343,-4.457],[-2.555,0.983]],\"o\":[[-2.966,-1.57],[-0.349,4.536],[4.536,-1.745]],\"v\":[[189.772,-1.472],[181.224,4.896],[188.464,10.217]],\"c\":true}],\"e\":[{\"i\":[[-0.214,-0.113],[-0.025,0.322],[0.184,-0.071]],\"o\":[[0.214,0.113],[0.025,-0.327],[-0.327,0.126]],\"v\":[[186.733,4.48],[187.35,4.02],[186.827,3.636]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 43\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.625,0.375],[-6.125,-6],[-1.25,4.375]],\"o\":[[-6.625,-0.375],[6.125,6],[1.25,-4.375]],\"v\":[[103.625,-133.75],[98.25,-121.5],[114.75,-125]],\"c\":true}],\"e\":[{\"i\":[[0.222,0.013],[-0.206,-0.201],[-0.042,0.147]],\"o\":[[-0.222,-0.013],[0.206,0.201],[0.042,-0.147]],\"v\":[[104.048,-125.112],[103.867,-124.701],[104.421,-124.819]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 44\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[6.75,0.625],[-3.875,-8.375],[-2.375,6.375]],\"o\":[[-6.75,-0.625],[3.875,8.375],[2.375,-6.375]],\"v\":[[211.625,-85.875],[201,-73.625],[220.375,-75.625]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.003],[-0.019,-0.041],[-0.012,0.031]],\"o\":[[-0.033,-0.003],[0.019,0.041],[0.012,-0.031]],\"v\":[[209.946,-75.924],[209.894,-75.864],[209.988,-75.874]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 45\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.25,0.625],[-3.375,-1.25]],\"o\":[[-3.25,-0.625],[3.375,1.25]],\"v\":[[-193,-116.125],[-194.625,-111.375]],\"c\":true}],\"e\":[{\"i\":[[-0.061,-0.012],[0.064,0.024]],\"o\":[[0.061,0.012],[-0.064,-0.024]],\"v\":[[-193.892,-113.387],[-193.861,-113.476]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 46\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[3.5,0.375],[-4.375,-3.875],[-0.125,3]],\"o\":[[-3.5,-0.375],[4.375,3.875],[0.125,-3]],\"v\":[[-60.625,-146.5],[-63.25,-139],[-55.25,-142.25]],\"c\":true}],\"e\":[{\"i\":[[0.298,0.032],[-0.372,-0.33],[-0.011,0.255]],\"o\":[[-0.298,-0.032],[0.372,0.33],[0.011,-0.255]],\"v\":[[-61.311,-141.468],[-61.535,-140.83],[-60.854,-141.106]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 47\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[4.462,1.05],[-3.413,-4.375],[-1.575,3.413]],\"o\":[[-4.463,-1.05],[3.412,4.375],[1.575,-3.412]],\"v\":[[1.113,-129.537],[-4.837,-120.788],[5.925,-120.613]],\"c\":true}],\"e\":[{\"i\":[[-0.071,-0.017],[0.054,0.069],[0.025,-0.054]],\"o\":[[0.071,0.017],[-0.054,-0.069],[-0.025,0.054]],\"v\":[[-0.399,-123.404],[-0.304,-123.543],[-0.475,-123.546]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 48\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":26,\"s\":[{\"i\":[[2.375,0.375],[-3.375,-4.125],[0,2.625]],\"o\":[[-2.375,-0.375],[3.375,4.125],[0,-2.625]],\"v\":[[135.875,-163.625],[132.125,-156.5],[141.5,-158.875]],\"c\":true}],\"e\":[{\"i\":[[0.077,0.012],[-0.109,-0.133],[0,0.085]],\"o\":[[-0.077,-0.012],[0.109,0.133],[0,-0.085]],\"v\":[[135.149,-158.363],[135.028,-158.133],[135.331,-158.21]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":25,\"s\":[0,0],\"h\":1},{\"t\":26,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 49\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.07,-0.047],[-3.875,-7.25],[0,0],[-0.25,-4],[-5.875,-1.875],[0,2.75],[-3.25,1.25],[5.75,7.5],[5.333,-2.828],[0,0],[2.959,3.893]],\"o\":[[-8.25,0.125],[3.875,7.25],[0,0],[0.25,4],[5.875,1.875],[0,-2.75],[3.25,-1.25],[-2.966,-3.868],[-5.007,2.656],[0,0],[-1.754,-2.308]],\"v\":[[-1.25,-134.125],[-8.75,-118.75],[5.375,-113.5],[2.625,-104.875],[12.625,-92.75],[23.625,-105.625],[30.375,-111.5],[33.875,-127.875],[16.728,-131.431],[10.125,-120.875],[8.81,-131.165]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,1.375],[0.625,-3.5],[3.625,2.5],[7.5,-0.375],[-3.75,-9],[-9,1.125],[-5.875,-0.75],[-12.625,5.5]],\"o\":[[-10.25,-1.375],[-0.625,3.5],[-3.625,-2.5],[-7.5,0.375],[3.75,9],[9,-1.125],[5.875,0.75],[12.625,-5.5]],\"v\":[[104.875,-137.125],[93,-131.875],[82.875,-127.75],[68.75,-136.625],[55.375,-118.25],[76.875,-109.75],[90.125,-122],[112.5,-117.625]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.125,0.75],[-1.25,-11.375],[-3.25,-2.375],[1,-0.5],[3.5,-14.25],[-10.25,4],[0.625,3.75],[-2.125,4.25],[-2.125,4.5],[0.625,10]],\"o\":[[-5.125,-0.75],[1.25,11.375],[3.25,2.375],[-1,0.5],[-3.5,14.25],[10.25,-4],[-0.625,-3.75],[2.125,-4.25],[2.125,-4.5],[-0.625,-10]],\"v\":[[195.375,-51.125],[186.5,-34.25],[191.625,-20.25],[195.25,-14.75],[177,5.625],[187.75,17.625],[197.5,0.625],[194.125,-9.875],[201,-18],[205.375,-37.75]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.891,-8.168],[-9.875,-6.125],[0,0],[-1.625,-4.75],[0,0],[1,-1.625],[0,0],[7.125,-5.25],[-10.375,-0.375],[-2.875,5],[0,0],[-1.5,5.375],[8.735,11.767]],\"o\":[[-10,7.5],[9.875,6.125],[0,0],[1.625,4.75],[0,0],[-1,1.625],[0,0],[-5.73,4.222],[10.375,0.375],[2.875,-5],[0,0],[1.5,-5.375],[-9,-12.125]],\"v\":[[133.875,-97.5],[136.75,-75.875],[160,-72],[158.125,-61.125],[166.125,-57.375],[164,-54.875],[164,-51.625],[152.75,-52.125],[157.625,-36.375],[173.25,-47],[170.125,-58.25],[178.75,-64.125],[173,-84.375]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[13.632,3.84],[0,0],[8.75,1.375],[-6.25,-4],[-2.625,-2],[-12,-1.125],[-3.75,1.625],[0.375,-2.5],[-9.625,-3.125],[-1.875,-2.875],[1.875,-11.875],[1.875,-2.875],[-6.875,-5.625],[-1.75,8],[3.5,0.625],[-2.75,0.75],[-1.5,24.5],[6.125,1.375],[1.25,5.875]],\"o\":[[-17.75,-5],[0,0],[-8.75,-1.375],[6.25,4],[2.625,2],[12,1.125],[3.75,-1.625],[-0.375,2.5],[9.625,3.125],[1.875,2.875],[-1.875,11.875],[-1.875,2.875],[6.875,5.625],[1.75,-8],[-3.5,-0.625],[2.75,-0.75],[1.5,-24.5],[-6.125,-1.375],[-1.25,-5.875]],\"v\":[[164.25,-163.375],[141.75,-158.125],[134.625,-163.625],[133.5,-156.125],[141.25,-153.75],[157.625,-145.375],[180,-145.625],[185.625,-140.125],[194.75,-129],[209.375,-125.5],[199.75,-106.375],[203.625,-88.5],[201.625,-69.875],[221.125,-75.5],[211.5,-88.875],[210.625,-94.5],[228.375,-119.75],[199.625,-145.125],[183.5,-151.125]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[12.125,1.25],[0,0],[6.875,-5.375],[0,0],[3,-1],[0,0],[6.125,-21.125],[0,0],[3,-8.875],[-12.25,-6.25],[0,0],[0,-2.875],[-8.625,-4.75],[0,0],[-13,0.5],[0,0],[-5.75,0],[0,0],[-6.125,-0.625],[0.5,12.25],[13.625,7.375],[0,0],[0.875,2.875],[0,0],[-4.25,-1.125],[-3.75,0.875],[-2.5,9],[5.375,8.75],[1.75,-3.625],[0,0],[1.75,3.625],[0,0],[-4.5,3.5],[0,0],[-2,-0.5],[-3.125,6.5]],\"o\":[[-12.125,-1.25],[0,0],[-6.875,5.375],[0,0],[-3,1],[0,0],[-6.125,21.125],[0,0],[-3,8.875],[12.25,6.25],[0,0],[0,2.875],[8.625,4.75],[0,0],[13,-0.5],[0,0],[5.75,0],[0,0],[6.125,0.625],[-0.5,-12.25],[-13.625,-7.375],[0,0],[-0.875,-2.875],[0,0],[4.25,1.125],[3.75,-0.875],[2.5,-9],[-5.375,-8.75],[-1.75,3.625],[0,0],[-1.75,-3.625],[0,0],[4.5,-3.5],[0,0],[2,0.5],[3.125,-6.5]],\"v\":[[-153,-138.25],[-168.25,-132.75],[-185.25,-129.625],[-190,-114.875],[-194.75,-116.375],[-196,-112.625],[-211.25,-93.125],[-200.625,-63.375],[-218.375,-54.375],[-207.625,-23.625],[-184.375,-28.125],[-189.5,-19.5],[-181.625,-9.375],[-167.875,-6.5],[-154.625,-3.25],[-143.25,-14.625],[-137.125,-11.375],[-129.625,-15],[-121.75,-9],[-107.875,-28.125],[-130.625,-56.25],[-162.375,-53.875],[-158.25,-61.75],[-159.125,-71],[-150.25,-65.875],[-137,-65.25],[-127.375,-76.875],[-131.125,-100.875],[-147.875,-103.375],[-158.875,-95.625],[-159.75,-104.5],[-170.625,-110.5],[-161.875,-112.625],[-160,-124.125],[-153.375,-120.625],[-138.625,-126.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[6.5,2.75],[-1.5,-15.5],[-9.25,-0.375],[-1,1.375],[-6.25,0],[-1,4.5],[5.75,0.875],[1.875,-3.875],[0.5,2.25],[3.375,1.75],[0.75,-2],[0,0],[1.875,1.25],[0,0],[-2,3.875]],\"o\":[[-6.5,-2.75],[1.5,15.5],[9.25,0.375],[1,-1.375],[6.25,0],[1,-4.5],[-5.75,-0.875],[-1.875,3.875],[-0.5,-2.25],[-3.375,-1.75],[-0.75,2],[0,0],[-1.875,-1.25],[0,0],[2,-3.875]],\"v\":[[-72,-161.625],[-86.75,-140.75],[-69.25,-125.625],[-54.625,-131.875],[-47.125,-125.375],[-29.5,-135.625],[-38.75,-148.375],[-50.25,-140.625],[-55.375,-139.625],[-56.375,-146.25],[-65.5,-146.375],[-66.125,-140.875],[-69.125,-145.875],[-74.375,-147.125],[-64.875,-150.375]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 40\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.25,3],[-4,-4.25]],\"o\":[[-6.25,-3],[4,4.25]],\"v\":[[118.75,-151.25],[115,-144]],\"c\":true}],\"e\":[{\"i\":[[0.431,0.207],[-0.276,-0.293]],\"o\":[[-0.431,-0.207],[0.276,0.293]],\"v\":[[118.052,-147.293],[117.793,-146.793]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 29\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,0.75],[-3.5,-4.75],[-4.5,6.5]],\"o\":[[-5.75,-0.75],[3.5,4.75],[4.5,-6.5]],\"v\":[[138,-25.75],[132.5,-13],[144,-16.75]],\"c\":true}],\"e\":[{\"i\":[[-0.442,-0.058],[0.269,0.365],[0.346,-0.5]],\"o\":[[0.442,0.058],[-0.269,-0.365],[-0.346,0.5]],\"v\":[[138.808,-16.731],[139.231,-17.712],[138.346,-17.423]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 30\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.75,-2.25],[-8,-4.5],[0,6]],\"o\":[[-4.75,2.25],[8,4.5],[0,-6]],\"v\":[[92.25,65.25],[88.75,79.25],[106.75,69]],\"c\":true}],\"e\":[{\"i\":[[0.057,-0.027],[-0.096,-0.054],[0,0.072]],\"o\":[[-0.057,0.027],[0.096,0.054],[0,-0.072]],\"v\":[[93.732,73.277],[93.69,73.446],[93.907,73.322]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 31\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[6.5,1.25],[-6.75,-3.25]],\"o\":[[-6.5,-1.25],[6.75,3.25]],\"v\":[[-89,-175],[-90.75,-166]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-90,-169.5],[-90,-169.5]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 32\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[15,1],[-2.5,-10.75],[-4,5.25]],\"o\":[[-15,-1],[2.5,10.75],[4,-5.25]],\"v\":[[-111,-164.5],[-126.75,-146.5],[-100.25,-147]],\"c\":true}],\"e\":[{\"i\":[[-1.241,-0.083],[0.207,0.889],[0.331,-0.434]],\"o\":[[1.241,0.083],[-0.207,-0.889],[-0.331,0.434]],\"v\":[[-112.759,-149.477],[-111.457,-150.966],[-113.648,-150.925]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 33\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.75,-1.75],[-15.5,-8.5],[5.75,4.5]],\"o\":[[-5.75,1.75],[15.5,8.5],[-5.75,-4.5]],\"v\":[[129.5,37.25],[129,63],[147,42.75]],\"c\":true}],\"e\":[{\"i\":[[-0.037,0.011],[0.099,0.054],[-0.037,-0.029]],\"o\":[[0.037,-0.011],[-0.099,-0.054],[0.037,0.029]],\"v\":[[133.148,53.604],[133.151,53.439],[133.037,53.568]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 34\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[7.75,2.5],[-5.25,-4.5],[-0.25,5.5]],\"o\":[[-7.75,-2.5],[5.25,4.5],[0.25,-5.5]],\"v\":[[162.75,15.25],[154.25,31],[168.5,26]],\"c\":true}],\"e\":[{\"i\":[[-0.901,-0.291],[0.61,0.523],[0.029,-0.64]],\"o\":[[0.901,0.291],[-0.61,-0.523],[-0.029,0.64]],\"v\":[[159.401,25.157],[160.39,23.326],[158.733,23.907]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 35\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[5.25,2.5],[-2.625,-2.625]],\"o\":[[-3.898,-1.856],[2.625,2.625]],\"v\":[[-154.5,5.25],[-157.75,12.375]],\"c\":true}],\"e\":[{\"i\":[[-0.177,-0.084],[0.088,0.088]],\"o\":[[0.131,0.063],[-0.088,-0.088]],\"v\":[[-154.823,9.33],[-154.713,9.09]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 36\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.25],[-4.25,-7],[-0.125,7.5]],\"o\":[[-4.125,-1.25],[4.25,7],[0.125,-7.5]],\"v\":[[-147.5,25.5],[-150.5,40.875],[-132.875,46.5]],\"c\":true}],\"e\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":29,\"s\":[{\"i\":[[2.286,0.693],[-2.355,-3.879],[-0.069,4.156]],\"o\":[[-2.286,-0.693],[2.355,3.879],[0.069,-4.156]],\"v\":[[-147.611,33.318],[-150.659,39.621],[-142.555,39.136]],\"c\":true}],\"e\":[{\"i\":[[-0.109,-0.033],[0.112,0.184],[0.003,-0.197]],\"o\":[[0.109,0.033],[-0.112,-0.184],[-0.003,0.197]],\"v\":[[-147.757,38.288],[-147.612,37.988],[-147.997,38.012]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 37\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.125,1.625],[-5.375,-9.5],[-3.625,10.125]],\"o\":[[-4.125,-1.625],[5.375,9.5],[3.625,-10.125]],\"v\":[[-101.25,-11.75],[-109.75,5.75],[-95.5,2.375]],\"c\":true}],\"e\":[{\"i\":[[0.177,0.07],[-0.231,-0.409],[-0.156,0.435]],\"o\":[[-0.177,-0.07],[0.231,0.409],[0.156,-0.435]],\"v\":[[-103.403,0.392],[-103.769,1.144],[-103.156,0.999]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 38\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.5,4.25],[-3.75,-9],[-2.75,-6.75],[-4.25,3.75],[0,0],[-2,10.25],[10.75,-2]],\"o\":[[-4.108,-1.838],[3.75,9],[2.75,6.75],[4.25,-3.75],[0,0],[2,-10.25],[-10.75,2]],\"v\":[[-3.25,-137.75],[-13.75,-121.75],[1.75,-100.5],[18,-91.5],[29,-107.5],[39,-118.5],[17.75,-135.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[22.75,-5.5],[0,0],[10.5,-18.5],[0,0],[-13,-24.25],[0,0],[-8,-6.75],[0,0],[-8,-0.25],[-9,0],[-6.25,-7.5],[-0.75,24.25],[0,0],[-3.75,9],[13.75,7.25],[4.75,3.5],[0,0],[-3.25,3.5],[0,0],[-3.25,8.75]],\"o\":[[-22.75,5.5],[0,0],[-10.5,18.5],[0,0],[13,24.25],[0,0],[8,6.75],[0,0],[8,0.25],[9,0],[6.25,7.5],[0.75,-24.25],[0,0],[3.75,-9],[-13.75,-7.25],[-4.75,-3.5],[0,0],[3.25,-3.5],[0,0],[3.25,-8.75]],\"v\":[[-169.75,-138.25],[-197.25,-118.5],[-212.5,-103.5],[-213.5,-68.75],[-219,-29.75],[-191.5,-20],[-188,-8],[-170,-3.25],[-158.75,2.75],[-137.75,-5.5],[-127.25,-5],[-105.25,-26],[-135.25,-61.25],[-126,-71.75],[-135,-105.75],[-154.5,-105.25],[-166.25,-107],[-157,-110.5],[-154,-118.25],[-134.75,-129.25]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10,5.75],[4,-7.5],[-13.5,-6.25],[-6.25,-2],[-7.75,3.25],[5.5,7],[4.25,-4.75],[0,0],[0,1.75],[0,0]],\"o\":[[-10,-5.75],[-4,7.5],[13.5,6.25],[6.25,2],[7.75,-3.25],[-5.5,-7],[-4.25,4.75],[0,0],[0,-1.75],[0,0]],\"v\":[[-68,-162.75],[-87,-154],[-79.5,-124.75],[-52.75,-123],[-32.25,-128.25],[-31,-147.25],[-48.75,-147.5],[-54.25,-139.75],[-54,-146],[-62.75,-151]],\"c\":true}},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[5.75,3.5],[-1.25,-13.5],[0,0],[4.5,-9.75],[-5,-2.75],[-4.5,10.75],[-4,6],[0.5,8.5]],\"o\":[[-5.75,-3.5],[1.25,13.5],[0,0],[-1.977,4.283],[5,2.75],[4.5,-10.75],[4,-6],[-0.5,-8.5]],\"v\":[[199.5,-52.75],[182.25,-35.75],[190.75,-18],[174.75,2],[174.75,22.25],[199.25,8.25],[200.75,-12.5],[208,-33.75]],\"c\":true}},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[16.25,6.75],[8.5,-13.25],[-7.5,-1],[0,0],[-2.5,-3.25],[0,0],[2.75,-9.25],[-10.75,3],[-2.75,14.25]],\"o\":[[-16.25,-6.75],[-8.5,13.25],[7.5,1],[0,0],[2.5,3.25],[0,0],[-2.75,9.25],[10.75,-3],[2.75,-14.25]],\"v\":[[163.25,-98.75],[124,-91.5],[139,-69.75],[152.75,-68],[152.5,-60.25],[159.25,-56.5],[144.5,-48.25],[158.75,-34.25],[180.5,-58]],\"c\":true}},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[18,5.5],[0,0],[5.75,0.25],[-7.25,-7.5],[-9,-1.5],[0,0],[-6.75,-1.75],[0,0],[0,-10.5],[-17.75,8],[0,0],[6.5,27.25],[0,0]],\"o\":[[-18,-5.5],[0,0],[-5.75,-0.25],[7.25,7.5],[9,1.5],[0,0],[6.75,1.75],[0,0],[0,10.5],[17.75,-8],[0,0],[-6.5,-27.25],[0,0]],\"v\":[[164.75,-171.5],[142.5,-162.75],[132.75,-168],[129.5,-153.5],[155,-140.75],[180.25,-137.5],[194.25,-126],[204.25,-122.5],[193,-85.5],[215,-65.5],[219,-91.25],[232.25,-129.25],[186.25,-152.25]],\"c\":true}},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.75,1.75],[0,0],[7.5,0.75],[3,-12.25],[-16.75,1.75],[-7.606,-2.48],[1.25,11.75]],\"o\":[[-17.527,-2.61],[0,0],[-5.855,-0.586],[-3.154,12.879],[16.75,-1.75],[11.5,3.75],[-0.954,-8.963]],\"v\":[[103.5,-145.75],[86.5,-129.75],[71.25,-138],[51.75,-125],[75,-107],[95.5,-115.25],[120,-128.25]],\"c\":true}},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 39\",\"np\":7,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.125,0.5],[-5.125,-1.625]],\"o\":[[-8.125,-0.5],[6.076,1.926]],\"v\":[[-91.625,-69.375],[-94.25,-62.5]],\"c\":true}],\"e\":[{\"i\":[[-0.375,-0.023],[0.237,0.075]],\"o\":[[0.375,0.023],[-0.28,-0.089]],\"v\":[[-91.625,-65.033],[-91.504,-65.35]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 27\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[8.25,-0.25],[-2.75,-10.5],[-2.125,6.25]],\"o\":[[-8.25,0.25],[2.75,10.5],[2.125,-6.25]],\"v\":[[-87.875,-94.125],[-98.25,-78.125],[-76.25,-80.625]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-87.562,-81],[-87.562,-81],[-87.562,-81]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 28\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4,-0.375],[-3.5,-5.125],[-0.625,4.5]],\"o\":[[-4,0.375],[3.5,5.125],[0.625,-4.5]],\"v\":[[-3.25,137.625],[-8.125,148],[4.125,143.25]],\"c\":true}],\"e\":[{\"i\":[[-0.092,0.009],[0.08,0.117],[0.014,-0.103]],\"o\":[[0.092,-0.009],[-0.08,-0.117],[-0.014,0.103]],\"v\":[[-3.442,145.361],[-3.33,145.123],[-3.611,145.232]],\"c\":true}]},{\"t\":29}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":26,\"s\":[0,0],\"h\":1},{\"t\":27,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 26\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.506,2.794],[2.343,-6.218],[-5.137,0.09],[-0.541,3.424]],\"o\":[[-4.506,-2.794],[-2.343,6.218],[5.137,-0.09],[0.541,-3.424]],\"v\":[[-25.506,127.416],[-38.032,130.119],[-29.471,141.384],[-21.631,137.509]],\"c\":true}],\"e\":[{\"i\":[[-0.029,-0.018],[-0.015,0.04],[0.033,-0.001],[0.003,-0.022]],\"o\":[[0.029,0.018],[0.015,-0.04],[-0.033,0.001],[-0.003,0.022]],\"v\":[[-30.721,132.722],[-30.64,132.704],[-30.695,132.631],[-30.746,132.656]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 24\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[4.75,-1.625],[3.625,2],[-1,-3.625],[-1.212,0.387],[-1.56,-1.97],[-4.625,5.875],[1.75,2]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.343,1.244],[2.318,-0.74],[2.375,3],[4.625,-5.875],[-1.75,-2]],\"v\":[[-6.25,134.625],[-15.875,144.875],[-21,149.25],[-18.483,150.129],[-11.375,149.125],[5.125,147.625],[5,134.875]],\"c\":true}],\"e\":[{\"i\":[[4.75,-1.625],[3.625,2],[-0.625,-2.625],[-1.142,0.534],[-2.013,-0.633],[-5.5,-0.625],[0.923,5.539]],\"o\":[[-4.75,1.625],[-3.625,-2],[0.177,0.742],[1.405,-0.656],[4.375,1.375],[3.107,0.353],[-0.75,-4.5]],\"v\":[[-5.125,140.125],[-13.375,145.375],[-19.125,147.375],[-16.356,148.417],[-12,146.375],[-3,150.75],[3.75,144.375]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":24,\"s\":[0,0],\"h\":1},{\"t\":25,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 25\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.125,0.625],[-2.5,-2.5]],\"o\":[[-2.125,-0.625],[2.5,2.5]],\"v\":[[-79.625,43.625],[-81.125,46.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-80.562,46.125],[-80.562,46.125]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":23,\"s\":[0,0],\"h\":1}],\"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 14\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,2.25],[-2.25,-1.75]],\"o\":[[-4.25,-2.25],[2.25,1.75]],\"v\":[[-45.75,26.5],[-48.25,32]],\"c\":true}],\"e\":[{\"i\":[[0.236,0.125],[-0.125,-0.097]],\"o\":[[-0.236,-0.125],[0.125,0.097]],\"v\":[[-45.986,28.861],[-46.125,29.167]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 13\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3,-1.25],[-3,-5],[-7.75,1.75],[2,4.75]],\"o\":[[-3,1.25],[3,5],[7.75,-1.75],[-2,-4.75]],\"v\":[[-46.5,-2.25],[-52.5,8.25],[-39.75,18],[-31.5,2.5]],\"c\":true}],\"e\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.842,-0.553],[-0.386,-1.929],[-2.614,0.59],[0.675,1.602]],\"o\":[[-1.686,0.506],[0.337,1.686],[2.614,-0.59],[-0.675,-1.602]],\"v\":[[-43.192,4.663],[-45.258,9.006],[-40.704,11.536],[-38.175,6.223]],\"c\":true}],\"e\":[{\"i\":[[-0.024,0.007],[0.005,0.025],[0.034,-0.008],[-0.009,-0.021]],\"o\":[[0.022,-0.007],[-0.004,-0.022],[-0.034,0.008],[0.009,0.021]],\"v\":[[-41.551,8.163],[-41.524,8.107],[-41.583,8.074],[-41.616,8.143]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 12\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,3],[0,-5.75],[-2.75,2.5]],\"o\":[[-4.25,-3],[0,5.75],[2.75,-2.5]],\"v\":[[121.75,-3.75],[113.5,0.75],[127.75,4.5]],\"c\":true}],\"e\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[1.179,0.832],[0,-1.595],[-0.763,0.693]],\"o\":[[-1.179,-0.832],[0,1.595],[0.763,-0.693]],\"v\":[[121.735,-1.671],[118.875,0.027],[122.237,1.31]],\"c\":true}],\"e\":[{\"i\":[[0.033,0.023],[0,-0.044],[-0.021,0.019]],\"o\":[[-0.033,-0.023],[0,0.044],[0.021,-0.019]],\"v\":[[120.96,-0.289],[120.88,-0.242],[120.974,-0.207]],\"c\":true}]},{\"t\":26}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":26,\"s\":[0,0],\"h\":1}],\"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 11\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.5,-3.75],[0,0],[-4.5,-10.75],[-4,6.75],[7,7.5]],\"o\":[[-4.5,3.75],[0,0],[4.5,10.75],[4,-6.75],[-7,-7.5]],\"v\":[[75,14],[73.5,24],[70,39.25],[96.5,37.5],[94.75,14.5]],\"c\":true}],\"e\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[1.484,-1.237],[0,0],[-1.505,-2.803],[-1.319,2.226],[2.309,2.473]],\"o\":[[-1.484,1.237],[0,0],[1.818,3.386],[1.319,-2.226],[-2.309,-2.473]],\"v\":[[84.241,20.409],[82.344,23.254],[82.942,28.469],[91.331,28.159],[90.754,20.574]],\"c\":true}],\"e\":[{\"i\":[[0.032,-0.026],[0,0],[-0.032,-0.06],[-0.028,0.048],[0.049,0.053]],\"o\":[[-0.032,0.026],[0,0],[0.039,0.072],[0.028,-0.048],[-0.049,-0.053]],\"v\":[[87.186,24.88],[87.145,24.941],[87.158,25.053],[87.337,25.046],[87.325,24.884]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 10\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,1.25],[0,-5.75],[-5.75,8.5]],\"o\":[[-4.25,-1.25],[0,5.75],[5.75,-8.5]],\"v\":[[55.25,97.75],[44.25,114],[57.25,114]],\"c\":true}],\"e\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[1.545,0.455],[0,-2.091],[-2.091,3.091]],\"o\":[[-1.545,-0.455],[0,2.091],[2.091,-3.091]],\"v\":[[53.693,107.614],[49.875,110.523],[54.784,112.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[53.375,111.25],[53.375,111.25],[53.375,111.25]],\"c\":true}]},{\"t\":25}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 15\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4.25,-3.5],[-2.75,-8.75],[-8.25,-0.25],[4.75,14.75]],\"o\":[[-4.25,3.5],[2.75,8.75],[8.25,0.25],[-4.75,-14.75]],\"v\":[[-38.75,60],[-44.25,76.25],[-23.25,92.75],[-6.5,67]],\"c\":true}],\"e\":[{\"i\":[[0.07,-0.058],[-0.046,-0.145],[-0.137,-0.004],[0.079,0.244]],\"o\":[[-0.07,0.058],[0.046,0.145],[0.137,0.004],[-0.079,-0.244]],\"v\":[[-24.613,72.416],[-24.704,72.685],[-24.356,72.959],[-24.079,72.532]],\"c\":true}]},{\"t\":28}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 16\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[10,-2.5],[-7.25,-12.5],[-2.25,7]],\"o\":[[-10,2.5],[7.25,12.5],[2.25,-7]],\"v\":[[-78.25,74.5],[-88.75,93],[-67,89.75]],\"c\":true}],\"e\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.72,-0.921],[-3.422,-4.605],[-1.062,2.579]],\"o\":[[-4.72,0.921],[3.422,4.605],[1.062,-2.579]],\"v\":[[-90.642,72.171],[-93.828,78.895],[-83.562,77.697]],\"c\":true}],\"e\":[{\"i\":[[-0.08,0.016],[0.058,0.078],[0.018,-0.044]],\"o\":[[0.08,-0.016],[-0.058,-0.078],[-0.018,0.044]],\"v\":[[-98.362,72.463],[-98.308,72.349],[-98.482,72.37]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 17\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[2.5,3],[-3.5,-5]],\"o\":[[-2.5,-3],[3.5,5]],\"v\":[[-119.5,57],[-124,63.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-122.25,61.125],[-122.25,61.125]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 18\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[9.5,-2.75],[2.5,-5],[0,0],[-7.25,-6.75],[-2,3.5],[0,0],[4,11]],\"o\":[[-9.5,2.75],[-2.5,5],[0,0],[7.25,6.75],[2,-3.5],[0,0],[-4,-11]],\"v\":[[-88.25,-97.75],[-104.5,-86.75],[-104.25,-71.5],[-104,-54],[-77,-59.5],[-76,-71.75],[-65.75,-92.5]],\"c\":true}],\"e\":[{\"i\":[[7.293,-2.111],[1.244,-4.107],[0,0],[-5.566,-5.182],[-1.293,4.188],[0,0],[3.071,8.444]],\"o\":[[-7.293,2.111],[-2.682,8.857],[0,0],[5.566,5.182],[2.519,-8.159],[0,0],[-3.071,-8.444]],\"v\":[[-90.843,-93.802],[-100.568,-86.607],[-95.626,-73.15],[-94.684,-64.466],[-82.707,-65.938],[-86.189,-72.842],[-76.821,-86.021]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 19\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[3.967,1.543],[1.763,-7.714],[-2.94,1.96],[-6.391,2.204],[1.543,3.526],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-1.763,7.714],[6.612,-4.408],[2.668,-0.92],[-1.543,-3.526],[-0.441,-6.391]],\"v\":[[-11,-75.637],[-25.987,-66.38],[-13.645,-56.021],[-2.184,-52.275],[4.207,-59.107],[-5.049,-66.16]],\"c\":true}],\"e\":[{\"i\":[[3.967,1.543],[2.081,-7.714],[-4.12,1.96],[-6.467,-1.97],[2.293,4.357],[0.13,1.879]],\"o\":[[-3.967,-1.543],[-2.081,7.714],[7.176,-3.414],[4.184,1.275],[-1.792,-3.406],[-0.441,-6.391]],\"v\":[[-9,-74.887],[-20.737,-69.38],[-10.395,-61.021],[-3.684,-56.025],[0.957,-62.107],[-4.549,-65.16]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 20\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[5.342,-0.929],[0.697,-7.896],[-9.754,4.645],[1.858,4.877]],\"o\":[[-5.342,0.929],[-0.697,7.896],[9.754,-4.645],[-1.858,-4.877]],\"v\":[[-151.777,-175.317],[-171.053,-161.846],[-149.686,-159.291],[-134.358,-173.923]],\"c\":true}],\"e\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[2.392,-0.416],[0.312,-3.536],[-4.368,2.08],[0.832,2.184]],\"o\":[[-2.392,0.416],[-0.312,3.536],[4.368,-2.08],[-0.832,-2.184]],\"v\":[[-152.182,-170.891],[-157.12,-165.082],[-149.118,-160.915],[-145.948,-168.028]],\"c\":true}],\"e\":[{\"i\":[[0.034,-0.006],[0.004,-0.051],[-0.063,0.03],[0.012,0.031]],\"o\":[[-0.034,0.006],[-0.004,0.051],[0.063,-0.03],[-0.012,-0.031]],\"v\":[[-151.107,-165.155],[-151.177,-165.071],[-151.063,-165.011],[-151.017,-165.113]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":28,\"s\":[0,0],\"h\":1}],\"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 21\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[4,-1.5],[-3,-8.25],[-4,-4.25],[0,0],[-4.25,-1.5],[0,0],[-12.5,8.75],[1.75,4],[15.25,-3.5],[0,0],[0,2.75],[0,0],[2.75,4.25]],\"o\":[[-4.521,1.695],[3,8.25],[4,4.25],[0,0],[4.25,1.5],[0,0],[12.5,-8.75],[-1.75,-4],[-15.25,3.5],[0,0],[0,-2.75],[0,0],[-2.75,-4.25]],\"v\":[[-46,102.5],[-47,128.25],[-35.5,146.25],[-26,150.5],[-15,160.5],[-5.75,156.75],[17.25,151.5],[34.75,132],[13,122.25],[-7.25,130.75],[-13.75,125.25],[-19.25,118.75],[-29.75,108.25]],\"c\":true}],\"e\":[{\"i\":[[1.993,-1.84],[-1.905,-5.238],[-3.64,-0.695],[0,0],[-2.699,-0.952],[0,0],[-9.612,4.283],[0.773,2.662],[9.683,-2.222],[0,0],[0.478,1.68],[0,0],[5.489,2.259]],\"o\":[[-3.975,3.671],[1.905,5.238],[3.728,0.712],[0,0],[2.699,0.952],[0,0],[8.85,-3.944],[-1.501,-5.17],[-9.683,2.222],[0,0],[-1.685,-5.922],[0,0],[-2.972,-1.223]],\"v\":[[-39.001,120.963],[-41.876,136.567],[-30.654,145.384],[-24.249,146.403],[-21.183,152.192],[-13.817,149.998],[0.041,151.703],[8.727,139.881],[-4.524,133.503],[-14.769,142.26],[-16.097,133.355],[-19.963,125.496],[-27.75,120.322]],\"c\":true}]},{\"t\":24}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":25,\"s\":[0,0],\"h\":1}],\"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 22\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[15,-6],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[3.5,1.75],[4.25,2.75],[0,0],[-1.5,14],[0,0],[3.5,17.25],[0,0],[-7,3.25],[0,0],[-3.5,0],[0,0],[-7.75,-0.75],[0,0],[-7.75,-5],[0,0],[-9,-1.5],[0.75,-2.5],[-6,1.75],[-8.25,0.75],[0,0],[-10.75,8.5],[0,0],[-2.25,3],[-3.5,-4.25],[-8,2.25],[-9,-4.5],[0,0],[13.75,3.5],[6.75,-10.75],[-9.25,-8.25],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-3.5,7.25],[0,0],[2.75,-8.25],[12.25,-5.25],[0,0],[6.5,-5],[4,-1.5],[4.5,-9.25],[-5.25,-1.25],[-4,5.5],[0,0],[-4.25,5.25],[0,0],[-24.5,19.75],[0,6.75],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[3.75,-1],[0,0],[7.25,1],[0,0],[3,-6],[0,0],[5,-1.25],[0,0],[5,1.25],[0,0],[7.25,4],[0,0],[4.75,4.5],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-15,6],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[-3.5,-1.75],[-4.25,-2.75],[0,0],[1.5,-14],[0,0],[-3.5,-17.25],[0,0],[7,-3.25],[0,0],[3.5,0],[0,0],[7.75,0.75],[0,0],[7.75,5],[0,0],[9,1.5],[-0.75,2.5],[6,-1.75],[8.25,-0.75],[0,0],[10.75,-8.5],[0,0],[2.25,-3],[3.5,4.25],[8,-2.25],[9,4.5],[0,0],[-13.75,-3.5],[-6.75,10.75],[9.25,8.25],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[3.5,-7.25],[0,0],[-2.75,8.25],[-12.25,5.25],[0,0],[-6.5,5],[-4,1.5],[-4.5,9.25],[5.25,1.25],[4,-5.5],[0,0],[4.25,-5.25],[0,0],[24.5,-19.75],[0,-6.75],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-3.75,1],[0,0],[-7.25,-1],[0,0],[-3,6],[0,0],[-5,1.25],[0,0],[-5,-1.25],[0,0],[-7.25,-4],[0,0],[-4.75,-4.5],[0,0]],\"v\":[[-71.75,-184],[-104.5,-167],[-132.75,-157],[-141.75,-147.5],[-191,-134],[-209.5,-120.75],[-230.25,-101],[-231.25,-77.75],[-234.5,-26.5],[-200.25,11.5],[-171.25,22.25],[-154.25,27.25],[-150.25,49],[-124.5,54.75],[-142,32.25],[-123.75,32.5],[-100,41.5],[-100,33.25],[-111.5,22],[-116.25,14.75],[-105,-11.5],[-113.5,-43.75],[-112,-88.5],[-126.5,-111.75],[-114.25,-118],[-109.25,-131.75],[-101.5,-134.5],[-96.25,-137.75],[-75,-130],[-54,-125.5],[-47.5,-110.25],[-30.5,-105.75],[-17.25,-93.75],[-4.5,-84.5],[10.5,-85],[34.25,-85],[51.75,-89.75],[71,-92.5],[87,-106.25],[107.5,-111.25],[120.25,-110.5],[141,-104.5],[164.5,-106.5],[174.75,-87.75],[157.5,-99.75],[112.5,-94],[114.25,-62],[134.5,-48.5],[129,-36],[123.25,-19.25],[130.75,-5.5],[146.75,-18.75],[162.5,-33.5],[169.5,-45.75],[176.25,-22.75],[149.5,-4.25],[127.75,20.75],[110,31.5],[90,51.25],[70,73.75],[66,92],[108,69.25],[116,51],[136.5,46.75],[140,31.75],[182.75,18.5],[204.75,-20.25],[204.75,-46],[222.25,-67.75],[230,-86],[239.25,-114.5],[218.75,-141],[199.25,-148.5],[171.5,-176.75],[145.25,-176.75],[130,-176.75],[120.25,-165.25],[100.25,-163.75],[87.75,-159.75],[66,-157.25],[67.25,-142.25],[44.5,-126.75],[28,-126],[15.5,-131.5],[3.75,-132.75],[-4.25,-139.75],[-10.75,-139.75],[-23,-156.5],[-41.75,-163.75]],\"c\":true}],\"e\":[{\"i\":[[20.5,1],[0,0],[7,-5],[0,0],[23.666,-4.733],[0,0],[5.75,-12.25],[0,0],[-11,-30],[0,0],[-8.75,0],[0,0],[-9.25,-9.5],[-5,10.75],[0,0],[-4,1],[-7,0.75],[-5.753,-0.846],[-3.456,-2.925],[0,0],[1.106,18.528],[0,0],[3.5,17.25],[0,0],[-3.451,6.903],[3.486,4.183],[-8.825,5.711],[0,0],[-16.259,-12.646],[0,0],[-8,1.75],[0,0],[-6.965,-5.894],[-3.973,-8.513],[-6,-2],[-5.96,5.754],[0,0],[-13.621,1.513],[0,0],[-10.021,4.432],[0.095,5.505],[-4.5,0],[-42.5,-3],[0,0],[13.324,4.877],[6.75,-10.75],[-33.25,-3.5],[0,0],[-2.25,-7.75],[4.25,-3.5],[-9.75,-1],[0,0],[-11,4],[0,0],[-3.25,-10.25],[12.25,-5.25],[0,0],[11.302,-9.247],[4,-1.5],[4.5,-9.25],[-9.5,-6],[-4.5,16.75],[0,0],[-10.5,11.25],[0,0],[-24.5,19.75],[2.75,9.25],[0,0],[-6.25,11.75],[0,0],[1.75,18],[7,4.5],[0,0],[12.75,5.75],[0,0],[11.616,-4.937],[0,0],[7.25,1],[0,0],[5.447,-3.915],[0,0],[11.597,-4.481],[0,0],[10.556,4.59],[0,0],[9.25,-0.75],[0,0],[15.169,11.507],[0,0]],\"o\":[[-20.5,-1],[0,0],[-7,5],[0,0],[-35,7],[0,0],[-5.75,12.25],[0,0],[11,30],[0,0],[8.75,0],[0,0],[9.25,9.5],[5,-10.75],[0,0],[4,-1],[7,-0.75],[8.5,1.25],[6.5,5.5],[9.25,-0.25],[-2,-33.5],[0,0],[-3.5,-17.25],[0,0],[4.75,-9.5],[0,0],[8.5,-5.5],[0,0],[4.5,3.5],[0,0],[9.01,-1.971],[0,0],[9.75,8.25],[3.5,7.5],[5.929,1.976],[7.25,-7],[0,0],[13.5,-1.5],[0,0],[13,-5.75],[-0.25,-14.5],[8.31,0],[38.666,2.729],[0,0],[-28,-10.25],[-6.75,10.75],[12.326,1.298],[0,0],[2.25,7.75],[-4.25,3.5],[9.75,1],[0,0],[7.566,-2.751],[0,0],[2.628,8.29],[-12.25,5.25],[0,0],[-11,9],[-4,1.5],[-4.5,9.25],[4.563,2.882],[0.598,-2.226],[0,0],[11.75,-12.589],[0,0],[24.5,-19.75],[-5.632,-18.945],[0,0],[6.25,-11.75],[0,0],[-1.75,-18],[-7,-4.5],[0,0],[-12.75,-5.75],[0,0],[-10,4.25],[0,0],[-7.25,-1],[0,0],[-8,5.75],[0,0],[-11,4.25],[0,0],[-11.5,-5],[0,0],[-8.253,0.669],[0,0],[-14.5,-11],[0,0]],\"v\":[[-83.75,-180],[-106.5,-171],[-126.25,-164],[-135.25,-146.5],[-164.5,-144.5],[-202,-120.75],[-220.75,-106],[-216.75,-74.25],[-227.5,-34],[-194.25,-8],[-173.75,2.75],[-154.25,21.25],[-148.75,44],[-131,50.75],[-148,20.25],[-149.75,2],[-140,1.5],[-132.5,5.25],[-122.5,5],[-104.25,14.25],[-91,-8.5],[-123.5,-62.25],[-121.5,-95.5],[-144,-115.75],[-131.75,-121.5],[-126.25,-136.75],[-105.5,-137.5],[-91.75,-152.25],[-83.5,-123.5],[-68,-117.5],[-47.5,-118.25],[-20.5,-132.25],[-12.25,-114.25],[-1,-97],[14,-83],[29.75,-101.5],[45.75,-114.25],[71,-101],[93.5,-105.25],[114,-111.25],[122.25,-128.5],[127.5,-147.5],[173.5,-133],[185.25,-81.25],[164.5,-102.25],[118,-91],[145.25,-64.5],[142.5,-51.5],[139,-35.5],[130.75,-23.25],[137.25,-11.5],[145.75,-28.25],[169,-33.5],[181,-56.25],[179.25,-25.25],[168,3.75],[145.75,30.25],[127,39.5],[114.5,60.75],[84.5,62.75],[85.5,84],[113.5,68.25],[115,68],[142.5,57.75],[149,34.75],[191.75,18.5],[210.75,-34.75],[199.25,-56],[224.25,-60.75],[225.5,-92.5],[236.75,-118],[220.25,-147],[188.75,-156.5],[169,-173.75],[140.25,-167.75],[127,-169.75],[121.25,-157.25],[106.75,-156.75],[106.25,-156.75],[88.5,-152.75],[83.25,-137.75],[59.5,-139.25],[46.5,-119],[31.5,-134],[12.75,-138.75],[-4.25,-139.75],[-18.25,-134.75],[-30.5,-154],[-51.75,-154.25]],\"c\":true}]},{\"t\":23}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":20,\"s\":[0,0],\"h\":1},{\"t\":21,\"s\":[100,100],\"h\":1},{\"t\":24,\"s\":[0,0],\"h\":1}],\"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 23\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.75,2.5],[2.75,-6.625],[-6.375,0],[-2.875,6.25]],\"o\":[[-3.75,-2.5],[-2.75,6.625],[6.375,0],[2.875,-6.25]],\"v\":[[61.125,-3.375],[45.375,4.375],[45.875,20.625],[61.375,9.375]],\"c\":true}],\"e\":[{\"i\":[[0.499,0.333],[0.366,-0.881],[-0.848,0],[-0.382,0.831]],\"o\":[[-0.499,-0.333],[-0.366,0.881],[0.848,0],[0.382,-0.831]],\"v\":[[49.836,-0.797],[47.741,-0.199],[48.339,1.63],[50.368,0.799]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":15,\"s\":[0,0],\"h\":1},{\"t\":16,\"s\":[100,100],\"h\":1},{\"t\":20,\"s\":[0,0],\"h\":1}],\"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 9\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[18.934,5.164],[12.016,-5.06],[0,0],[7.451,1.765],[5.645,-0.226],[8.945,-6.665],[0,0],[3.262,5.811],[4.317,4.176],[8.725,3.611],[3.199,1.087],[3.063,0.78],[3.171,0.415],[1.81,-0.109],[0,0],[1.157,0.458],[3.871,0.977],[29.142,-11.922],[4.627,-7.197],[0.375,-1.333],[0,0],[13,-29.5],[0,0],[-23,-39],[0,0],[-16,-9],[-7.135,-0.67],[-1.267,-0.023],[0,0],[-0.432,-0.986],[-0.407,-0.855],[-0.265,-0.527],[-0.148,-0.286],[-1.643,-2.364],[-1.437,-1.437],[-3.036,-1.535],[-0.155,-0.076],[-0.051,-0.025],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-30,23],[0,0],[-20,9.5],[0,0],[-7,12],[-0.795,3.115],[-0.216,2.726],[0.096,1.897],[0,0],[-29.425,54.272],[0,0],[-3.315,6.41],[4.925,18.605],[0,0],[6.451,10.777]],\"o\":[[-22.018,-6.005],[-8.995,3.788],[0,0],[-4.31,-1.021],[-8.324,0.333],[-25.5,19],[0,0],[-2.036,-3.627],[-4.834,-4.676],[-3.662,-1.515],[-3.671,-1.247],[-4.464,-1.138],[-4.901,-0.642],[-1.06,0.064],[0,0],[-1.686,-0.668],[-12.803,-3.233],[-26.494,10.838],[-1.791,2.785],[-0.265,0.943],[0,0],[-13,29.5],[0,0],[23,39],[0,0],[9.867,5.55],[2.536,0.238],[0.949,0.017],[0,0],[0.264,0.602],[0.224,0.471],[0.137,0.273],[1.119,2.164],[1.214,1.747],[5.421,5.421],[0.248,0.125],[0.075,0.037],[0.045,0.022],[0,0],[0,0],[8,12],[0,0],[12.5,5],[0,0],[30,-23],[0,0],[20,-9.5],[0,0],[1.684,-2.887],[0.783,-3.067],[0.263,-3.309],[-0.078,-1.551],[0,0],[22.5,-41.5],[0,0],[4.007,-7.746],[-9,-34],[0,0],[-6.242,-10.429]],\"v\":[[164.5,-192],[111.719,-188.32],[97.5,-180.5],[85.228,-184.887],[70.084,-186.417],[43.5,-177],[18,-143.5],[13.904,-153.572],[4.567,-165.607],[-15.5,-178.5],[-25.791,-182.386],[-35.892,-185.402],[-47.344,-187.652],[-57.41,-188.155],[-59,-188],[-60.761,-188.751],[-69.176,-191.415],[-135,-185.5],[-177.205,-156.264],[-180.194,-149.959],[-180.5,-148.5],[-230.5,-120],[-236,-60.5],[-227,9],[-170.5,50],[-138,87],[-109.8,95.157],[-103.974,95.496],[-102.5,95.5],[-101.838,97.075],[-100.828,99.282],[-100.095,100.783],[-99.667,101.622],[-95.49,108.635],[-91.5,113.5],[-73.449,125.529],[-72.842,125.833],[-72.654,125.925],[-72.548,125.977],[-72.5,126],[-70,157],[-44,176.5],[-28.5,196.5],[-1.5,193.5],[47.5,178.5],[72,132.5],[116.5,127],[132.5,101],[170.5,81],[174.143,71.85],[175.569,63.021],[175.689,54.963],[175.5,52.5],[245.5,6],[237.5,-64.5],[244.608,-73.882],[247,-113],[208.5,-144.5],[200.629,-164.834]],\"c\":true}],\"e\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[18.934,5.164],[6.416,-5.76],[0,0],[6.842,-0.377],[5.751,-1.079],[11.401,-4.911],[0,0],[9.8,-0.851],[7.11,2.469],[6.318,9.929],[3.369,2.539],[4.885,2.011],[7.562,1.448],[6.526,0.268],[0,0],[1.008,0.421],[3.284,0.946],[21.632,-8.941],[3.142,-9.123],[0.141,-1.798],[0,0],[13,-29.5],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.822,2.767],[2.023,2.613],[0,0],[-7.19,-1.373],[-2.135,-1.396],[0.387,-0.947],[0.749,-0.54],[-1.022,-6.216],[-0.909,-1.565],[-5.057,-0.356],[-0.259,-0.01],[-0.085,-0.002],[0,0],[0,0],[-8,-12],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-20,9.5],[0,0],[-19.035,15.618],[-3.716,4.066],[-2.62,3.517],[-1.499,2.426],[0,0],[-27.024,42.787],[0,0],[-7.354,10.112],[4.925,18.605],[0,0],[6.07,8.237]],\"o\":[[-22.018,-6.005],[-4.803,4.312],[0,0],[-3.958,0.218],[-8.48,1.591],[-29.206,12.581],[0,0],[-6.118,0.531],[-7.962,-2.764],[-2.127,-3.343],[-3.867,-2.914],[-7.121,-2.931],[-11.687,-2.238],[-3.822,-0.157],[0,0],[-1.469,-0.614],[-10.862,-3.128],[-22.58,9.333],[-1.216,3.531],[-0.1,1.272],[0,0],[-13,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[2.268,-2.224],[-1.514,-1.956],[0,0],[4.389,0.838],[1.176,0.769],[-0.201,0.491],[-10.38,7.485],[0.755,4.595],[7.506,12.927],[0.413,0.029],[0.125,0.005],[0.075,0.002],[0,0],[0,0],[5,7.5],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[20,-9.5],[0,0],[4.691,-3.849],[3.659,-4.003],[3.18,-4.268],[1.226,-1.984],[0,0],[12,-19],[0,0],[8.888,-12.221],[-9,-34],[0,0],[-5.873,-7.971]],\"v\":[[160.5,-192],[119.861,-186.802],[113.5,-178],[102.767,-178.131],[88.113,-176.321],[58,-167],[44,-140.5],[27.067,-136.592],[6.683,-138.859],[-15.5,-157],[-23.854,-165.795],[-37.147,-173.14],[-59.681,-179.579],[-88.888,-182.861],[-95,-183],[-96.543,-183.685],[-103.769,-186.191],[-156,-183.5],[-190.162,-151.723],[-191.941,-143.492],[-192,-141.5],[-230.5,-112],[-234,-68],[-221,10],[-151.5,48.5],[-130.5,71.5],[-103.759,74.765],[-105.39,66.4],[-108.5,63],[-93.605,65.02],[-82.883,68.363],[-81.543,70.935],[-82.946,72.481],[-93.788,94.263],[-90,104],[-61.585,119.429],[-60.573,119.485],[-60.257,119.496],[-60.08,119.499],[-60,119.5],[-54.5,145],[-42.5,158.5],[-26,176],[-2,173],[27.5,165.5],[52,134.5],[84.5,127.5],[102.5,105],[140,89.5],[152.636,77.446],[162.078,65.994],[169.138,55.645],[171,52.5],[217,11],[227,-35.5],[241.837,-51.967],[254.5,-100.5],[203,-154.5],[195.897,-169.71]],\"c\":true}],\"e\":[{\"i\":[[8.864,2.813],[7.079,-1.354],[0,0],[13.094,-1.21],[-0.018,-0.843],[5.661,-2.668],[0,0],[17.71,1.266],[12.336,3.848],[0.25,0.75],[9.83,8.017],[0.562,0.657],[25.725,4.726],[9.831,-6.216],[0,0],[-3.032,3.853],[0.747,8.445],[15.471,-6.395],[-7.536,-6.601],[-7.961,-1.468],[0,0],[21.655,-23.881],[0,0],[-32.528,-31.495],[0,0],[-15.405,-9.985],[-2.08,3.361],[7.074,6.982],[0,0],[-14.244,-1.531],[-5.859,-7.626],[1.287,-2.776],[3.373,-0.392],[0.886,-6.879],[-1.961,-1.267],[-3.784,12.826],[-2.09,4.283],[-1.499,-0.451],[-0.354,-4.451],[0,0],[-12.5,-20.75],[0,0],[-12.5,-5],[0,0],[-22.449,15.501],[0,0],[-6.505,6.505],[0,0],[-20.995,16.055],[-8.207,7.28],[-0.548,0.003],[-6.236,1.925],[0,0],[-27.024,42.787],[0,0],[-9.085,17.825],[3.883,14.669],[0,0],[8.143,11.01]],\"o\":[[-13.759,-4.366],[-19.726,3.772],[0,0],[-8.945,0.827],[-0.018,-0.593],[-21.75,10.25],[0,0],[0.019,-0.088],[-13.81,-4.307],[0,-0.25],[-11.414,-9.308],[-0.688,-0.593],[-15.588,-2.864],[-11.425,7.224],[0,0],[3.287,-4.177],[-0.537,-6.071],[-17.147,7.088],[5.403,4.732],[6.094,1.124],[0,0],[-26.75,29.5],[0,0],[31.5,30.5],[0,0],[11.224,7.275],[1.698,-2.743],[-5.053,-4.987],[0,0],[12.035,1.294],[4.522,5.885],[-0.856,1.846],[-10.422,1.211],[-1.075,8.345],[12,7.75],[0.432,-1.463],[1.255,-2.571],[3.219,0.968],[0.518,6.518],[0,0],[8.593,14.264],[0,0],[12.5,5],[0,0],[21,-14.5],[0,0],[6.5,-6.5],[0,0],[6.447,-4.93],[7.537,-6.685],[1.977,-0.948],[9.61,-2.967],[0,0],[12,-19],[0,0],[6.894,-13.526],[-9,-34],[0,0],[-4.511,-6.1]],\"v\":[[166,-182],[142.226,-178.772],[118.5,-165.75],[104.445,-167.327],[90.018,-161.407],[69.5,-161.5],[61.75,-141],[32.731,-125.412],[11.06,-137.943],[-10.25,-140],[-20.586,-156.942],[-42.062,-164.657],[-72.225,-184.726],[-105.941,-167.407],[-135.75,-154],[-143.677,-157.193],[-127.997,-171.695],[-157.25,-175],[-173.153,-153.482],[-148.789,-155.532],[-149,-149.25],[-215.5,-124.5],[-231.25,-78.25],[-217.75,-1.25],[-155,30],[-140.25,62],[-112.259,65.765],[-115.824,47.268],[-128.5,39],[-102.285,44.956],[-77.909,55.814],[-69.342,69.609],[-76.446,71.481],[-95.214,83.819],[-87.5,98.25],[-64.716,90.174],[-64.128,77.554],[-56.682,75.116],[-49.105,84.318],[-52.5,97.5],[-46,142.75],[-29,152.25],[-20.5,164.5],[-4,161.25],[18.5,154.5],[42,124],[58,116.25],[59.5,98.75],[93,83.75],[108.207,71.72],[123.048,55.997],[136.065,57.709],[151.75,42.25],[204,5.75],[209.5,-42.75],[227.03,-63.49],[244.75,-108.75],[200.25,-150],[181.607,-169.76]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[-28,-15.25],[0,0],[-15.75,9.5],[0,0],[-10.5,-4.25],[0,0],[-0.25,-4.75],[0,0],[6,0],[0,0],[10.25,-9.5],[-1.75,-8],[0,0],[10.25,-0.75],[0,0],[2,10.5],[0,0],[17.75,4.5],[5,-3.5],[0,0],[2.5,4],[0,0],[-0.75,7.5],[-4.25,8.75]],\"o\":[[0,0],[28,15.25],[0,0],[15.75,-9.5],[0,0],[10.5,4.25],[0,0],[0.25,4.75],[0,0],[-6,0],[0,0],[-10.25,9.5],[1.75,8],[0,0],[-10.25,0.75],[0,0],[-2,-10.5],[0,0],[-17.75,-4.5],[-5,3.5],[0,0],[-2.5,-4],[0,0],[0.75,-7.5],[4.25,-8.75]],\"v\":[[-50.5,-75.25],[-29.75,-39.75],[19.25,-34.75],[50.75,-41.75],[69,-59.75],[91,-37.75],[107,-23.75],[99.75,-11.75],[99.75,1.25],[84.75,-4.75],[76,-0.25],[55.25,0.5],[42,23],[45,39.5],[19,35.25],[-10.25,39],[-9,14.75],[-18.25,-1.5],[-32.25,-27.5],[-63.25,-21.75],[-71.25,-6.25],[-73.5,-14.75],[-83,-20.25],[-66.5,-33.75],[-62.25,-65.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.074,0.04],[0,0],[0.041,-0.025],[0,0],[0.028,0.011],[0,0],[0.001,0.012],[0,0],[-0.016,0],[0,0],[-0.027,0.025],[0.005,0.021],[0,0],[-0.027,0.002],[0,0],[-0.005,-0.028],[0,0],[-0.047,-0.012],[-0.013,0.009],[0,0],[-0.007,-0.011],[0,0],[0.002,-0.02],[0.011,-0.023]],\"o\":[[0,0],[-0.074,-0.04],[0,0],[-0.041,0.025],[0,0],[-0.028,-0.011],[0,0],[-0.001,-0.012],[0,0],[0.016,0],[0,0],[0.027,-0.025],[-0.005,-0.021],[0,0],[0.027,-0.002],[0,0],[0.005,0.028],[0,0],[0.047,0.012],[0.013,-0.009],[0,0],[0.007,0.011],[0,0],[-0.002,0.02],[-0.011,0.023]],\"v\":[[12.164,-17.724],[12.11,-17.817],[11.981,-17.831],[11.898,-17.812],[11.85,-17.765],[11.792,-17.823],[11.75,-17.86],[11.769,-17.891],[11.769,-17.925],[11.809,-17.91],[11.832,-17.921],[11.886,-17.923],[11.921,-17.983],[11.913,-18.026],[11.982,-18.015],[12.059,-18.025],[12.055,-17.961],[12.08,-17.918],[12.116,-17.85],[12.198,-17.865],[12.219,-17.906],[12.225,-17.883],[12.25,-17.869],[12.207,-17.833],[12.195,-17.75]],\"c\":true}]},{\"t\":15}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.125,0.057],[0,0],[0.038,-0.016],[0,0],[0.063,-0.035],[0,0],[0.061,0.023],[0,0.05],[-0.003,0.025],[0,0],[-0.031,0.004],[0,0],[-0.05,0.025],[-0.01,0.057],[0,0],[0.019,0.048],[0,0],[-0.02,0.051],[0,0],[-0.023,-0.034],[0,0],[0.009,-0.101],[-0.038,0.016],[0,0],[-0.02,-0.019],[0,0],[-0.023,-0.047],[0,0],[-0.128,0.007],[0.003,0.025],[0,0],[-0.034,-0.034],[0,0],[0.023,-0.09],[0.028,-0.051]],\"o\":[[0,0],[-0.125,-0.057],[0,0],[-0.038,0.016],[0,0],[-0.063,0.035],[0,0],[-0.061,-0.023],[0,-0.05],[0.003,-0.025],[0,0],[0.031,-0.004],[0,0],[0.05,-0.025],[0.01,-0.057],[0,0],[-0.019,-0.048],[0,0],[0.02,-0.051],[0,0],[0.023,0.034],[0,0],[-0.009,0.101],[0.038,-0.016],[0,0],[0.02,0.019],[0,0],[0.023,0.047],[0,0],[0.128,-0.007],[-0.003,-0.025],[0,0],[0.034,0.034],[0,0],[-0.023,0.09],[-0.028,0.051]],\"v\":[[10.723,4.496],[10.612,4.271],[10.433,4.229],[10.313,4.238],[10.272,4.29],[10.125,4.315],[10.008,4.395],[9.924,4.296],[9.791,4.147],[9.848,4.052],[9.857,4.001],[9.965,4.025],[10.049,3.991],[10.096,4.034],[10.198,3.937],[10.14,3.873],[10.166,3.78],[10.11,3.706],[10.186,3.612],[10.239,3.5],[10.262,3.579],[10.317,3.614],[10.183,3.708],[10.38,3.802],[10.459,3.77],[10.479,3.809],[10.529,3.832],[10.527,3.971],[10.573,4.06],[10.699,4.128],[10.841,4.044],[10.832,4],[10.877,4.079],[10.959,4.13],[10.826,4.268],[10.787,4.449]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-21.5,-9.75],[0,0],[-6.5,2.75],[0,0],[-10.75,6],[0,0],[-10.5,-4],[0,-8.5],[0.5,-4.25],[0,0],[5.25,-0.75],[0,0],[8.5,-4.25],[1.75,-9.75],[0,0],[-3.25,-8.25],[0,0],[3.5,-8.75],[0,0],[4,5.75],[0,0],[-1.5,17.25],[6.5,-2.75],[0,0],[3.5,3.25],[0,0],[4,8],[0,0],[22,-1.25],[-0.5,-4.25],[0,0],[5.75,5.75],[0,0],[-4,15.5],[-4.75,8.75]],\"o\":[[0,0],[21.5,9.75],[0,0],[6.5,-2.75],[0,0],[10.75,-6],[0,0],[10.5,4],[0,8.5],[-0.5,4.25],[0,0],[-5.25,0.75],[0,0],[-8.5,4.25],[-1.75,9.75],[0,0],[3.25,8.25],[0,0],[-3.5,8.75],[0,0],[-4,-5.75],[0,0],[1.5,-17.25],[-6.5,2.75],[0,0],[-3.5,-3.25],[0,0],[-4,-8],[0,0],[-22,1.25],[0.5,4.25],[0,0],[-5.75,-5.75],[0,0],[4,-15.5],[4.75,-8.75]],\"v\":[[-49.25,-81],[-30.25,-42.5],[0.5,-35.25],[21,-36.75],[28,-45.75],[53.25,-50],[73.25,-63.75],[87.75,-46.75],[110.5,-21.25],[100.75,-5],[99.25,3.75],[80.75,-0.25],[66.25,5.5],[58.25,-1.75],[40.75,14.75],[50.75,25.75],[46.25,41.75],[55.75,54.5],[42.75,70.5],[33.75,89.75],[29.75,76.25],[20.25,70.25],[43.25,54],[9.5,38],[-4,43.5],[-7.5,36.75],[-16,32.75],[-15.75,9],[-23.5,-6.25],[-45.25,-18],[-69.5,-3.5],[-68,4],[-75.75,-9.5],[-89.75,-18.25],[-67,-42],[-60.25,-73]],\"c\":true}],\"e\":[{\"i\":[[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,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]],\"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],[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]],\"v\":[[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4],[10.375,4]],\"c\":true}]},{\"t\":16}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0.022,0.041],[0,0],[-0.044,0.022],[0,0],[0.015,-0.081]],\"o\":[[0,0],[-0.022,-0.041],[0,0],[0.044,-0.022],[0,0],[-0.015,0.081]],\"v\":[[-66.087,51.996],[-66.157,51.959],[-66.25,51.904],[-66.168,51.885],[-66.083,51.8],[-66.106,51.881]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[-0.268,3.095],[0,0],[-3.271,-1.106],[0,0],[2.477,-1.696]],\"o\":[[0,0],[0.322,-3.724],[0,0],[3.846,1.3],[0,0],[-4.367,2.991]],\"v\":[[-52.807,47.871],[-51.557,41.947],[-51.627,35.74],[-46.996,39.762],[-42,41.413],[-47.769,43.453]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-60.325,47.041],[-58.321,37.533],[-58.432,27.571],[-50.999,34.025],[-48.481,36.676],[-52.24,39.949]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-0.429,4.967],[0,0],[-5.251,-1.775],[0,0],[3.975,-2.722]],\"o\":[[0,0],[0.517,-5.977],[0,0],[6.174,2.087],[0,0],[-7.01,4.801]],\"v\":[[-61.825,52.541],[-60.821,37.533],[-65.057,14.946],[-50.437,27.9],[-45.231,35.426],[-50.24,42.199]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.004,-0.043],[0,0],[0.045,0.015],[0,0],[-0.034,0.023]],\"o\":[[0,0],[-0.004,0.052],[0,0],[-0.053,-0.018],[0,0],[0.061,-0.041]],\"v\":[[-54.598,33.581],[-54.607,33.711],[-54.571,33.906],[-54.697,33.794],[-54.742,33.729],[-54.698,33.67]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[-0.005,-0.001],[-0.001,0.001],[0,0],[0.001,-0.002],[-0.023,-0.015],[0,0],[-0.005,0.008],[0,0.002],[0,0],[-0.003,0],[-0.007,0.006],[-0.004,0.003],[0,0],[-0.013,-0.005],[0,0],[-0.004,-0.006],[0,0],[0.005,-0.009],[0,-0.003],[0,0],[0.001,0],[0.004,0],[0.009,-0.004],[0,0.006],[0.002,-0.004],[0.005,-0.01],[-0.003,-0.004],[0,0],[0.002,-0.006],[0,0],[0.004,-0.006],[0.001,-0.002],[0,0],[0,-0.001],[0,-0.001],[0,0],[0,0],[0,0],[0,0],[0.002,0.006],[0,0],[0.001,0.01],[0.007,-0.001],[0,0],[0.005,0.001],[0.002,0],[0,0],[0.011,0.017],[0.013,0],[0,0],[0.001,-0.006],[0,0],[0,0],[0.007,0.006],[0,0],[0.003,0.005],[0,0],[-0.003,0.011],[0,0],[-0.003,0.009]],\"o\":[[0,0],[0.004,0.001],[0,0],[0,0],[-0.003,0.008],[0.03,0.019],[0,0],[0.004,-0.005],[0,-0.001],[0,0],[0.008,-0.001],[0.005,-0.004],[0.003,-0.003],[0,0],[0.013,0.005],[0,0],[0.004,0.006],[0,0],[-0.002,0.004],[0,0.003],[0,0],[-0.002,0],[-0.008,-0.001],[-0.016,0.006],[0,-0.006],[-0.002,0.004],[-0.005,0.01],[0.003,0.004],[0,0],[-0.002,0.006],[0,0],[-0.001,0.002],[0,0],[0,0.001],[-0.001,0.001],[0,0],[0,0],[0,0],[0,0],[0.001,-0.004],[-0.003,-0.008],[0,0],[-0.001,-0.01],[-0.007,0.001],[0,0],[-0.004,-0.001],[-0.001,0],[0,0],[-0.011,-0.017],[-0.013,0],[0,0],[-0.001,0.006],[0,0],[-0.002,-0.003],[-0.008,-0.007],[0,0],[-0.003,-0.005],[0,0],[0.003,-0.011],[0,0],[0.003,-0.009]],\"v\":[[9.302,5.518],[9.307,5.522],[9.313,5.52],[9.314,5.52],[9.312,5.523],[9.33,5.564],[9.367,5.573],[9.388,5.572],[9.393,5.561],[9.393,5.559],[9.397,5.559],[9.43,5.551],[9.444,5.539],[9.449,5.534],[9.467,5.558],[9.489,5.572],[9.493,5.589],[9.5,5.591],[9.487,5.608],[9.484,5.618],[9.484,5.623],[9.483,5.623],[9.475,5.622],[9.446,5.625],[9.436,5.626],[9.418,5.64],[9.425,5.65],[9.425,5.67],[9.433,5.678],[9.419,5.695],[9.417,5.709],[9.408,5.717],[9.404,5.723],[9.404,5.725],[9.402,5.727],[9.401,5.73],[9.401,5.731],[9.4,5.732],[9.4,5.731],[9.401,5.73],[9.401,5.71],[9.393,5.695],[9.404,5.677],[9.38,5.667],[9.365,5.671],[9.358,5.664],[9.345,5.663],[9.345,5.663],[9.338,5.62],[9.305,5.602],[9.292,5.614],[9.285,5.622],[9.291,5.642],[9.291,5.641],[9.277,5.621],[9.263,5.613],[9.258,5.599],[9.25,5.588],[9.277,5.575],[9.283,5.553],[9.294,5.531]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[-4.25,-0.75],[-0.843,0.613],[0,0],[0.688,-1.923],[-19.802,-12.497],[0,0],[-4.25,6.5],[-0.187,1.717],[0,0],[-2.329,0.17],[-5.821,4.882],[-3.246,2.834],[0,0],[-10.75,-4],[0,0],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.188,-2.261],[0,0],[0.789,0.125],[3.044,0.231],[7.808,-3.241],[0.25,5],[2,-3.25],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[3.25,-5.5],[0.885,-1.723],[0.198,-0.396],[0.331,-0.686],[0.28,-0.607],[0.082,-0.181],[0,0],[-0.053,0.207],[-0.096,0.41],[2.001,5.203],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[4,1],[1.901,-0.033],[0,0],[9.25,14.75],[11,0],[0,0],[1.25,-4.75],[0,0],[0.223,0.41],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-2.25,9.75],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,0.53],[0.349,-0.254],[0,0],[-2.29,6.404],[25.75,16.25],[0,0],[2.998,-4.586],[0.078,-0.717],[0,0],[7.03,-0.513],[4.266,-3.578],[2.651,-2.315],[0,0],[10.75,4],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-0.24,2.882],[0,0],[-1.374,-0.217],[-6.879,-0.523],[-13.25,5.5],[-0.25,-5],[-2,3.25],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.019,1.724],[-0.212,0.413],[-0.401,0.8],[-0.469,0.973],[-0.138,0.298],[-0.107,0.236],[0,0],[0.056,-0.217],[0.751,-3.212],[-2.5,-6.5],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-3.255,-0.814],[-0.435,0.008],[0,0],[-9.25,-14.75],[-11,0],[0,0],[-1.25,4.75],[0,0],[-1.36,-2.496],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[2.25,-9.75],[0,0],[2.25,-8]],\"v\":[[-53.25,-85.25],[-49,-82.5],[-43.27,-83.553],[-42.75,-84],[-44.091,-80.956],[-29.25,-46.75],[2.25,-38.75],[20.75,-39.5],[24.694,-49.393],[24.75,-50.5],[28.55,-50.716],[56.25,-57.75],[68.331,-68.119],[72.75,-72],[87.5,-51.5],[106.5,-40],[109.75,-25.5],[116,-23.25],[105.25,-9.25],[102.362,-0.609],[102.75,4],[101.522,3.791],[94.667,3.003],[70,5.75],[61,6.75],[46,18.75],[51.75,26.75],[51.75,44],[58.5,50.5],[46.5,65.5],[45,77.25],[37.25,84.25],[34.352,89.544],[33.736,90.759],[32.633,93.002],[31.495,95.412],[31.164,96.136],[31,96.5],[31.084,96.181],[31.317,95.231],[31.75,78.25],[24.5,65.25],[34.5,50.25],[14,41.5],[1.25,45.25],[-5.25,38.5],[-15.814,37.734],[-16.5,37.75],[-22.5,1.75],[-50,-14.25],[-61.5,-3.75],[-67.5,3.25],[-62,19.75],[-62.343,19.111],[-74.5,2.25],[-86.25,-4.5],[-90.5,-16.5],[-97.25,-25.75],[-74,-36.75],[-69.25,-55.75],[-59.5,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[-3.814,-2.019],[-2.308,-0.576],[0,0],[1.301,-0.987],[-16.162,-16.944],[0,0],[-4.25,6.5],[0.986,1.424],[0,0],[-1.938,0.158],[-12.309,3.868],[-3.854,4.494],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[1.379,-3.832],[0,0],[0.723,0.087],[2.824,0.105],[7.808,-3.241],[0,5.006],[-1.893,-3.313],[4.5,-8.75],[-2.5,-3.75],[0,0],[1.75,-5.25],[0,0],[1.514,-6.207],[3.1,-3.231],[0.765,-0.629],[1.482,-0.771],[1.455,-0.382],[0.451,-0.079],[0,0],[-0.254,0.143],[-0.487,0.32],[-1.001,16.409],[0,0],[0.5,8.5],[5.75,-1.25],[0,0],[12.25,3.25],[2.318,-1.301],[0,0],[1.804,17.317],[11,0],[0,0],[3.234,-3.696],[0,0],[0.358,0.393],[5.583,5.154],[0,0],[2.75,4.25],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[3.006,1.591],[0.955,0.238],[0,0],[-4.333,3.285],[15.5,16.25],[0,0],[2.998,-4.586],[-0.412,-0.594],[0,0],[5.849,-0.478],[9.633,-3.027],[3.147,-3.67],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.978,3.407],[-1.758,4.884],[0,0],[-1.257,-0.151],[-6.38,-0.238],[-13.25,5.5],[0,-12.5],[1,1.75],[-4.5,8.75],[2.5,3.75],[0,0],[-1.75,5.25],[0,0],[-1.567,6.426],[-0.743,0.775],[-1.548,1.273],[-2.101,1.093],[-0.715,0.188],[-0.587,0.103],[0,0],[0.266,-0.15],[3.812,-2.508],[0.424,-6.951],[0,0],[-0.5,-8.5],[-5.75,1.25],[0,0],[-11.349,-3.011],[-0.53,0.298],[0,0],[-1.25,-12],[-11,0],[0,0],[-5.25,6],[0,0],[-2.179,-2.392],[-6.5,-6],[0,0],[-2.75,-4.25],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-52.5,-93],[-45,-87.75],[-35.305,-84.367],[-33.75,-84],[-36.066,-82.548],[-31.75,-53.25],[-10,-45.5],[19.25,-45.5],[20.03,-54.602],[19.25,-55.5],[22.31,-55.711],[53.75,-61.5],[73.688,-74.7],[78.25,-81.25],[83,-57],[105.75,-46.5],[112.75,-33.5],[123.75,-24.75],[110.5,-15],[105.357,-3.387],[102.5,5.5],[101.379,5.352],[95.06,4.87],[71.5,8.25],[59.25,6.75],[47.25,15],[58.25,20.5],[56,39.5],[62.75,49.75],[49.25,66],[46.75,77.25],[39.25,86.25],[31.788,100.466],[29.519,102.568],[24.922,105.603],[19.436,107.729],[17.67,108.118],[16.75,108.25],[17.144,108.038],[18.288,107.336],[32.75,80.5],[22.5,65],[29.5,50],[10.25,43.5],[1.25,45.25],[-7.25,35.25],[-28.199,36.755],[-29,37.25],[-25.75,8.75],[-49,-7.25],[-58.5,-0.75],[-63.25,4],[-59.062,21.5],[-59.618,20.888],[-75.5,4.5],[-91.25,-4],[-94.5,-16.5],[-103,-31.75],[-78,-40.25],[-70.5,-58.25],[-61.25,-74.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[-4.312,0.172],[-4.558,-0.427],[0,0],[2.609,-1.261],[-14.133,-16.979],[0,0],[-4.25,6.5],[1.388,3.536],[0,0],[-3.054,-0.484],[-11.412,3.587],[-4.924,7.451],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[0.138,-3.881],[0,0],[2.182,-1.714],[1.585,0.443],[8.872,-2.494],[4,0],[-1.272,-3.62],[0.333,-5.417],[-3.667,-4.417],[0,0],[2.206,-5.024],[0,0],[2.114,-5.958],[2.068,-2.201],[1.689,0.801],[3.047,-0.168],[3.356,0.331],[2.326,1.502],[0,0],[-0.08,0.818],[-0.881,-0.296],[-4.919,12.187],[0,0],[0.5,8.5],[5.833,0.75],[0,0],[12.25,3.25],[3.1,2.013],[0,0],[1.804,17.317],[11,0],[0,0],[1.797,-4.062],[0,0],[2.804,-1.117],[7.405,7.992],[0,0],[4.072,8.101],[0,0],[-8.75,8.5],[0,0],[-2.25,8]],\"o\":[[0,0],[6.25,-0.25],[2.513,0.186],[0,0],[-6.129,3.313],[12.5,14.5],[0,0],[2.852,-4.362],[-0.757,-2.104],[0,0],[6.402,0.52],[9.086,-2.855],[4.472,-6.937],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.908,3.286],[0.037,5.307],[0,0],[-3.412,2.582],[-2.687,-2.126],[-5,0.333],[-5.25,-1.25],[1.083,3.083],[0.083,5.833],[2.751,3.539],[0,0],[-3.667,7.167],[0,0],[-1.955,5.784],[-0.495,0.523],[-2.522,-0.694],[-3.642,0.353],[-2.092,-0.271],[-3.794,-2.543],[0,0],[0.08,-0.889],[5.088,0.661],[2.51,-5.288],[0,0],[-0.5,-8.5],[-5.371,-0.384],[0,0],[-10.716,-2.843],[-1.005,-1.009],[0,0],[-1.25,-12],[-11,0],[0,0],[-2.75,7.333],[0,0],[-4.66,0.129],[-6.187,-6.293],[0,0],[-4.667,-9.5],[0,0],[7.177,-6.972],[0,0],[2.25,-8]],\"v\":[[-53.75,-88],[-46.75,-97.5],[-34.703,-90.426],[-26.167,-84.583],[-29.438,-81.706],[-30.25,-54.667],[-9.667,-47.917],[16.083,-48.333],[14.56,-60.056],[14.5,-63.667],[18.724,-60.778],[52.417,-66.333],[75.647,-80.838],[88.083,-88.417],[87.5,-60.333],[108.75,-48.333],[117.75,-35.5],[124.917,-24.75],[111.667,-14],[106.729,-1.018],[110.167,7.333],[105.032,9.676],[96.616,15.794],[78,8.667],[65,10.25],[58.917,19.167],[57.167,28.417],[61.583,41.833],[73.167,47.5],[55.25,65.75],[49.833,82.583],[40.917,92.417],[34.44,107.441],[30.083,110.408],[21.443,109.93],[9.836,113.394],[3.395,108.505],[-3.333,104.667],[-3.857,102.426],[-1.271,101.224],[17,85],[13.917,71.5],[20.083,57.917],[4.333,48.667],[-5.417,49.25],[-15.083,40.917],[-32.688,35.373],[-31.75,31.583],[-27.25,7.583],[-48.083,-6.583],[-58.5,-0.75],[-61.917,5.333],[-55.812,19.083],[-57.644,23.304],[-81.083,14.167],[-96.75,3.667],[-97.833,-17.417],[-106,-40.25],[-81.583,-41.583],[-71,-62],[-62.667,-77.083]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-7.5,-3.25],[-8.083,-4.093],[0,0],[5.225,-1.81],[-10.076,-17.051],[0,0],[-4.25,6.5],[2.192,7.761],[0,0],[-5.285,-1.77],[-9.617,3.023],[-7.065,13.364],[0,0],[-8.994,-11.594],[-6.059,-1.01],[-3.25,-5.5],[0,0],[4.5,-7.75],[-2.345,-3.979],[0,0],[5.1,-5.315],[-0.891,1.119],[11,-1],[5.076,-2.343],[0.981,-0.196],[0.317,-9.834],[-6,-5.75],[0,0],[3.117,-4.572],[0,0],[3.315,-5.461],[0.004,-0.142],[3.538,3.662],[6.177,1.037],[7.159,1.756],[6.076,4.663],[0,0],[0.268,2.167],[-1.669,-1.529],[-12.757,3.744],[0,0],[0.5,8.5],[6,4.75],[0,0],[12.25,3.25],[4.665,8.641],[0,0],[1.804,17.317],[11,0],[0,0],[-1.078,-4.792],[0,0],[7.696,-4.137],[11.048,13.67],[0,0],[6.716,15.802],[0,0],[-8.75,8.5],[0,0],[-1.848,8.102]],\"o\":[[0,0],[2.721,1.179],[6.999,3.545],[0,0],[-9.722,3.368],[6.5,11],[0,0],[2.56,-3.915],[-1.447,-5.123],[0,0],[7.507,2.515],[7.991,-2.512],[7.121,-13.47],[0,0],[5.919,7.631],[0,0],[3.25,5.5],[0,0],[-1.767,3.043],[3.627,6.153],[0,0],[-7.721,8.046],[4.699,-5.902],[-14.287,1.299],[-3.25,1.5],[0.5,0.25],[-0.25,7.75],[3.254,3.118],[0,0],[-7.5,11],[0,0],[-2.732,4.499],[0.001,0.02],[-4.471,-4.629],[-6.724,-1.129],[-4.847,-1.189],[-10.206,-7.834],[0,0],[-0.293,-2.368],[7.64,6.999],[6.682,-1.961],[0,0],[-0.5,-8.5],[-4.614,-3.652],[0,0],[-9.452,-2.508],[-1.955,-3.621],[0,0],[-1.25,-12],[-11,0],[0,0],[2.25,10],[0,0],[-9.622,5.171],[-5.56,-6.88],[0,0],[-8.5,-20],[0,0],[7.177,-6.972],[0,0],[3.25,-14.25]],\"v\":[[-55.25,-99],[-38,-102.5],[-26.499,-92.295],[-11,-85.75],[-16.181,-80.022],[-27.25,-57.5],[-9,-52.75],[9.75,-54],[-3.88,-73.713],[3.25,-80.5],[12.303,-78.912],[49.75,-76],[79.565,-93.114],[107.75,-102.75],[96.5,-67],[114.75,-52],[127.75,-39.5],[127.25,-24.75],[114,-12],[109.472,3.722],[125.5,11],[112.338,18.324],[99.729,37.643],[91,9.5],[73.5,13.5],[70.25,20.75],[65.5,31.5],[72.75,46.5],[94,43],[67.25,65.25],[56,93.25],[44.25,104.75],[39.746,121.392],[31.212,126.088],[14.486,118.584],[-9.366,124.723],[-25.155,109.278],[-43.5,97.5],[-45.859,91.202],[-40.39,89.001],[-14.5,94],[-3.25,84.5],[1.25,73.75],[-7.5,59],[-18.75,57.25],[-30.75,52.25],[-41.665,32.609],[-37.25,20.25],[-30.25,5.25],[-46.25,-5.25],[-58.5,-0.75],[-59.25,8],[-49.313,14.25],[-53.696,28.137],[-92.25,33.5],[-107.75,19],[-104.5,-19.25],[-112,-57.25],[-88.75,-44.25],[-72,-69.5],[-65.5,-81.75]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.04,-0.009],[-0.019,-0.009],[0.026,-0.016],[0.026,-0.028],[0,0],[0.019,0.068]],\"o\":[[0.04,0.009],[0.019,0.009],[-0.026,0.016],[-0.026,0.028],[0,0],[-0.016,-0.058]],\"v\":[[-51.449,39.759],[-51.357,39.815],[-51.332,39.874],[-51.435,39.914],[-51.509,40],[-51.533,39.818]],\"c\":true}],\"e\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-5.75,-1.25],[-2.75,-1.25],[3.75,-2.25],[3.75,-4],[0,0],[2.75,9.75]],\"o\":[[5.75,1.25],[2.75,1.25],[-3.75,2.25],[-3.75,4],[0,0],[-2.356,-8.352]],\"v\":[[-52.25,25.5],[-39,33.5],[-35.5,42],[-50.25,47.75],[-60.75,60],[-64.25,34]],\"c\":true}],\"e\":[{\"i\":[[-5.84,0.724],[-2.429,-1.796],[2.794,-3.365],[2.214,-5.016],[0,0],[8.09,15.052]],\"o\":[[5.84,-0.724],[5.929,4.383],[-2.794,3.365],[-2.214,5.016],[0,0],[-4.108,-7.644]],\"v\":[[-62.831,35.704],[-44.679,38.617],[-41.313,54.729],[-46.827,64.288],[-57.43,67.573],[-72.59,55.198]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-0.104,-0.071],[0.086,0.038],[0.145,0.005],[0,0],[0.014,0.093],[0,0],[-0.123,0.023],[0,0]],\"o\":[[0.12,0.081],[-0.035,-0.016],[-0.145,-0.005],[0,0],[-0.014,-0.093],[0,0],[0.123,-0.023],[0,0]],\"v\":[[-82.663,-101.709],[-82.586,-101.615],[-82.846,-101.602],[-83.042,-101.565],[-83.224,-101.565],[-83.137,-101.671],[-82.993,-101.705],[-82.858,-101.698]],\"c\":true}],\"e\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-8.283,-5.625],[6.836,3.032],[11.536,0.42],[0,0],[1.094,7.441],[0,0],[-9.797,1.81],[0,0]],\"o\":[[9.527,6.469],[-2.826,-1.253],[-11.536,-0.42],[0,0],[-1.094,-7.441],[0,0],[9.797,-1.81],[0,0]],\"v\":[[-66.487,-108.275],[-60.336,-100.782],[-81.074,-99.751],[-96.682,-96.813],[-111.143,-96.792],[-104.211,-105.279],[-92.783,-107.968],[-82.001,-107.406]],\"c\":true}],\"e\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[-8.597,-5.095],[5.168,-6.734],[11.518,-0.29],[0,0],[1.547,7.345],[0,0],[-9.648,2.405],[0,0]],\"o\":[[9.889,5.86],[-3.163,7.623],[-11.518,0.29],[0,0],[-1.547,-7.345],[0,0],[9.648,-2.405],[0,0]],\"v\":[[-74.993,-115.637],[-54.293,-103.516],[-85.537,-99.626],[-104.216,-88.907],[-113.072,-100.146],[-114.98,-109.89],[-101.016,-113.484],[-90.5,-116.703]],\"c\":true}],\"e\":[{\"i\":[[-8.912,-4.564],[3.5,-16.5],[11.5,-1],[0,0],[2,7.25],[0,0],[-9.5,3],[0,0]],\"o\":[[10.25,5.25],[-3.5,16.5],[-11.5,1],[0,0],[-2,-7.25],[0,0],[9.5,-3],[0,0]],\"v\":[[-83.5,-123],[-54.25,-109.75],[-90,-99.5],[-111.75,-81],[-115,-103.5],[-125.75,-114.5],[-109.25,-119],[-99,-126]],\"c\":true}]},{\"t\":20}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[5.5,0],[-3.75,-7.75],[-5,5.25],[3.5,2]],\"o\":[[-5.5,0],[3.75,7.75],[5,-5.25],[-3.5,-2]],\"v\":[[64.25,-40.75],[59,-26.75],[76.25,-25.75],[74.25,-37.75]],\"c\":true}],\"e\":[{\"i\":[[-0.106,0],[0.072,0.149],[0.096,-0.101],[-0.067,-0.038]],\"o\":[[0.106,0],[-0.072,-0.149],[-0.096,0.101],[0.067,0.038]],\"v\":[[72.077,-31.166],[72.178,-31.435],[71.846,-31.454],[71.885,-31.224]],\"c\":true}]},{\"t\":18}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":13,\"s\":[0,0],\"h\":1},{\"t\":14,\"s\":[100,100],\"h\":1},{\"t\":21,\"s\":[0,0],\"h\":1}],\"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 8\",\"np\":8,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-40.51,7.147],[0,0],[-17.338,-13.577],[0,0],[-8.296,0],[0,0],[-26.663,15.973],[0,0],[-33.95,-10.778],[0,0],[-21.615,-37.512],[0,0],[8.98,-29.643],[0,0],[16.078,-18.847],[0,0],[19.91,-14.379],[0,0],[9.955,-9.125],[0,0],[16.722,-12.243],[0,0],[18.514,-5.056],[0,0],[9.125,-0.553],[0,0],[18.949,11.815],[0,0],[16.315,12.72],[0,0],[23.953,16.773],[0,0],[11.973,13.619],[0,0],[6.913,32.077],[0,0],[-4.701,15.209],[0,0],[-10.231,17.145],[0,0],[-9.402,7.743],[0,0]],\"o\":[[43.349,-7.648],[0,0],[17.031,13.336],[0,0],[3.739,0],[0,0],[17.54,-10.508],[0,0],[33.43,10.613],[0,0],[16.117,27.97],[0,0],[-7.619,25.151],[0,0],[-16.113,18.888],[0,0],[-19.91,14.379],[0,0],[-9.955,9.125],[0,0],[-16.624,12.172],[0,0],[-14.931,4.078],[0,0],[-9.125,0.553],[0,0],[-22.801,-14.217],[0,0],[-16.315,-12.72],[0,0],[-19.543,-13.685],[0,0],[-14.781,-16.813],[0,0],[-6.913,-32.077],[0,0],[4.701,-15.209],[0,0],[10.231,-17.145],[0,0],[9.402,-7.743],[0,0]],\"v\":[[-122.349,-200.852],[-67.036,-197.802],[-29.531,-189.336],[-8.428,-159.127],[5.686,-161.605],[12.864,-156.627],[42.96,-187.992],[81.916,-196.269],[137.57,-196.113],[183.871,-164.877],[232.883,-120.97],[241.361,-65.366],[240.52,-14.357],[219.652,17.144],[204.113,62.612],[179.151,78.022],[158.805,108.917],[131.471,116.361],[108.784,144.6],[82.14,158.301],[67.624,177.828],[43.385,190.688],[24.986,203.556],[3.47,204.704],[-15.345,210.947],[-32.448,201.14],[-56.949,189.685],[-78.783,151.211],[-100.318,142.161],[-117.198,116.933],[-155.953,98.227],[-179.067,65.84],[-206.973,51.381],[-217.527,16.527],[-241.967,-19.72],[-239.542,-62.358],[-241.872,-94.094],[-219.588,-110.856],[-217.027,-145.422],[-189.511,-163.714],[-181.673,-176.147],[-165.9,-178.912]],\"c\":true}],\"e\":[{\"i\":[[-41.027,10.852],[0,0],[-32.19,-17.46],[0,0],[-0.18,0.259],[0,0],[-27.898,13.394],[0,0],[-45.894,-13.697],[0,0],[-15.016,-36.577],[0,0],[5.71,-33.936],[0,0],[21.4,-13.403],[0,0],[17.976,-16.121],[0,0],[10.092,-8.239],[0,0],[19.309,-16.744],[0,0],[19.25,-9.223],[0,0],[12.239,3.847],[0,0],[15.375,17.378],[0,0],[11.519,13.671],[0,0],[24.516,15.038],[0,0],[12.163,12.071],[0,0],[6.597,28.03],[0,0],[-1.353,14.044],[0,0],[-16.709,12.856],[0,0],[-8.214,8.547],[0,0]],\"o\":[[44.248,-11.704],[0,0],[18.544,10.058],[0,0],[-0.18,0.259],[0,0],[18.352,-8.811],[0,0],[38.632,11.53],[0,0],[13.202,32.158],[0,0],[-3.833,22.781],[0,0],[-19.873,12.446],[0,0],[-19.185,17.206],[0,0],[-19.586,15.988],[0,0],[-11.367,9.857],[0,0],[-14.319,6.86],[0,0],[-20.345,-6.395],[0,0],[-17.652,-19.952],[0,0],[-13.005,-15.434],[0,0],[-20.002,-12.269],[0,0],[-15.015,-14.901],[0,0],[-6.597,-28.03],[0,0],[1.428,-14.823],[0,0],[14.517,-11.169],[0,0],[11.131,-11.582],[0,0]],\"v\":[[-115.248,-190.796],[-59.008,-190.107],[-10.81,-172.04],[19.517,-144.869],[19.18,-146.759],[19.528,-146.795],[54.253,-183.013],[96.25,-182.982],[162.394,-192.803],[206.803,-147.766],[248.798,-114.658],[238.601,-66.134],[250.833,-17.781],[241.164,16.728],[212.1,46.403],[176.142,53.42],[165.685,84.794],[131.081,97.874],[119.086,124.512],[72.746,132.43],[64.367,162.143],[42.534,175.875],[17.75,190.723],[-3.557,191.818],[-24.655,195.895],[-44.198,175.545],[-65.375,158.622],[-72.314,125.748],[-87.019,114.329],[-103.831,93.1],[-142.713,85.645],[-170.687,49.612],[-206.339,36.512],[-226.657,9.999],[-241.335,-25.987],[-238.074,-63.029],[-240.428,-90.677],[-234.051,-113.839],[-215.291,-138.856],[-184.468,-150.252],[-177.631,-164.918],[-158.245,-175.028]],\"c\":true}]},{\"t\":14}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[0,0],[3.25,0],[0,0],[-0.5,-7],[0,0],[-5.5,-1.25],[0,0],[-2.5,7.75],[0,0],[6,0],[0,0],[1.75,-2.75],[0.75,5.5]],\"o\":[[0,0],[-3.25,0],[0,0],[0.5,7],[0,0],[5.5,1.25],[0,0],[2.5,-7.75],[0,0],[-6,0],[0,0],[-1.75,2.75],[-0.75,-5.5]],\"v\":[[10.25,-12.5],[2.5,-9.25],[-3.25,-9],[0.25,6.25],[-1.5,20],[11.5,22.25],[20.75,27.75],[24.75,15],[41.75,-3],[30.75,-6.75],[20.75,-8.25],[21.5,1.25],[9,-1.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.108,0],[0,0],[0.017,0.197],[0,0],[0.183,0.035],[0,0],[0.083,-0.219],[0,0],[-0.2,0],[0,0],[-0.058,0.078],[-0.025,-0.155]],\"o\":[[0,0],[0.108,0],[0,0],[-0.017,-0.197],[0,0],[-0.183,-0.035],[0,0],[-0.083,0.219],[0,0],[0.2,0],[0,0],[0.058,-0.078],[0.025,0.155]],\"v\":[[19.55,8.193],[19.808,8.101],[20,8.094],[19.883,7.664],[19.942,7.276],[19.508,7.212],[19.2,7.057],[19.067,7.417],[18.5,7.925],[18.867,8.03],[19.2,8.073],[19.175,7.805],[19.592,7.882]],\"c\":true}]},{\"t\":10}]},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.064,0.03],[0.037,0.036],[0,0],[0.094,-0.005],[0,0],[0.034,-0.041],[0,0],[0.003,-0.023],[0,0],[-0.014,0],[0,0],[-0.057,0.03],[0,0],[-0.022,0.001],[0,0],[-0.007,-0.022]],\"o\":[[0.064,-0.03],[-0.037,-0.036],[0,0],[-0.094,0.005],[0,0],[-0.034,0.041],[0,0],[-0.003,0.023],[0,0],[0.014,0],[0,0],[0.057,-0.03],[0,0],[0.022,-0.001],[0,0],[0.007,0.022]],\"v\":[[15.686,3.128],[15.702,2.98],[15.653,2.842],[15.507,2.878],[15.377,2.865],[15.343,2.944],[15.269,2.975],[15.272,3.015],[15.25,3.072],[15.283,3.074],[15.344,3.115],[15.374,3.045],[15.463,3.052],[15.501,3.031],[15.54,3.041],[15.561,3.087]],\"c\":true}],\"e\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[11.75,-5.5],[-6.75,-6.5],[0,0],[-17.25,1],[0,0],[-6.25,7.5],[0,0],[-0.5,4.25],[0,0],[2.5,0],[0,0],[10.5,-5.5],[0,0],[4,-0.25],[0,0],[1.25,4]],\"o\":[[-11.75,5.5],[6.75,6.5],[0,0],[17.25,-1],[0,0],[6.25,-7.5],[0,0],[0.5,-4.25],[0,0],[-2.5,0],[0,0],[-10.5,5.5],[0,0],[-4,0.25],[0,0],[-1.25,-4]],\"v\":[[-17.25,-24.5],[-20.25,2.75],[-11.25,28],[15.5,21.25],[39.25,23.75],[45.5,9.25],[59,3.5],[58.5,-3.75],[62.5,-14.25],[56.5,-14.5],[45.25,-22],[39.75,-9.25],[23.5,-10.5],[16.5,-6.75],[9.5,-8.5],[5.5,-17]],\"c\":true}],\"e\":[{\"i\":[[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]],\"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]],\"v\":[[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14],[17,14]],\"c\":true}]},{\"t\":11}]},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":4,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.059,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.17],[0,0],[0.193,-0.003],[0,0],[0.094,-0.181],[0,0],[0.023,-0.059],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.059,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.17],[0,0],[-0.193,0.003],[0,0],[-0.094,0.182],[0,0],[-0.023,0.059],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.749],[28.945,-0.819],[29.012,-0.842],[28.992,-0.998],[29.214,-0.945],[29.346,-0.951],[29.434,-0.854],[29.583,-0.851],[29.697,-0.796],[29.706,-0.898],[29.75,-0.989],[29.607,-1.244],[29.601,-1.501],[29.279,-1.434],[28.971,-1.472],[28.901,-1.229],[28.582,-1.1],[28.523,-1.015],[28.5,-0.878],[28.775,-0.939]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[2.25,-1.25],[0,0],[9.25,-5.75],[0,0],[5,2.25],[0,0],[6.75,1.75],[0,0],[0.5,-2],[0,0],[-5.75,-14.5],[0,0],[-16.5,0.25],[0,0],[-8,15.5],[0,0],[-2,5],[0,0],[10.25,3.25]],\"o\":[[0,0],[-2.25,1.25],[0,0],[-9.25,5.75],[0,0],[-5,-2.25],[0,0],[-6.75,-1.75],[0,0],[-0.5,2],[0,0],[5.75,14.5],[0,0],[16.5,-0.25],[0,0],[8,-15.5],[0,0],[2,-5],[0,0],[-10.25,-3.25]],\"v\":[[50.5,-33.25],[44.5,-27.25],[38.75,-25.25],[40.5,-12],[21.5,-16.5],[10.25,-16],[2.75,-24.25],[-10,-24.5],[-19.75,-29.25],[-20.5,-20.5],[-24.25,-12.75],[-12,9],[-11.5,31],[16,25.25],[42.25,28.5],[48.25,7.75],[75.5,-3.25],[80.5,-10.5],[82.5,-22.25],[59,-17]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.026,0.015],[0,0],[-0.108,0.067],[0,0],[-0.058,-0.026],[0,0],[-0.079,-0.02],[0,0],[-0.006,0.023],[0,0],[0.067,0.169],[0,0],[0.193,-0.003],[0,0],[0.093,-0.181],[0,0],[0.023,-0.058],[0,0],[-0.12,-0.038]],\"o\":[[0,0],[0.026,-0.015],[0,0],[0.108,-0.067],[0,0],[0.058,0.026],[0,0],[0.079,0.02],[0,0],[0.006,-0.023],[0,0],[-0.067,-0.169],[0,0],[-0.193,0.003],[0,0],[-0.093,0.181],[0,0],[-0.023,0.058],[0,0],[0.12,0.038]],\"v\":[[28.875,-0.75],[28.946,-0.82],[29.013,-0.843],[28.992,-0.998],[29.214,-0.946],[29.345,-0.951],[29.433,-0.855],[29.582,-0.852],[29.696,-0.797],[29.704,-0.899],[29.748,-0.989],[29.605,-1.243],[29.599,-1.5],[29.278,-1.433],[28.972,-1.471],[28.902,-1.229],[28.584,-1.1],[28.525,-1.016],[28.502,-0.878],[28.776,-0.94]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 5\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":5,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.008,0.004],[0,0],[0.014,0.026],[-0.085,0.002],[0,0],[-0.017,0.014],[0,0],[-0.057,0.004],[0,0],[-0.053,-0.011],[0,0],[-0.001,0.014],[0,0],[0.033,0.05],[0,0],[0.033,0],[0,0],[0.115,-0.02],[0,0],[0,-0.02],[0,0],[-0.036,-0.017]],\"o\":[[0,0],[0.008,-0.004],[0,0],[-0.014,-0.026],[0.085,-0.002],[0,0],[0.017,-0.014],[0,0],[0.057,-0.004],[0,0],[0.053,0.011],[0,0],[0.001,-0.014],[0,0],[-0.033,-0.05],[0,0],[-0.033,0],[0,0],[-0.075,0.013],[0,0],[0,0.02],[0,0],[0.036,0.017]],\"v\":[[26.605,7.051],[26.632,7.031],[26.664,7.016],[26.567,6.967],[26.642,6.901],[26.718,6.986],[26.756,6.951],[26.803,6.935],[26.798,6.874],[26.844,6.92],[26.938,6.911],[27.037,6.945],[27.032,6.916],[27.044,6.884],[26.995,6.819],[26.969,6.667],[26.891,6.689],[26.783,6.666],[26.64,6.844],[26.501,6.807],[26.516,6.85],[26.501,6.926],[26.536,6.975]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1.75,-0.75],[0,0],[-3,-5.5],[17.75,-0.5],[0,0],[3.5,-3],[0,0],[12,-0.75],[0,0],[11,2.25],[0,0],[0.25,-3],[0,0],[-7,-10.5],[0,0],[-7,0],[0,0],[-24,4.25],[0,0],[0,4.25],[0,0],[7.5,3.5]],\"o\":[[0,0],[-1.75,0.75],[0,0],[3,5.5],[-17.75,0.5],[0,0],[-3.5,3],[0,0],[-12,0.75],[0,0],[-11,-2.25],[0,0],[-0.25,3],[0,0],[7,10.5],[0,0],[7,0],[0,0],[15.604,-2.763],[0,0],[0,-4.25],[0,0],[-7.5,-3.5]],\"v\":[[76,-50.5],[70.5,-46.25],[63.75,-43],[84,-32.75],[68.25,-19],[52.5,-36.75],[44.5,-29.5],[34.75,-26.25],[35.75,-13.5],[26,-23],[6.5,-21.25],[-14.25,-28.25],[-13.25,-22.25],[-15.75,-15.5],[-5.5,-2],[0,29.75],[16.25,25.25],[38.75,30],[68.75,-7.25],[97.75,0.5],[94.75,-8.5],[97.75,-24.25],[90.5,-34.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.003,0.001],[0,0],[0.005,0.009],[-0.029,0.001],[0,0],[-0.006,0.005],[0,0],[-0.02,0.001],[0,0],[-0.018,-0.004],[0,0],[0,0.005],[0,0],[0.011,0.017],[0,0],[0.011,0],[0,0],[0.039,-0.007],[0,0],[0,-0.007],[0,0],[-0.012,-0.006]],\"o\":[[0,0],[0.003,-0.001],[0,0],[-0.005,-0.009],[0.029,-0.001],[0,0],[0.006,-0.005],[0,0],[0.02,-0.001],[0,0],[0.018,0.004],[0,0],[0,-0.005],[0,0],[-0.011,-0.017],[0,0],[-0.011,0],[0,0],[-0.026,0.005],[0,0],[0,0.007],[0,0],[0.012,0.006]],\"v\":[[21.286,5.989],[21.295,5.982],[21.306,5.977],[21.273,5.96],[21.299,5.937],[21.324,5.966],[21.338,5.955],[21.353,5.949],[21.352,5.928],[21.368,5.944],[21.4,5.941],[21.434,5.953],[21.432,5.943],[21.436,5.932],[21.419,5.91],[21.41,5.858],[21.384,5.865],[21.347,5.857],[21.298,5.918],[21.25,5.906],[21.255,5.92],[21.25,5.946],[21.262,5.963]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 6\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":6,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[-0.005,0.026],[0,0],[0.02,0],[0,0],[-0.02,-0.025]],\"o\":[[0,0],[0.005,-0.026],[0,0],[-0.02,0],[0,0],[0.02,0.025]],\"v\":[[27.221,7.084],[27.23,7.031],[27.25,6.977],[27.211,6.996],[27.148,6.996],[27.199,7.032]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[1,-5.5],[0,0],[-4.25,0],[0,0],[4.25,5.25]],\"o\":[[0,0],[-1,5.5],[0,0],[4.25,0],[0,0],[-4.25,-5.25]],\"v\":[[-52.75,-57.25],[-54.5,-46.25],[-58.75,-35],[-50.5,-39],[-37.5,-39],[-48,-46.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-0.002,0.009],[0,0],[0.007,0],[0,0],[-0.007,-0.009]],\"o\":[[0,0],[0.002,-0.009],[0,0],[-0.007,0],[0,0],[0.007,0.009]],\"v\":[[21.497,6],[21.499,5.982],[21.506,5.964],[21.493,5.97],[21.472,5.97],[21.489,5.982]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 7\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":7,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[-0.003,0.012],[0,0],[0.022,0],[0.014,0.004],[0,0],[0.003,0.01],[0,0],[0.024,0],[0,0],[0.014,-0.007],[0.002,-0.008],[0.01,0],[0,0],[0.005,0],[0,0],[0,-0.004],[0,0],[-0.008,-0.008],[0,0],[-0.02,0.013],[0,0],[-0.031,-0.014]],\"o\":[[0,0],[0.003,-0.012],[0,0],[-0.022,0],[-0.014,-0.004],[0,0],[-0.003,-0.01],[0,0],[-0.024,0],[0,0],[-0.005,0.003],[-0.002,0.008],[-0.01,0],[0,0],[-0.005,0],[0,0],[0,0.004],[0,0],[0.008,0.008],[0,0],[0.02,-0.013],[0,0],[0.031,0.014]],\"v\":[[25.23,5.825],[25.239,5.785],[25.25,5.763],[25.219,5.77],[25.184,5.766],[25.175,5.744],[25.16,5.728],[25.156,5.675],[25.117,5.683],[25.085,5.675],[25.081,5.703],[25.071,5.72],[25.057,5.731],[25.039,5.727],[25.029,5.729],[25,5.727],[25.005,5.742],[25.006,5.77],[25.026,5.786],[25.049,5.806],[25.084,5.775],[25.132,5.769],[25.183,5.773]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.25,-8],[0,0],[-14.75,0],[-9.75,-2.5],[0,0],[-1.75,-6.75],[0,0],[-16.75,0],[0,0],[-9.75,4.75],[-1.5,5.75],[-7,0],[0,0],[-3.75,0],[0,0],[0,3],[0,0],[5.5,5.75],[0,0],[13.75,-9],[0,0],[21.25,9.5]],\"o\":[[0,0],[-2.25,8],[0,0],[14.75,0],[9.75,2.5],[0,0],[1.75,6.75],[0,0],[16.75,0],[0,0],[3.554,-1.731],[1.5,-5.75],[7,0],[0,0],[3.75,0],[0,0],[0,-3],[0,0],[-5.5,-5.75],[0,0],[-13.75,9],[0,0],[-21.25,-9.5]],\"v\":[[-56.25,-68.75],[-62.75,-41.25],[-70,-26.25],[-49,-31.25],[-24.5,-28.25],[-18.5,-13],[-8.5,-2.25],[-5.75,34.25],[21,28.75],[42.75,34],[45.5,14.75],[52.5,3.5],[62.5,-4.25],[74.25,-1.75],[81.5,-2.75],[101.25,-1.5],[98,-11.5],[97,-31],[83.5,-42],[68,-55.5],[44,-34.5],[10.5,-30.25],[-24.25,-33]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 10\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":8,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0.047,-0.026],[-0.06,-0.047],[0.011,0.108]],\"o\":[[-0.047,0.026],[0.06,0.047],[-0.011,-0.108]],\"v\":[[55.32,-24.341],[55.305,-24.172],[55.495,-24.267]],\"c\":true}],\"e\":[{\"i\":[[5.5,-3],[-7,-5.5],[1.25,12.5]],\"o\":[[-5.5,3],[7,5.5],[-1.25,-12.5]],\"v\":[[61,-42.5],[59.25,-23],[81.25,-34]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 9\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":9,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[-0.106,0.009],[0.124,0.008]],\"o\":[[0.106,-0.009],[-0.066,-0.004]],\"v\":[[39.106,-21.324],[39.124,-21.43]],\"c\":true}],\"e\":[{\"i\":[[6,-0.5],[-7.002,-0.467]],\"o\":[[-6,0.5],[3.75,0.25]],\"v\":[[33.75,-23.75],[32.75,-17.75]],\"c\":true}]},{\"t\":13}]},\"nm\":\"Path 8\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":10,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[-0.173,-0.02],[0.061,0.133],[0.041,-0.122]],\"o\":[[0.173,0.02],[-0.061,-0.133],[-0.041,0.122]],\"v\":[[15.411,-2.936],[15.564,-3.202],[15.166,-3.171]],\"c\":true}],\"e\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[4.25,0.5],[-1.5,-3.25],[-1,3]],\"o\":[[-4.25,-0.5],[1.5,3.25],[1,-3]],\"v\":[[14.75,-3.5],[11,3],[20.75,2.25]],\"c\":true}],\"e\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[2.384,0.28],[-0.841,-1.823],[-0.561,1.683]],\"o\":[[-2.384,-0.28],[0.841,1.823],[0.561,-1.683]],\"v\":[[15.134,-1.47],[13.03,2.177],[18.5,1.756]],\"c\":true}],\"e\":[{\"i\":[[0.726,0.085],[-0.256,-0.555],[-0.171,0.512]],\"o\":[[-0.726,-0.085],[0.256,0.555],[0.171,-0.512]],\"v\":[[15.476,0.335],[14.835,1.445],[16.5,1.317]],\"c\":true}]},{\"t\":12}]},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":8,\"s\":[0,0],\"h\":1},{\"t\":9,\"s\":[100,100],\"h\":1},{\"t\":14,\"s\":[0,0],\"h\":1}],\"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 7\",\"np\":11,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.527,-15.381],[0,0],[-16.592,-17.145],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-13.448,7.664],[0,0],[-17.698,10.784],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-3.871,25.993],[0,0],[8.117,32.855],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[14.031,8.836],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[9.314,9.861],[0,0],[16.592,17.145],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[15.014,-8.556],[0,0],[17.698,-10.784],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[3.871,-25.993],[0,0],[-10.383,-42.03],[0,0],[-33.95,-10.778],[0,0],[-26.662,15.973],[0,0],[-8.296,0],[0,0],[-18.634,-11.735],[0,0]],\"v\":[[-121.849,-206.352],[-161.4,-175.412],[-182.173,-172.147],[-193.511,-153.214],[-214.027,-135.922],[-218.088,-102.356],[-229.872,-81.594],[-235.542,-46.858],[-241.467,0.28],[-222.027,33.027],[-205.473,58.881],[-178.067,73.84],[-160.953,112.227],[-121.198,125.433],[-113.318,152.661],[-89.783,163.211],[-64.949,195.685],[-25.948,210.14],[-11.345,221.447],[9.97,215.704],[36.986,213.556],[40.385,184.688],[78.624,178.828],[104.64,145.801],[121.784,144.1],[126.971,127.861],[160.805,114.917],[180.651,77.022],[213.113,53.612],[225.152,8.645],[241.52,-22.857],[229.361,-60.866],[232.883,-107.97],[180.871,-152.377],[142.07,-197.613],[82.916,-185.269],[39.46,-183.492],[17.864,-151.627],[4.686,-158.605],[-5.428,-154.127],[-28.031,-182.836],[-68.036,-192.302]],\"c\":true}],\"e\":[{\"i\":[[43.349,-7.648],[0,0],[9.402,-7.743],[0,0],[10.231,-17.145],[0,0],[4.701,-15.209],[0,0],[-6.913,-32.077],[0,0],[-14.781,-16.813],[0,0],[-19.543,-13.685],[0,0],[-16.315,-12.72],[0,0],[-22.801,-14.217],[0,0],[-9.125,0.553],[0,0],[-14.931,4.078],[0,0],[-16.624,12.172],[0,0],[-9.955,9.125],[0,0],[-19.91,14.379],[0,0],[-16.113,18.888],[0,0],[-7.619,25.151],[0,0],[16.117,27.97],[0,0],[33.43,10.613],[0,0],[17.54,-10.508],[0,0],[3.739,0],[0,0],[17.031,13.336],[0,0]],\"o\":[[-40.51,7.147],[0,0],[-9.402,7.743],[0,0],[-10.231,17.145],[0,0],[-4.701,15.209],[0,0],[6.913,32.077],[0,0],[11.973,13.619],[0,0],[23.953,16.773],[0,0],[16.315,12.72],[0,0],[18.949,11.815],[0,0],[9.125,-0.553],[0,0],[18.514,-5.056],[0,0],[16.722,-12.243],[0,0],[9.955,-9.125],[0,0],[19.91,-14.379],[0,0],[16.078,-18.847],[0,0],[8.98,-29.643],[0,0],[-21.615,-37.512],[0,0],[-33.95,-10.778],[0,0],[-26.663,15.973],[0,0],[-8.296,0],[0,0],[-17.338,-13.577],[0,0]],\"v\":[[-122.349,-200.852],[-165.9,-178.912],[-181.673,-176.147],[-189.511,-163.714],[-217.027,-145.422],[-219.588,-110.856],[-241.872,-94.094],[-239.542,-62.358],[-241.967,-19.72],[-217.527,16.527],[-206.973,51.381],[-179.067,65.84],[-155.953,98.227],[-117.198,116.933],[-100.318,142.161],[-78.783,151.211],[-56.949,189.685],[-32.448,201.14],[-15.345,210.947],[3.47,204.704],[24.986,203.556],[43.385,190.688],[67.624,177.828],[82.14,158.301],[108.784,144.6],[131.471,116.361],[158.805,108.917],[179.151,78.022],[204.113,62.612],[219.652,17.144],[240.52,-14.357],[241.361,-65.366],[232.883,-120.97],[183.871,-164.877],[137.57,-196.113],[81.916,-196.269],[42.96,-187.992],[12.864,-156.627],[5.686,-161.605],[-8.428,-159.127],[-29.531,-189.336],[-67.036,-197.802]],\"c\":true}]},{\"t\":9}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":4,\"s\":[0,0],\"h\":1},{\"t\":5,\"s\":[100,100],\"h\":1},{\"t\":9,\"s\":[0,0],\"h\":1}],\"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 6\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[37,-3.75],[0,0],[8.5,-7],[0,0],[9.25,-15.5],[0,0],[4.25,-13.75],[0,0],[-6.25,-29],[0,0],[-8.75,-18.25],[0,0],[-15,-15.5],[0,0],[-14.75,-11.5],[0,0],[-22.25,-9.75],[0,0],[-8.25,0.5],[0,0],[-13.25,4.5],[0,0],[-16,9.75],[0,0],[-9,8.25],[0,0],[-18,13],[0,0],[-12.25,18.75],[0,0],[-3.5,23.5],[0,0],[11.75,28.25],[0,0],[26,19],[0,0],[35,-6.25],[0,0],[7.5,0],[0,0],[8.75,8],[0,0]],\"o\":[[-37,3.75],[0,0],[-8.5,7],[0,0],[-9.25,15.5],[0,0],[-4.25,13.75],[0,0],[6.25,29],[0,0],[8.75,18.25],[0,0],[15,15.5],[0,0],[14.75,11.5],[0,0],[22.25,9.75],[0,0],[8.25,-0.5],[0,0],[13.25,-4.5],[0,0],[16,-9.75],[0,0],[9,-8.25],[0,0],[18,-13],[0,0],[12.25,-18.75],[0,0],[3.5,-23.5],[0,0],[-11.75,-28.25],[0,0],[-26,-19],[0,0],[-35,6.25],[0,0],[-7.5,0],[0,0],[-8.75,-8],[0,0]],\"v\":[[-99.5,-183.25],[-144.75,-160.25],[-156.75,-157.75],[-167,-144.25],[-186,-125],[-196,-93.75],[-205.75,-79.5],[-205,-49],[-209,-10],[-186,18.25],[-185.5,47.5],[-155.75,77.75],[-145.25,100.25],[-107.5,125.75],[-94.5,146.75],[-68.25,159],[-46.25,175.25],[-13.25,184.25],[-0.5,189.5],[14.25,182.5],[33.25,178.75],[53.5,163.5],[72.25,157.75],[91.25,141],[106.75,136.75],[125,118],[147,106.75],[166.75,74.75],[185.25,56.75],[199.75,17],[215,-16],[213.5,-58.5],[209,-104.25],[178.25,-134],[149.5,-164.5],[91.5,-177.75],[49.5,-177.5],[13.25,-150.5],[4.5,-155],[-6,-150.5],[-18.75,-164.25],[-40,-171]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":3,\"s\":[0,0],\"h\":1},{\"t\":4,\"s\":[100,100],\"h\":1},{\"t\":5,\"s\":[0,0],\"h\":1}],\"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 5\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[28.5,3],[0,0],[22.75,-14.5],[0,0],[6.75,-23.75],[0,0],[-1.75,-23.5],[0,0],[-7.25,-11.75],[0,0],[-10.5,-8.25],[0,0],[-9.75,-8.75],[0,0],[-14,-6.5],[0,0],[-5.5,-2.75],[0,0],[-14.75,4.5],[0,0],[-14.5,6],[0,0],[-20,14.25],[0,0],[-6.5,15],[0,0],[-1.75,21],[0,0],[9.5,20.75],[0,0],[6.75,5.5],[0,0],[14.75,3.75],[0,0],[24.5,-4.5],[0,0],[4.5,1],[0,0]],\"o\":[[-28.5,-3],[0,0],[-22.75,14.5],[0,0],[-6.75,23.75],[0,0],[1.75,23.5],[0,0],[7.25,11.75],[0,0],[10.5,8.25],[0,0],[9.75,8.75],[0,0],[14,6.5],[0,0],[5.5,2.75],[0,0],[14.75,-4.5],[0,0],[14.5,-6],[0,0],[20,-14.25],[0,0],[6.5,-15],[0,0],[1.75,-21],[0,0],[-9.5,-20.75],[0,0],[-6.75,-5.5],[0,0],[-14.75,-3.75],[0,0],[-24.5,4.5],[0,0],[-4.5,-1],[0,0]],\"v\":[[-42.25,-141.75],[-83.5,-133],[-116.75,-124.25],[-131.75,-102],[-157,-69.5],[-155.75,-47.25],[-164,-6.75],[-151.25,18.75],[-146,44.75],[-134.75,55.5],[-123.25,79.5],[-110,85.5],[-98.5,104.25],[-79.75,113],[-61.75,129.75],[-42.75,132.5],[-32,141],[-13.5,141.75],[8,140.25],[26.75,131.25],[56.75,125.75],[73,110.75],[101,97.5],[129,67.25],[146,41.5],[153.25,14],[165.25,-17.25],[160.75,-52.5],[154.25,-91],[134.5,-109.75],[126.75,-123.75],[115.25,-125.25],[93,-140],[68,-140.5],[30.5,-141.5],[12,-124],[2.5,-126.5],[-8.75,-123.5]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":2,\"s\":[0,0],\"h\":1},{\"t\":3,\"s\":[100,100],\"h\":1},{\"t\":4,\"s\":[0,0],\"h\":1}],\"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 4\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[10.25,-3],[5.5,-1.75],[0,0],[26.75,0.25],[0,0],[9,-17.25],[0,0],[-3.25,-19.25],[0,0],[-8.5,-9.25],[0,0],[-14.75,-9.5],[0,0],[-18.5,2.75],[0,0],[-13,5],[0,0],[-9.5,16.5],[0,0],[-7,16.25],[0,0],[12.75,16.25],[0,0],[20.25,11.75],[0,0]],\"o\":[[-10.25,3],[-5.5,1.75],[0,0],[-26.75,-0.25],[0,0],[-9,17.25],[0,0],[3.25,19.25],[0,0],[8.5,9.25],[0,0],[14.75,9.5],[0,0],[18.5,-2.75],[0,0],[13,-5],[0,0],[9.5,-16.5],[0,0],[7,-16.25],[0,0],[-12.75,-16.25],[0,0],[-20.25,-11.75],[0,0]],\"v\":[[19,-97],[2.25,-85.75],[-4.75,-87.5],[-31.75,-96.5],[-64.5,-83],[-93.75,-63.5],[-99,-34.75],[-108,-0.5],[-99.5,20.5],[-90,53],[-70.5,62.5],[-54,82],[-35.75,87.5],[2.25,92],[18.5,84],[45,82.5],[60.25,69.25],[86.75,55.5],[91,28.75],[106.25,7.75],[108.75,-25.25],[105.5,-54.75],[88.25,-66.75],[70.25,-88.5],[41.25,-89.75]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":1,\"s\":[0,0],\"h\":1},{\"t\":2,\"s\":[100,100],\"h\":1},{\"t\":3,\"s\":[0,0],\"h\":1}],\"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 3\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[9.87,0.318],[0,0],[20.098,-10.357],[0,0],[5.5,-10.375],[0,0],[-8.375,-17.375],[0,0],[-8.75,-6.625],[0,0],[-14.875,0.5],[0,0],[-11.625,3.5],[0,0],[-5.25,9],[0,0],[-0.5,17.375],[0,0],[6.125,8],[0,0],[6.625,3.125],[0,0]],\"o\":[[-11.625,-0.375],[0,0],[-20.375,10.5],[0,0],[-6.558,12.37],[0,0],[8.156,16.92],[0,0],[8.75,6.625],[0,0],[14.875,-0.5],[0,0],[11.625,-3.5],[0,0],[5.25,-9],[0,0],[0.447,-15.518],[0,0],[-6.125,-8],[0,0],[-6.625,-3.125],[0,0]],\"v\":[[8.125,-57.25],[-3.75,-46.75],[-37.5,-48.875],[-42.125,-21.75],[-60.5,-21.125],[-51.125,-5.25],[-59.625,20.25],[-38.875,28.25],[-38.125,46.875],[-22.25,41.625],[-2.75,53.625],[14.375,40.375],[32.125,45.625],[39.25,36],[55.625,28.5],[51.5,13.25],[65.625,-9.125],[55.25,-22.5],[55.75,-41.125],[38.625,-40.25],[34,-53.75],[19.25,-44.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":0,\"s\":[0,0],\"h\":1},{\"t\":1,\"s\":[100,100],\"h\":1},{\"t\":2,\"s\":[0,0],\"h\":1}],\"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 2\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[11.875,-2.25],[0,0],[3.375,-4.5],[0,0],[0.125,-15.625],[0,0],[-9.125,-7.125],[0,0],[-15.809,5.312],[0,0],[-1.625,15],[0,0],[13.75,8.375],[0,0]],\"o\":[[-8.37,1.586],[0,0],[-3.375,4.5],[0,0],[-0.125,15.625],[0,0],[11.114,8.678],[0,0],[15.625,-5.25],[0,0],[1.625,-15],[0,0],[-13.75,-8.375],[0,0]],\"v\":[[-14.875,-37.75],[-24.5,-27.25],[-33.625,-26.25],[-34.25,-17.875],[-45.25,-2.625],[-35.5,15],[-28.5,33.25],[-8,35.75],[16.125,36.75],[33.125,23.875],[46.125,4.625],[40.625,-13.5],[28.625,-36],[3.625,-36]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":-1,\"s\":[0,0],\"h\":1},{\"t\":0,\"s\":[100,100],\"h\":1},{\"t\":1,\"s\":[0,0],\"h\":1}],\"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\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[3.5,2.75],[-1.75,-4]],\"o\":[[-3.5,-2.75],[1.75,4]],\"v\":[[-0.25,-62.25],[-4.625,-57.5]],\"c\":true}],\"e\":[{\"i\":[[0.045,0.036],[-0.023,-0.052]],\"o\":[[-0.045,-0.036],[0.023,0.052]],\"v\":[[-1.545,-59.289],[-1.602,-59.227]],\"c\":true}]},{\"t\":27}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":27,\"s\":[0,0],\"h\":1}],\"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 64\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[4.625,0.625],[-2.75,-7.125],[0.125,4.875]],\"o\":[[-4.625,-0.625],[2.75,7.125],[-0.125,-4.875]],\"v\":[[-11.875,-74.5],[-18,-64.625],[-5,-67.375]],\"c\":true}],\"e\":[{\"i\":[[0.036,0.005],[-0.022,-0.056],[0.001,0.038]],\"o\":[[-0.036,-0.005],[0.022,0.056],[-0.001,-0.038]],\"v\":[[-12.805,-66.377],[-12.853,-66.299],[-12.751,-66.321]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":23,\"s\":[0,0],\"h\":1},{\"t\":24,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 65\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[1.312,0.875],[-2.438,-1.75]],\"o\":[[-1.312,-0.875],[2.438,1.75]],\"v\":[[218.25,-117.562],[217.062,-114.812]],\"c\":true}],\"e\":[{\"i\":[[0.017,0.011],[-0.031,-0.022]],\"o\":[[-0.017,-0.011],[0.031,0.022]],\"v\":[[217.108,-115.773],[217.093,-115.738]],\"c\":true}]},{\"t\":30}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 66\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.625,0],[-2.438,-5.312],[-1.062,4.125]],\"o\":[[-3.625,0],[2.438,5.312],[1.062,-4.125]],\"v\":[[216.062,-112.125],[210.375,-102.812],[220.562,-107.25]],\"c\":true}],\"e\":[{\"i\":[[-0.05,0],[0.033,0.073],[0.015,-0.057]],\"o\":[[0.05,0],[-0.033,-0.073],[-0.015,0.057]],\"v\":[[214.764,-104.712],[214.842,-104.84],[214.702,-104.779]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 67\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.062,0.25],[-0.375,-3.5],[-1.062,2.438]],\"o\":[[-3.062,-0.25],[0.375,3.5],[1.062,-2.438]],\"v\":[[218.875,-126.688],[214.938,-120.812],[222.062,-122.188]],\"c\":true}],\"e\":[{\"i\":[[-0.067,-0.005],[0.008,0.077],[0.023,-0.053]],\"o\":[[0.067,0.005],[-0.008,-0.077],[-0.023,0.053]],\"v\":[[218.843,-122.025],[218.929,-122.154],[218.773,-122.124]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 68\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[2.25,-0.75],[-4,-4],[1,5.375]],\"o\":[[-2.25,0.75],[4,4],[-1,-5.375]],\"v\":[[-158.75,-23.375],[-159.25,-13.5],[-151.25,-18.875]],\"c\":true}],\"e\":[{\"i\":[[0.267,-0.089],[-0.475,-0.475],[0.119,0.638]],\"o\":[[-0.267,0.089],[0.475,0.475],[-0.119,-0.638]],\"v\":[[-156.987,-17.646],[-157.047,-16.475],[-156.097,-17.112]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 69\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.5,0.75],[-2.625,-4.375],[-0.625,4.625]],\"o\":[[-4.5,-0.75],[2.625,4.375],[0.625,-4.625]],\"v\":[[-174.375,-63],[-179.875,-56.375],[-169.875,-58.25]],\"c\":true}],\"e\":[{\"i\":[[-0.255,-0.042],[0.149,0.248],[0.035,-0.262]],\"o\":[[0.255,0.042],[-0.149,-0.248],[-0.035,0.262]],\"v\":[[-175.96,-57.585],[-175.649,-57.96],[-176.215,-57.854]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 70\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,1.25],[-3.25,-3]],\"o\":[[-3.125,-1.25],[3.25,3]],\"v\":[[-168.625,-97.625],[-170.375,-92.875]],\"c\":true}],\"e\":[{\"i\":[[0.24,0.096],[-0.25,-0.231]],\"o\":[[-0.24,-0.096],[0.25,0.231]],\"v\":[[-169.49,-94.625],[-169.625,-94.26]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 71\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.125,1.125],[-2.125,-3.25]],\"o\":[[-4.125,-1.125],[2.125,3.25]],\"v\":[[-174.75,-46.25],[-177.75,-41.25]],\"c\":true}],\"e\":[{\"i\":[[-0.223,-0.061],[0.115,0.176]],\"o\":[[0.223,0.061],[-0.115,-0.176]],\"v\":[[-175.277,-42.495],[-175.115,-42.765]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 72\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4,1.75],[-2.375,-2.5],[1.875,-2.125],[-6,2],[0,3.875]],\"o\":[[-4,-1.75],[2.375,2.5],[-1.875,2.125],[6,-2],[0,-3.875]],\"v\":[[-135.25,-91.25],[-140.375,-86.375],[-140.625,-79],[-138.5,-73],[-131.875,-84]],\"c\":true}],\"e\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31,\"s\":[{\"i\":[[1.513,0.673],[0.376,-1.269],[-0.263,-1.509],[-1.768,0.106],[0,1.489]],\"o\":[[-1.513,-0.673],[-0.408,1.376],[0.187,1.072],[2.388,-0.143],[0,-1.489]],\"v\":[[-136.388,-85.265],[-139.579,-83.901],[-140.175,-79.946],[-137.717,-77.793],[-135.011,-82.224]],\"c\":true}],\"e\":[{\"i\":[[-0.226,-0.099],[0.134,0.142],[-0.106,0.12],[0.34,-0.113],[0,-0.219]],\"o\":[[0.226,0.099],[-0.134,-0.142],[0.106,-0.12],[-0.34,0.113],[0,0.219]],\"v\":[[-138.024,-81.476],[-137.733,-81.752],[-137.719,-82.17],[-137.84,-82.509],[-138.215,-81.887]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 73\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.375,0.5],[-0.875,-5.875],[-0.25,4]],\"o\":[[-3.375,-0.5],[0.875,5.875],[0.25,-4]],\"v\":[[-149.375,-91.5],[-154,-81.25],[-144.25,-83.75]],\"c\":true}],\"e\":[{\"i\":[[0.272,0.04],[-0.07,-0.473],[-0.02,0.322]],\"o\":[[-0.272,-0.04],[0.07,0.473],[0.02,-0.322]],\"v\":[[-149.432,-84.316],[-149.805,-83.491],[-149.02,-83.693]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 74\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.25,0.5],[-1.625,-3.375],[0,2.75]],\"o\":[[-3.25,-0.5],[1.625,3.375],[0,-2.75]],\"v\":[[-139,-26.125],[-141.625,-19.5],[-134.5,-20.625]],\"c\":true}],\"e\":[{\"i\":[[-0.464,-0.071],[0.232,0.482],[0,-0.393]],\"o\":[[0.464,0.071],[-0.232,-0.482],[0,0.393]],\"v\":[[-138.857,-20.696],[-138.482,-21.643],[-139.5,-21.482]],\"c\":true}]},{\"t\":32}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":32,\"s\":[0,0],\"h\":1}],\"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 75\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[3.125,0.25],[-4.125,-0.5]],\"o\":[[-3.125,-0.25],[4.125,0.5]],\"v\":[[-129.25,-31.375],[-128.25,-26.5]],\"c\":true}],\"e\":[{\"i\":[[-0.379,-0.03],[0.5,0.061]],\"o\":[[0.379,0.03],[-0.5,-0.061]],\"v\":[[-128.129,-28.502],[-128.25,-29.093]],\"c\":true}]},{\"t\":31}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":31,\"s\":[0,0],\"h\":1}],\"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 76\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[4.875,0.25],[-6.125,-10.5],[0.875,9.875]],\"o\":[[-4.875,-0.25],[6.084,10.43],[-0.875,-9.875]],\"v\":[[-121.25,-44.375],[-123.25,-23.75],[-111.875,-31.25]],\"c\":true}],\"e\":[{\"i\":[[-0.298,-0.015],[0.375,0.643],[-0.054,-0.605]],\"o\":[[0.298,0.015],[-0.373,-0.639],[0.054,0.605]],\"v\":[[-120.122,-28.029],[-120,-29.292],[-120.696,-28.833]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 77\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28,\"s\":[{\"i\":[[5.75,-0.125],[-1.25,-3.625],[-1.125,5.25]],\"o\":[[-5.75,0.125],[1.25,3.625],[1.125,-5.25]],\"v\":[[-177,-126.875],[-183.875,-117.875],[-168.5,-120.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[-176.25,-120.625],[-176.25,-120.625],[-176.25,-120.625]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 78\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[7.625,-0.125],[0,0],[2.46,-4.038],[-3.208,-3.921],[0,0],[-1.375,10.5],[0,0],[1.065,4.639]],\"o\":[[-7.625,0.125],[0,0],[-2.228,3.658],[6.75,8.25],[0,0],[1.375,-10.5],[0,0],[-1.75,-7.625]],\"v\":[[-188.125,-106.125],[-193.75,-93.625],[-201.198,-89.718],[-200.125,-76],[-187.5,-73.625],[-172.875,-75.25],[-176.25,-88],[-173.375,-97.625]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.863,4.079],[-1.375,-8.125],[-4.25,1],[0,0],[-4.5,1.875],[4,3.25]],\"o\":[[-3.875,-3.25],[1.375,8.125],[4.25,-1],[0,0],[4.5,-1.875],[-4,-3.25]],\"v\":[[-151.125,-47.625],[-158.375,-39.375],[-148.75,-28.875],[-144.125,-31.75],[-136.75,-31.875],[-134.625,-46.375]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[1.75,2.5],[5,-5.25],[0,0],[-10.625,-1.875]],\"o\":[[-1.75,-2.5],[-5,5.25],[0,0],[10.625,1.875]],\"v\":[[-161.625,-32],[-173.25,-37],[-175,-28.625],[-168,-17]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,-1.5],[0,0],[4.75,-10.25],[-6.625,-1],[-1,4.5],[0,0],[0.625,8.5]],\"o\":[[-4.25,1.5],[0,0],[-4.75,10.25],[6.625,1],[1,-4.5],[0,0],[-0.625,-8.5]],\"v\":[[-191.5,-60.125],[-195.25,-53.5],[-209.625,-48.125],[-199.625,-31.75],[-188.125,-37.75],[-187.875,-44.875],[-180.125,-53.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":27,\"s\":[0,0],\"h\":1},{\"t\":28,\"s\":[100,100],\"h\":1},{\"t\":29,\"s\":[0,0],\"h\":1}],\"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 79\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[4.25,0],[4.5,2],[-1,-6.25],[-4,1.875],[-1.5,3.375]],\"o\":[[-4.25,0],[-4.5,-2],[1,6.25],[4,-1.875],[1.5,-3.375]],\"v\":[[-138.375,-45.625],[-149,-44.5],[-155.5,-36.75],[-144.5,-33.75],[-135.5,-35.25]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":1,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[2.625,1.25],[1.125,-4.875],[-1.75,-1.5],[0,0],[0,0],[3.625,-9.5],[-6.5,2.125],[-2.75,-2.5],[0.875,6.125],[0,0],[-0.125,3.625]],\"o\":[[-2.625,-1.25],[-1.125,4.875],[1.75,1.5],[0,0],[0,0],[-3.625,9.5],[6.5,-2.125],[2.75,2.5],[-0.875,-6.125],[0,0],[0.125,-3.625]],\"v\":[[-180.375,-103.75],[-191.375,-101.375],[-190,-93.25],[-185.875,-91.375],[-186.5,-89.125],[-199.625,-86.875],[-189.875,-74.875],[-181.5,-72.75],[-174.5,-78.875],[-179.25,-88.75],[-175.75,-97.125]],\"c\":true}},\"nm\":\"Path 2\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":2,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.243,-1.321],[0,0],[0,0],[4.125,0.25],[-2.125,-8.75],[-3.375,3],[0,0],[-1.529,-0.888],[0.5,4.75]],\"o\":[[-6.75,2.75],[0,0],[0,0],[-4.125,-0.25],[2.125,8.75],[3.375,-3],[0,0],[3.875,2.25],[-0.5,-4.75]],\"v\":[[-189,-58.75],[-191.25,-50.375],[-191.25,-50.125],[-199.75,-52.625],[-208.375,-40.375],[-192.75,-35.625],[-192,-46.125],[-188.875,-48.875],[-181.75,-53.375]],\"c\":true}},\"nm\":\"Path 3\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ind\":3,\"ty\":\"sh\",\"ks\":{\"a\":0,\"k\":{\"i\":[[3.125,0],[-0.375,-4.875],[-7,0.375],[1.5,4]],\"o\":[[-3.125,0],[0.375,4.875],[7,-0.375],[-1.5,-4]],\"v\":[[-168.25,-36.375],[-174,-29.875],[-166,-19.5],[-161.75,-30.25]],\"c\":true}},\"nm\":\"Path 4\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":28,\"s\":[0,0],\"h\":1},{\"t\":29,\"s\":[100,100],\"h\":1},{\"t\":30,\"s\":[0,0],\"h\":1}],\"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 80\",\"np\":4,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,-0.75],[-2.625,-1.375],[0,4]],\"o\":[[-3.375,0.75],[2.625,1.375],[0,-4]],\"v\":[[-149.875,-43],[-151.625,-34.25],[-140.625,-37.875]],\"c\":true}],\"e\":[{\"i\":[[-0.036,0.016],[0.023,0.017],[0.003,-0.039]],\"o\":[[0.035,-0.016],[-0.03,-0.023],[-0.004,0.049]],\"v\":[[-147.285,-38.411],[-147.278,-38.502],[-147.371,-38.464]],\"c\":true}]},{\"t\":37}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":37,\"s\":[0,0],\"h\":1}],\"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 81\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.875,-1.25],[-3.625,-2.375],[2.25,3.125]],\"o\":[[-3.875,1.25],[3.625,2.375],[-2.25,-3.125]],\"v\":[[-168.875,-33.875],[-169.875,-23.625],[-163.625,-30.375]],\"c\":true}],\"e\":[{\"i\":[[0.04,-0.013],[-0.037,-0.024],[0.023,0.032]],\"o\":[[-0.04,0.013],[0.037,0.024],[-0.023,-0.032]],\"v\":[[-167.46,-27.678],[-167.463,-27.584],[-167.398,-27.653]],\"c\":true}]},{\"t\":36}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":36,\"s\":[0,0],\"h\":1}],\"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 82\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[3.375,0.625],[-3.75,-1.875]],\"o\":[[-3.375,-0.625],[3.75,1.875]],\"v\":[[-187,-58.125],[-187.875,-52.75]],\"c\":true}],\"e\":[{\"i\":[[0.105,0.02],[-0.117,-0.059]],\"o\":[[-0.105,-0.02],[0.117,0.059]],\"v\":[[-187.605,-54.916],[-187.633,-54.748]],\"c\":true}]},{\"t\":34}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":34,\"s\":[0,0],\"h\":1}],\"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 83\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.5,0.875],[-5.5,-5.875],[0.875,4]],\"o\":[[-4.5,-0.875],[5.5,5.875],[-0.875,-4]],\"v\":[[-200,-50.25],[-204.125,-37.625],[-192.375,-45.25]],\"c\":true}],\"e\":[{\"i\":[[-0.132,-0.026],[0.179,0.154],[-0.003,-0.12]],\"o\":[[0.132,0.026],[-0.128,-0.11],[0.004,0.139]],\"v\":[[-201.803,-42.273],[-201.682,-42.643],[-201.997,-42.496]],\"c\":true}]},{\"t\":39}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":39,\"s\":[0,0],\"h\":1}],\"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 84\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.375,0.875],[-2,-1.75]],\"o\":[[-2.375,-0.875],[2,1.75]],\"v\":[[-178.25,-80.5],[-180.375,-75.875]],\"c\":true}],\"e\":[{\"i\":[[0.183,0.067],[-0.154,-0.135]],\"o\":[[-0.183,-0.067],[0.154,0.135]],\"v\":[[-179.058,-77.962],[-179.221,-77.606]],\"c\":true}]},{\"t\":33}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":33,\"s\":[0,0],\"h\":1}],\"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 85\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[4.625,1.125],[-4.25,-5.5],[-2.125,4.125]],\"o\":[[-4.625,-1.125],[4.25,5.5],[2.125,-4.125]],\"v\":[[-191.75,-89.5],[-196.875,-79.375],[-186.875,-80.75]],\"c\":true}],\"e\":[{\"i\":[[-0.097,-0.024],[0.089,0.115],[0.045,-0.087]],\"o\":[[0.097,0.024],[-0.089,-0.115],[-0.045,0.087]],\"v\":[[-192.962,-82.098],[-192.839,-82.31],[-193.08,-82.289]],\"c\":true}]},{\"t\":38}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":38,\"s\":[0,0],\"h\":1}],\"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 86\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"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\":[{\"i\":[[2.346,0.324],[-2.993,-3.154],[-0.566,2.346]],\"o\":[[-2.346,-0.324],[2.993,3.154],[0.566,-2.346]],\"v\":[[-182.926,-100.581],[-185.757,-95],[-179.691,-95.647]],\"c\":true}],\"e\":[{\"i\":[[0.03,0.004],[-0.039,-0.041],[-0.007,0.03]],\"o\":[[-0.03,-0.004],[0.039,0.041],[0.007,-0.03]],\"v\":[[-183.924,-96.43],[-183.961,-96.357],[-183.882,-96.366]],\"c\":true}]},{\"t\":35}]},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"t\":29,\"s\":[0,0],\"h\":1},{\"t\":30,\"s\":[100,100],\"h\":1},{\"t\":35,\"s\":[0,0],\"h\":1}],\"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 87\",\"np\":1,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0,0,0,1]},\"o\":{\"a\":0,\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"}],\"ip\":0,\"op\":41,\"st\":0,\"bm\":0,\"sr\":1}]}],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":0,\"nm\":\"Smoke 02 *\",\"refId\":\"comp_0\",\"ks\":{\"o\":{\"a\":0,\"k\":100},\"r\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[960,540,0]},\"a\":{\"a\":0,\"k\":[960,540,0]},\"s\":{\"a\":0,\"k\":[100,100,100]}},\"ao\":0,\"ef\":[{\"ty\":20,\"nm\":\"Tint\",\"mn\":\"ADBE Tint\",\"ix\":1,\"en\":1,\"ef\":[{\"ty\":2,\"nm\":\"Map Black To\",\"mn\":\"ADBE Tint-0001\",\"ix\":1,\"v\":{\"a\":0,\"k\":[1,0,0.26,1]}},{\"ty\":2,\"nm\":\"Map White To\",\"mn\":\"ADBE Tint-0002\",\"ix\":2,\"v\":{\"a\":0,\"k\":[0.4,0.07,0.19,1]}},{\"ty\":0,\"nm\":\"Amount to Tint\",\"mn\":\"ADBE Tint-0003\",\"ix\":3,\"v\":{\"a\":0,\"k\":100}},{\"ty\":6,\"nm\":\"\",\"mn\":\"ADBE Tint-0004\",\"ix\":4,\"v\":0},{\"ty\":7,\"nm\":\"GPU Rendering\",\"mn\":\"ADBE Force CPU GPU\",\"ix\":5,\"v\":{\"a\":0,\"k\":1}}]}],\"w\":1920,\"h\":1080,\"ip\":0,\"op\":40,\"st\":0,\"bm\":0,\"sr\":1}]}"
  },
  {
    "path": "epoxy-sample/src/main/assets/favourite_app_icon.json",
    "content": "{\"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}]}"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/CarouselData.java",
    "content": "package com.airbnb.epoxy.sample;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport java.util.List;\n\npublic class CarouselData implements Parcelable {\n  private final long id;\n  private final List<ColorData> colors;\n\n  public CarouselData(long id, List<ColorData> colors) {\n    this.id = id;\n    this.colors = colors;\n  }\n\n  public List<ColorData> getColors() {\n    return colors;\n  }\n\n  public long getId() {\n    return id;\n  }\n\n  @Override\n  public int describeContents() {\n    return 0;\n  }\n\n  @Override\n  public void writeToParcel(Parcel dest, int flags) {\n    dest.writeLong(this.id);\n    dest.writeTypedList(this.colors);\n  }\n\n  protected CarouselData(Parcel in) {\n    this.id = in.readLong();\n    this.colors = in.createTypedArrayList(ColorData.CREATOR);\n  }\n\n  public static final Creator<CarouselData> CREATOR = new Creator<CarouselData>() {\n    @Override\n    public CarouselData createFromParcel(Parcel source) {\n      return new CarouselData(source);\n    }\n\n    @Override\n    public CarouselData[] newArray(int size) {\n      return new CarouselData[size];\n    }\n  };\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/ColorData.java",
    "content": "package com.airbnb.epoxy.sample;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport androidx.annotation.ColorInt;\n\npublic class ColorData implements Parcelable {\n  private final long id;\n  @ColorInt private int colorInt;\n  private boolean playAnimation;\n\n  public ColorData(int colorInt, long id) {\n    this.colorInt = colorInt;\n    this.id = id;\n  }\n\n  public long getId() {\n    return id;\n  }\n\n  @ColorInt\n  public int getColorInt() {\n    return colorInt;\n  }\n\n  public void setColorInt(@ColorInt int colorInt) {\n    this.colorInt = colorInt;\n  }\n\n  public void setPlayAnimation(boolean playAnimation) {\n    this.playAnimation = playAnimation;\n  }\n\n  public boolean shouldPlayAnimation() {\n    return playAnimation;\n  }\n\n  @Override\n  public int describeContents() {\n    return 0;\n  }\n\n  @Override\n  public void writeToParcel(Parcel dest, int flags) {\n    dest.writeInt(this.colorInt);\n    dest.writeLong(this.id);\n  }\n\n  protected ColorData(Parcel in) {\n    this.colorInt = in.readInt();\n    this.id = in.readLong();\n  }\n\n  public static final Creator<ColorData> CREATOR = new Creator<ColorData>() {\n    @Override\n    public ColorData createFromParcel(Parcel source) {\n      return new ColorData(source);\n    }\n\n    @Override\n    public ColorData[] newArray(int size) {\n      return new ColorData[size];\n    }\n  };\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/EpoxyConfig.java",
    "content": "package com.airbnb.epoxy.sample;\n\nimport com.airbnb.epoxy.EpoxyDataBindingLayouts;\nimport com.airbnb.epoxy.PackageModelViewConfig;\n\n@PackageModelViewConfig(rClass = R.class)\n@EpoxyDataBindingLayouts(R.layout.button)\ninterface EpoxyConfig {}\n\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/MainActivity.java",
    "content": "package com.airbnb.epoxy.sample;\n\nimport android.animation.ArgbEvaluator;\nimport android.animation.ValueAnimator;\nimport android.graphics.Color;\nimport android.graphics.drawable.ColorDrawable;\nimport android.os.Bundle;\nimport android.os.Parcelable;\nimport android.view.View;\n\nimport com.airbnb.epoxy.EpoxyRecyclerView;\nimport com.airbnb.epoxy.EpoxyTouchHelper;\nimport com.airbnb.epoxy.EpoxyTouchHelper.DragCallbacks;\nimport com.airbnb.epoxy.sample.SampleController.AdapterCallbacks;\nimport com.airbnb.epoxy.sample.models.CarouselModelGroup;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Random;\n\nimport androidx.annotation.ColorInt;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.GridLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport static android.animation.ValueAnimator.ofObject;\n\n/**\n * Example activity usage for {@link com.airbnb.epoxy.EpoxyController}.\n */\npublic class MainActivity extends AppCompatActivity implements AdapterCallbacks {\n  private static final Random RANDOM = new Random();\n  private static final String CAROUSEL_DATA_KEY = \"carousel_data_key\";\n\n  private final SampleController controller = new SampleController(this);\n  private List<CarouselData> carousels = new ArrayList<>();\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_main);\n\n    EpoxyRecyclerView recyclerView = (EpoxyRecyclerView) findViewById(R.id.recycler_view);\n    recyclerView.setLayoutManager(new GridLayoutManager(this, 2));\n\n    recyclerView.setController(controller);\n\n    if (savedInstanceState != null) {\n      carousels = savedInstanceState.getParcelableArrayList(CAROUSEL_DATA_KEY);\n    }\n\n    initTouch(recyclerView);\n\n    updateController();\n  }\n\n  private void initTouch(final RecyclerView recyclerView) {\n    // Swiping is not used since it interferes with the carousels, but here is an example of\n    // how we would set it up.\n\n//    EpoxyTouchHelper.initSwiping(recyclerView)\n//        .leftAndRight()\n//        .withTarget(CarouselModelGroup.class)\n//        .andCallbacks(new SwipeCallbacks<CarouselModelGroup>() {\n//\n//          @Override\n//          public void onSwipeProgressChanged(CarouselModelGroup model, View itemView,\n//              float swipeProgress) {\n//\n    // Fades a background color in the further you swipe. A different color is used\n    // for swiping left vs right.\n//            int alpha = (int) (Math.abs(swipeProgress) * 255);\n//            if (swipeProgress > 0) {\n//              itemView.setBackgroundColor(Color.argb(alpha, 0, 255, 0));\n//            } else {\n//              itemView.setBackgroundColor(Color.argb(alpha, 255, 0, 0));\n//            }\n//          }\n//\n//          @Override\n//          public void onSwipeCompleted(CarouselModelGroup model, View itemView, int position,\n//              int direction) {\n//            carousels.remove(model.data);\n//            updateController();\n//          }\n//\n//          @Override\n//          public void clearView(CarouselModelGroup model, View itemView) {\n//            itemView.setBackgroundColor(Color.WHITE);\n//          }\n//        });\n\n    EpoxyTouchHelper.initDragging(controller)\n        .withRecyclerView(recyclerView)\n        .forVerticalList()\n        .withTarget(CarouselModelGroup.class)\n        .andCallbacks(new DragCallbacks<CarouselModelGroup>() {\n          @ColorInt final int selectedBackgroundColor = Color.argb(200, 200, 200, 200);\n          ValueAnimator backgroundAnimator = null;\n\n          @Override\n          public void onModelMoved(int fromPosition, int toPosition,\n              CarouselModelGroup modelBeingMoved, View itemView) {\n\n            int carouselIndex = carousels.indexOf(modelBeingMoved.data);\n            carousels\n                .add(carouselIndex + (toPosition - fromPosition), carousels.remove(carouselIndex));\n          }\n\n          @Override\n          public void onDragStarted(CarouselModelGroup model, View itemView, int adapterPosition) {\n            backgroundAnimator = ValueAnimator\n                .ofObject(new ArgbEvaluator(), Color.WHITE, selectedBackgroundColor);\n            backgroundAnimator.addUpdateListener(\n                animator -> itemView.setBackgroundColor((int) animator.getAnimatedValue())\n            );\n\n            backgroundAnimator.start();\n\n            itemView\n                .animate()\n                .scaleX(1.05f)\n                .scaleY(1.05f);\n          }\n\n          @Override\n          public void onDragReleased(CarouselModelGroup model, View itemView) {\n            if (backgroundAnimator != null) {\n              backgroundAnimator.cancel();\n            }\n\n            backgroundAnimator =\n                ofObject(new ArgbEvaluator(), ((ColorDrawable) itemView.getBackground()).getColor(),\n                    Color.WHITE);\n            backgroundAnimator.addUpdateListener(\n                animator -> itemView.setBackgroundColor((int) animator.getAnimatedValue())\n            );\n\n            backgroundAnimator.start();\n\n            itemView\n                .animate()\n                .scaleX(1f)\n                .scaleY(1f);\n          }\n\n          @Override\n          public void clearView(CarouselModelGroup model, View itemView) {\n            onDragReleased(model, itemView);\n          }\n        });\n  }\n\n  @Override\n  protected void onSaveInstanceState(Bundle state) {\n    super.onSaveInstanceState(state);\n    state.putParcelableArrayList(CAROUSEL_DATA_KEY, (ArrayList<? extends Parcelable>) carousels);\n    controller.onSaveInstanceState(state);\n  }\n\n  @Override\n  protected void onRestoreInstanceState(Bundle savedInstanceState) {\n    super.onRestoreInstanceState(savedInstanceState);\n    controller.onRestoreInstanceState(savedInstanceState);\n  }\n\n  private void updateController() {\n    controller.setData(carousels);\n  }\n\n  @Override\n  public void onAddCarouselClicked() {\n    CarouselData carousel = new CarouselData(carousels.size(), new ArrayList<>());\n    addColorToCarousel(carousel);\n    carousels.add(0, carousel);\n    updateController();\n  }\n\n  private void addColorToCarousel(CarouselData carousel) {\n    List<ColorData> colors = carousel.getColors();\n    colors.add(0, new ColorData(randomColor(), colors.size()));\n  }\n\n  @Override\n  public void onClearCarouselsClicked() {\n    carousels.clear();\n    updateController();\n  }\n\n  @Override\n  public void onShuffleCarouselsClicked() {\n    Collections.shuffle(carousels);\n    updateController();\n  }\n\n  @Override\n  public void onChangeAllColorsClicked() {\n    for (CarouselData carouselData : carousels) {\n      for (ColorData colorData : carouselData.getColors()) {\n        colorData.setColorInt(randomColor());\n      }\n    }\n\n    updateController();\n  }\n\n  @Override\n  public void onAddColorToCarouselClicked(CarouselData carousel) {\n    addColorToCarousel(carousel);\n    updateController();\n  }\n\n  @Override\n  public void onClearCarouselClicked(CarouselData carousel) {\n    carousel.getColors().clear();\n    updateController();\n  }\n\n  @Override\n  public void onShuffleCarouselColorsClicked(CarouselData carousel) {\n    Collections.shuffle(carousel.getColors());\n    updateController();\n  }\n\n  @Override\n  public void onChangeCarouselColorsClicked(CarouselData carousel) {\n    for (ColorData colorData : carousel.getColors()) {\n      colorData.setColorInt(randomColor());\n    }\n\n    updateController();\n  }\n\n  @Override\n  public void onColorClicked(CarouselData carousel, int colorPosition) {\n    int carouselPosition = carousels.indexOf(carousel);\n    ColorData colorData = carousels.get(carouselPosition).getColors().get(colorPosition);\n    colorData.setPlayAnimation(!colorData.shouldPlayAnimation());\n\n    updateController();\n  }\n\n  private static int randomColor() {\n    int r = RANDOM.nextInt(256);\n    int g = RANDOM.nextInt(256);\n    int b = RANDOM.nextInt(256);\n\n    return Color.rgb(r, g, b);\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/SampleController.kt",
    "content": "package com.airbnb.epoxy.sample\n\nimport android.view.View\nimport com.airbnb.epoxy.AutoModel\nimport com.airbnb.epoxy.DataBindingEpoxyModel\nimport com.airbnb.epoxy.EpoxyAsyncUtil\nimport com.airbnb.epoxy.TypedEpoxyController\nimport com.airbnb.epoxy.sample.models.CarouselModelGroup\nimport com.airbnb.epoxy.sample.views.HeaderViewModel_\n\nclass SampleController(private val callbacks: AdapterCallbacks) :\n    TypedEpoxyController<List<CarouselData>>(\n        EpoxyAsyncUtil.getAsyncBackgroundHandler(),\n        EpoxyAsyncUtil.getAsyncBackgroundHandler()\n    ) {\n    interface AdapterCallbacks {\n        fun onAddCarouselClicked()\n        fun onClearCarouselsClicked()\n        fun onShuffleCarouselsClicked()\n        fun onChangeAllColorsClicked()\n        fun onAddColorToCarouselClicked(carousel: CarouselData?)\n        fun onClearCarouselClicked(carousel: CarouselData?)\n        fun onShuffleCarouselColorsClicked(carousel: CarouselData?)\n        fun onChangeCarouselColorsClicked(carousel: CarouselData?)\n        fun onColorClicked(carousel: CarouselData?, colorPosition: Int)\n    }\n\n    @AutoModel\n    lateinit var header: HeaderViewModel_\n\n    @AutoModel\n    lateinit var addButton: ButtonBindingModel_\n\n    @AutoModel\n    lateinit var clearButton: ButtonBindingModel_\n\n    @AutoModel\n    lateinit var shuffleButton: ButtonBindingModel_\n\n    @AutoModel\n    lateinit var changeColorsButton: ButtonBindingModel_\n\n    override fun buildModels(carousels: List<CarouselData>) {\n        header\n            .title(R.string.epoxy)\n            .caption(R.string.header_subtitle)\n        // \"addTo\" is not needed since implicit adding is enabled\n        // (https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#implicit-adding)\n        addButton\n            .textRes(R.string.button_add)\n            .clickListener { model: ButtonBindingModel_?, parentView: DataBindingEpoxyModel.DataBindingHolder?, clickedView: View?, position: Int -> callbacks.onAddCarouselClicked() }\n        clearButton\n            .textRes(R.string.button_clear)\n            .clickListener { v: View? -> callbacks.onClearCarouselsClicked() }\n            .addIf(carousels.size > 0, this)\n        shuffleButton\n            .textRes(R.string.button_shuffle)\n            .clickListener { v: View? -> callbacks.onShuffleCarouselsClicked() }\n            .addIf(carousels.size > 1, this)\n        changeColorsButton\n            .textRes(R.string.button_change)\n            .clickListener { v: View? -> callbacks.onChangeAllColorsClicked() }\n            .addIf(carousels.size > 0, this)\n        for (i in carousels.indices) {\n            val carousel = carousels[i]\n            add(CarouselModelGroup(carousel, callbacks))\n        }\n    }\n\n    override fun onExceptionSwallowed(exception: RuntimeException) {\n        // Best practice is to throw in debug so you are aware of any issues that Epoxy notices.\n        // Otherwise Epoxy does its best to swallow these exceptions and continue gracefully\n        throw exception\n    }\n\n    init {\n        // Demonstrating how model building and diffing can be done in the background.\n        // You can control them separately by passing in separate handler, as shown below.\n        //    super(new Handler(), BACKGROUND_HANDLER);\n//    super(BACKGROUND_HANDLER, new Handler());\n        isDebugLoggingEnabled = true\n    }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/BaseEpoxyHolder.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport androidx.annotation.CallSuper\nimport com.airbnb.epoxy.EpoxyHolder\nimport kotlin.properties.ReadOnlyProperty\nimport kotlin.reflect.KProperty\n\n/**\n * Creating a base holder class allows us to leverage easy view binding for all subclasses via property delegates.\n * This makes subclasses much cleaner, and is a highly recommended pattern.\n */\nabstract class BaseEpoxyHolder : EpoxyHolder() {\n    private lateinit var view: View\n\n    @CallSuper\n    override fun bindView(itemView: View) {\n        view = itemView\n    }\n\n    protected fun <V : View> bind(id: Int): ReadOnlyProperty<BaseEpoxyHolder, V> =\n        Lazy { holder: BaseEpoxyHolder, prop ->\n            holder.view.findViewById(id) as V?\n                ?: throw IllegalStateException(\"View ID $id for '${prop.name}' not found.\")\n        }\n\n    /**\n     * Taken from Kotterknife.\n     * https://github.com/JakeWharton/kotterknife\n     */\n    private class Lazy<V>(\n        private val initializer: (BaseEpoxyHolder, KProperty<*>) -> V\n    ) : ReadOnlyProperty<BaseEpoxyHolder, V> {\n        private object EMPTY\n\n        private var value: Any? = EMPTY\n\n        override fun getValue(thisRef: BaseEpoxyHolder, property: KProperty<*>): V {\n            if (value == EMPTY) {\n                value = initializer(thisRef, property)\n            }\n            @Suppress(\"UNCHECKED_CAST\")\n            return value as V\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/BaseView.java",
    "content": "package com.airbnb.epoxy.sample.models;\n\nimport android.content.Context;\n\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelView;\n\nimport androidx.appcompat.widget.AppCompatTextView;\n\n@ModelView\npublic abstract class BaseView extends AppCompatTextView {\n\n  public BaseView(Context context) {\n    super(context);\n  }\n\n  @ModelProp\n  public void setVerticalPadding(CharSequence tex) {\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/CarouselModelGroup.java",
    "content": "package com.airbnb.epoxy.sample.models;\n\nimport com.airbnb.epoxy.EpoxyModel;\nimport com.airbnb.epoxy.EpoxyModelGroup;\nimport com.airbnb.epoxy.sample.CarouselData;\nimport com.airbnb.epoxy.sample.ColorData;\nimport com.airbnb.epoxy.sample.R;\nimport com.airbnb.epoxy.sample.SampleController.AdapterCallbacks;\nimport com.airbnb.epoxy.sample.views.GridCarouselModel_;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class CarouselModelGroup extends EpoxyModelGroup {\n  public final CarouselData data;\n\n  public CarouselModelGroup(CarouselData carousel, AdapterCallbacks callbacks) {\n    super(R.layout.model_carousel_group, buildModels(carousel, callbacks));\n    this.data = carousel;\n    id(carousel.getId());\n  }\n\n  private static List<EpoxyModel<?>> buildModels(CarouselData carousel,\n      AdapterCallbacks callbacks) {\n    List<ColorData> colors = carousel.getColors();\n    ArrayList<EpoxyModel<?>> models = new ArrayList<>();\n\n    models.add(new ImageButtonModel_()\n        .id(\"add\")\n        .imageRes(R.drawable.ic_add_circle)\n        .clickListener((model, parentView, clickedView, position) -> callbacks\n            .onAddColorToCarouselClicked(carousel)));\n\n    models.add(new ImageButtonModel_()\n        .id(\"delete\")\n        .imageRes(R.drawable.ic_delete)\n        .clickListener(v -> callbacks.onClearCarouselClicked(carousel))\n        .show(colors.size() > 0));\n\n    models.add(new ImageButtonModel_()\n        .id(\"change\")\n        .imageRes(R.drawable.ic_change)\n        .clickListener(v -> callbacks.onChangeCarouselColorsClicked(carousel))\n        .show(colors.size() > 0));\n\n    models.add(new ImageButtonModel_()\n        .id(\"shuffle\")\n        .imageRes(R.drawable.ic_shuffle)\n        .clickListener(v -> callbacks.onShuffleCarouselColorsClicked(carousel))\n        .show(colors.size() > 1));\n\n    List<ColorModel_> colorModels = new ArrayList<>();\n    for (ColorData colorData : colors) {\n      colorModels.add(new ColorModel_()\n          .id(colorData.getId(), carousel.getId())\n          .color(colorData.getColorInt())\n          .playAnimation(colorData.shouldPlayAnimation())\n          .clickListener((model, parentView, clickedView, position) -> {\n            // A model click listener is used instead of a normal click listener so that we can get\n            // the current position of the view. Since the view may have been moved when the colors\n            // were shuffled we can't rely on the position of the model when it was added here to\n            // be correct, since the model won't have been rebound when shuffled.\n            callbacks.onColorClicked(carousel, position);\n          }));\n    }\n\n    models.add(new GridCarouselModel_()\n        .id(\"carousel\")\n        .models(colorModels));\n\n    return models;\n  }\n\n  @Override\n  public int getSpanSize(int totalSpanCount, int position, int itemCount) {\n    return totalSpanCount;\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/ColorModel.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.animation.Animator\nimport android.view.View\nimport androidx.annotation.ColorInt\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.sample.R\nimport com.airbnb.epoxy.sample.models.ColorModel.ColorHolder\nimport com.airbnb.lottie.LottieAnimationView\n\n/**\n * This is an example of using [com.airbnb.epoxy.SimpleEpoxyModel], which is useful if you\n * don't need to do anything special in onBind. You can also instantiate [ ] directly instead of subclassing it if you don't need to do\n * anything in onBind.\n */\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class ColorModel : EpoxyModelWithHolder<ColorHolder>() {\n    @EpoxyAttribute @ColorInt var color: Int = 0\n    @EpoxyAttribute var playAnimation: Boolean = false\n    @EpoxyAttribute(DoNotHash) var clickListener: View.OnClickListener? = null\n\n    override fun bind(holder: ColorHolder) {\n        holder.cardView.setBackgroundColor(color)\n        holder.cardView.setOnClickListener(clickListener)\n    }\n\n    override fun bind(holder: ColorHolder, previouslyBoundModel: EpoxyModel<*>) {\n        // When this model changes we get a bind call with the previously bound model, so we can see\n        // what changed and update accordingly.\n        val previousModel = previouslyBoundModel as ColorModel\n        if (previousModel.playAnimation != playAnimation) {\n            toggleAnimation(holder.lottieView, playAnimation)\n        } else {\n            bind(holder)\n        }\n    }\n\n    private fun toggleAnimation(lottieView: LottieAnimationView, playAnimation: Boolean) {\n        if (!playAnimation) {\n            if (lottieView.isAnimating) {\n                // Reverse it just for fun\n                lottieView.speed = -1f\n                lottieView.resumeAnimation()\n            } else {\n                cancelAnimation(lottieView)\n            }\n            return\n        }\n\n        lottieView.addAnimatorListener(object : SimpleAnimatorListener() {\n            override fun onAnimationStart(animation: Animator) {\n                lottieView.visibility = View.VISIBLE\n            }\n\n            override fun onAnimationEnd(animation: Animator) {\n                lottieView.removeAnimatorListener(this)\n                cancelAnimation(lottieView)\n            }\n\n            override fun onAnimationCancel(animation: Animator) {\n                lottieView.removeAnimatorListener(this)\n                cancelAnimation(lottieView)\n            }\n        })\n\n        lottieView.speed = 1f\n        lottieView.playAnimation()\n    }\n\n    private fun cancelAnimation(lottieView: LottieAnimationView) {\n        lottieView.cancelAnimation()\n        lottieView.progress = 0f\n        lottieView.visibility = View.GONE\n    }\n\n    override fun unbind(holder: ColorHolder) {\n        // Don't leak the click listener when this view goes back in the view pool\n        holder.cardView.setOnClickListener(null)\n        cancelAnimation(holder.lottieView)\n    }\n\n    class ColorHolder : BaseEpoxyHolder() {\n        val cardView: View by bind(R.id.card_view)\n        val lottieView: LottieAnimationView by bind(R.id.lottie_view)\n    }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/ImageButtonModel.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View.OnClickListener\nimport android.widget.ImageView\nimport androidx.annotation.DrawableRes\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyAttribute.Option.DoNotHash\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.sample.R\nimport com.airbnb.epoxy.sample.models.ImageButtonModel.ImageButtonHolder\n\n@EpoxyModelClass(layout = R.layout.model_image_button)\nabstract class ImageButtonModel : EpoxyModelWithHolder<ImageButtonHolder>() {\n    @EpoxyAttribute @DrawableRes var imageRes: Int = 0\n    @EpoxyAttribute(DoNotHash) var clickListener: OnClickListener? = null\n\n    override fun bind(holder: ImageButtonHolder) {\n        holder.button.setImageResource(imageRes)\n        holder.button.setOnClickListener(clickListener)\n    }\n\n    override fun unbind(holder: ImageButtonHolder) {\n        // Release resources and don't leak listeners as this view goes back to the view pool\n        holder.button.setOnClickListener(null)\n        holder.button.setImageDrawable(null)\n    }\n\n    class ImageButtonHolder : BaseEpoxyHolder() {\n        val button: ImageView by bind((R.id.button))\n    }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/SimpleAnimatorListener.java",
    "content": "package com.airbnb.epoxy.sample.models;\n\nimport android.animation.Animator;\nimport android.animation.Animator.AnimatorListener;\n\npublic class SimpleAnimatorListener implements AnimatorListener {\n  @Override\n  public void onAnimationStart(Animator animation) {\n\n  }\n\n  @Override\n  public void onAnimationEnd(Animator animation) {\n\n  }\n\n  @Override\n  public void onAnimationCancel(Animator animation) {\n\n  }\n\n  @Override\n  public void onAnimationRepeat(Animator animation) {\n\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel1.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel1 : EpoxyModel<View>() {\n\n    @EpoxyAttribute var num: Int = 0\n    @EpoxyAttribute var num2: Int = 0\n    @EpoxyAttribute var num3: Int = 0\n    @EpoxyAttribute var num4: Int = 0\n    @EpoxyAttribute var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel2.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel2 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel3.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel3 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel4.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel4 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel5.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel5 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel6.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel6 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/models/TestModel7.kt",
    "content": "package com.airbnb.epoxy.sample.models\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.sample.R\n\n@EpoxyModelClass(layout = R.layout.model_color)\nabstract class TestModel7 : EpoxyModel<View>() {\n\n    @EpoxyAttribute\n    var num: Int = 0\n    @EpoxyAttribute\n    var num2: Int = 0\n    @EpoxyAttribute\n    var num3: Int = 0\n    @EpoxyAttribute\n    var num4: Int = 0\n    @EpoxyAttribute\n    var num5: Int = 0\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/views/GridCarousel.java",
    "content": "package com.airbnb.epoxy.sample.views;\n\nimport android.content.Context;\n\nimport com.airbnb.epoxy.Carousel;\nimport com.airbnb.epoxy.ModelView;\nimport com.airbnb.epoxy.ModelView.Size;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.GridLayoutManager;\nimport androidx.recyclerview.widget.LinearLayoutManager;\n\n@ModelView(saveViewState = true, autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\npublic class GridCarousel extends Carousel {\n  private static final int SPAN_COUNT = 2;\n\n  public GridCarousel(Context context) {\n    super(context);\n  }\n\n  @NonNull\n  @Override\n  protected LayoutManager createLayoutManager() {\n    return new GridLayoutManager(getContext(), SPAN_COUNT, LinearLayoutManager.HORIZONTAL, false);\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/java/com/airbnb/epoxy/sample/views/HeaderView.java",
    "content": "package com.airbnb.epoxy.sample.views;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport com.airbnb.epoxy.ModelProp;\nimport com.airbnb.epoxy.ModelProp.Option;\nimport com.airbnb.epoxy.ModelView;\nimport com.airbnb.epoxy.TextProp;\nimport com.airbnb.epoxy.sample.R;\nimport com.airbnb.paris.annotations.Style;\nimport com.airbnb.paris.annotations.Styleable;\n\n@Styleable // Dynamic styling via the Paris library\n@ModelView\npublic class HeaderView extends LinearLayout {\n\n  private TextView title;\n  private TextView caption;\n\n  public HeaderView(Context context) {\n    super(context);\n    init();\n  }\n\n  @Style(isDefault = true)\n  static void headerStyle(HeaderViewStyleApplier.StyleBuilder builder) {\n    builder.layoutWidth(ViewGroup.LayoutParams.MATCH_PARENT)\n        .layoutHeight(ViewGroup.LayoutParams.WRAP_CONTENT);\n  }\n\n  private void init() {\n    setOrientation(VERTICAL);\n    inflate(getContext(), R.layout.view_header, this);\n    title = findViewById(R.id.title_text);\n    caption = findViewById(R.id.caption_text);\n  }\n\n  @TextProp(defaultRes = R.string.app_name)\n  public void setTitle(CharSequence title) {\n    this.title.setText(title);\n  }\n\n  @ModelProp(options = Option.GenerateStringOverloads)\n  public void setCaption(CharSequence caption) {\n    this.caption.setText(caption);\n  }\n}\n"
  },
  {
    "path": "epoxy-sample/src/main/res/drawable/ic_add_circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:pathData=\"M0 0h24v24H0z\" />\n    <path\n        android:fillColor=\"#000000\"\n        android:pathData=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5\n11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\" />\n</vector>"
  },
  {
    "path": "epoxy-sample/src/main/res/drawable/ic_change.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"#000000\"\n        android:pathData=\"M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57 0.46 3.03 1.24 4.26L6.7\n14.8c-0.45-0.83-0.7-1.79-0.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c0.44 0.84 0.7\n1.79 0.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8\n0-1.57-0.46-3.03-1.24-4.26z\" />\n    <path\n        android:pathData=\"M0 0h24v24H0z\" />\n</vector>"
  },
  {
    "path": "epoxy-sample/src/main/res/drawable/ic_delete.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"#000000\"\n        android:pathData=\"M6 19c0 1.1 0.9 2 2 2h8c1.1 0 2-0.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n    <path\n        android:pathData=\"M0 0h24v24H0z\" />\n</vector>"
  },
  {
    "path": "epoxy-sample/src/main/res/drawable/ic_shuffle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"#000000\"\n        android:pathData=\"M4.59 6.89c0.7-0.71 1.4-1.35 1.71-1.22 0.5 0.2 0 1.03-0.3 1.52-0.25 0.42 -2.86\n3.89-2.86 6.31 0 1.28 0.48 2.34 1.34 2.98 0.75 0.56 1.74 0.73 2.64 0.46 1.07-0.31\n1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78\n0.64 -5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33\n4.69-6.1H21v-2.5h-2.47c-0.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94\n2.84-0.58 0.73 -2.06 2.48-2.29 2.72-0.25 0.3 -0.68 0.84 -1.11 0.84 -0.45\n0-0.72-0.83-0.36-1.92 0.35 -1.09 1.4-2.86 1.85-3.52 0.78 -1.14 1.3-1.92 1.3-3.28C8.95\n3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-0.36 0.36 -0.66 0.66 -0.88 0.93 l1.75\n1.71zm9.29 11.66c-0.31 0-0.74-0.26-0.74-0.72 0-0.6 0.73 -2.2 2.87-2.76-0.3 2.69-1.43\n3.48-2.13 3.48z\" />\n    <path\n        android:pathData=\"M0 0h24v24H0z\" />\n</vector>"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.EpoxyRecyclerView android:id=\"@+id/recycler_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:padding=\"8dp\"\n    android:background=\"#ffffff\"\n    app:itemSpacing=\"4dp\"\n    />\n"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/button.xml",
    "content": "<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data>\n\n        <variable\n            name=\"textRes\"\n            type=\"int\" />\n\n        <variable\n            name=\"clickListener\"\n            type=\"android.view.View.OnClickListener\" />\n    </data>\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:onClick=\"@{clickListener}\"\n        android:text=\"@{textRes}\" />\n</layout>"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/model_carousel_group.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\">\n\n    <FrameLayout\n        android:layout_width=\"64dp\"\n        android:layout_height=\"64dp\"\n        android:animateLayoutChanges=\"true\">\n\n        <!-- Button view stubs -->\n        <ViewStub\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|left\" />\n\n        <ViewStub\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|right\" />\n\n        <ViewStub\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|left\" />\n\n        <ViewStub\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|right\" />\n\n    </FrameLayout>\n\n    <!-- We must set an inflatedId so this view can have its state saved (eg scroll position) -->\n    <ViewStub\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"120dp\"\n        android:inflatedId=\"@+id/recycler_view\" />\n\n</LinearLayout>"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/model_color.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"40dp\"\n    android:layout_height=\"match_parent\">\n\n    <com.airbnb.lottie.LottieAnimationView\n        android:id=\"@+id/lottie_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\"\n        app:lottie_fileName=\"favourite_app_icon.json\" />\n\n</androidx.cardview.widget.CardView>\n"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/model_image_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.appcompat.widget.AppCompatImageView android:id=\"@id/button\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"32dp\"\n    android:layout_height=\"32dp\" />\n"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/number_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"16dp\" />"
  },
  {
    "path": "epoxy-sample/src/main/res/layout/view_header.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <TextView\n        android:id=\"@+id/title_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:lineSpacingMultiplier=\"0.8\"\n        android:paddingTop=\"24dp\"\n        android:textColor=\"#000000\"\n        android:textSize=\"38sp\"\n        tools:text=\"Title\" />\n\n    <TextView\n        android:id=\"@+id/caption_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"8dp\"\n        android:textColor=\"#000000\"\n        android:textSize=\"20sp\"\n        tools:text=\"caption\" />\n\n    <Space\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:minHeight=\"24dp\" />\n\n</merge>"
  },
  {
    "path": "epoxy-sample/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "epoxy-sample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Epoxy Sample</string>\n    <string name=\"epoxy\">Epoxy</string>\n    <string name=\"header_subtitle\">Composing views with ease</string>\n    <string name=\"button_add\">Add</string>\n    <string name=\"button_clear\">Clear</string>\n    <string name=\"button_shuffle\">Shuffle</string>\n    <string name=\"button_change\">Change</string>\n</resources>\n"
  },
  {
    "path": "epoxy-sample/src/main/res/values-w820dp/dimens.xml",
    "content": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "epoxy-viewbinder/.gitignore",
    "content": "/build"
  },
  {
    "path": "epoxy-viewbinder/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply from: '../publishing.gradle'\n\nandroid {\n  namespace 'com.airbnb.epoxy.viewbinder'\n\n  defaultConfig {\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n}\n\nkotlin {\n  jvmToolchain(11)\n}\n\ndependencies {\n  implementation rootProject.deps.androidAppcompat\n  implementation rootProject.deps.androidCoreKtx\n  implementation rootProject.deps.androidRecyclerView\n  api project(':epoxy-adapter')\n  api project(':epoxy-annotations')\n\n  testImplementation rootProject.deps.androidTestCore\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.robolectric\n  testImplementation rootProject.deps.mockito\n  androidTestImplementation rootProject.deps.junit\n  androidTestImplementation rootProject.deps.androidArchCoreTesting\n  androidTestImplementation rootProject.deps.androidTestRunner\n\n  kaptAndroidTest project(\":epoxy-processor\")\n}\n"
  },
  {
    "path": "epoxy-viewbinder/gradle.properties",
    "content": "POM_NAME=Epoxy View Binder Support\nPOM_ARTIFACT_ID=epoxy-viewbinder\nPOM_PACKAGING=jar"
  },
  {
    "path": "epoxy-viewbinder/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "epoxy-viewbinder/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest />\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/java/com/airbnb/epoxy/EpoxyViewBinder.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.isVisible\n\n/**\n * A helper to allow binding EpoxyModels to views outside of a RecyclerView. It is recommended to\n * use the extension functions [epoxyView] and [optionalEpoxyView] on Activity/Fragment/View Groups.\n *\n * This is helpful in two cases:\n * 1. You want to dynamically insert a view (of unknown or dynamic type) into a layout\n * 2. You have a predefined view in a layout and you want to update its data functionally with an\n * EpoxyModel\n */\nclass EpoxyViewBinder : ModelCollector {\n\n    private var tempModel: EpoxyModel<*>? = null\n\n    override fun add(model: EpoxyModel<*>) {\n        require(tempModel == null) {\n            \"A model was already added to the ModelCollector. Only one should be added.\"\n        }\n        tempModel = model\n    }\n\n    /**\n     * Bind the model to the view.\n     * - If the model is null, the view will be hidden.\n     * - If the view has previously been bound to another model, a partial bind will be done to only\n     * update the properties that have changed.\n     */\n    fun <T : View> bind(view: T, model: EpoxyModel<T>?) {\n        val newModel = model ?: run {\n            // No model added, so the view is hidden\n            view.isVisible = false\n            return\n        }\n        view.isVisible = true\n\n        val existingHolder = view.viewHolder\n\n        val viewHolder =\n            if (existingHolder == null || !newModel.hasSameViewType(existingHolder.model)) {\n                EpoxyViewHolder(view.parent, view, false)\n            } else {\n                existingHolder\n            }\n\n        bind(viewHolder, newModel, existingHolder?.model)\n    }\n\n    /**\n     * Replaces an existing view if it exists, else creates a new view. This is similar to\n     * [replaceView] but it does not add new views to the parent [ViewGroup]. This allows for custom\n     * layout handling (e.g. adding constraints for a ConstraintLayout).\n     *\n     * If the previous view is the same view type then it is reused. The new view is set to have the\n     * same ID as the old view if it exists. If not then a new ID is generated.\n     *\n     * @return the [View] the model has been bound to.\n     */\n    fun replaceOrCreateView(\n        parentView: ViewGroup,\n        previousView: View?,\n        model: EpoxyModel<*>\n    ): View {\n        val existingHolder = previousView?.viewHolder\n\n        val viewHolder =\n            if (existingHolder == null || !model.hasSameViewType(existingHolder.model)) {\n                val newView = model.buildView(parentView)\n                newView.id = previousView?.id ?: ViewCompat.generateViewId()\n\n                EpoxyViewHolder(parentView, newView, false)\n            } else {\n                existingHolder\n            }\n\n        bind(viewHolder, model, null)\n        return viewHolder.itemView\n    }\n\n    /**\n     * Similar to [replaceView] but the model is provided via a lambda that adds it to this\n     * [ModelCollector].\n     */\n    fun replaceView(\n        previousView: View,\n        modelProvider: ModelCollector.(context: Context) -> Unit\n    ): View {\n        @Suppress(\"UNUSED_EXPRESSION\")\n        modelProvider(previousView.context)\n        val model = tempModel\n        tempModel = null\n\n        return replaceView(previousView, model)\n    }\n\n    /**\n     * Creates a view for the model and swaps it in place in the parent of the previous view.\n     * - If the previous view is the same view type, it is reused.\n     * - If the model is null, the view is hidden.\n     * - The new view is set to have the same ID as the old view.\n     */\n    fun replaceView(previousView: View, model: EpoxyModel<*>?): View {\n        val newModel = model ?: run {\n            // No model added, so the view is hidden\n            previousView.isVisible = false\n            return previousView\n        }\n\n        val existingHolder = previousView.viewHolder\n\n        val viewHolder =\n            if (existingHolder == null || !newModel.hasSameViewType(existingHolder.model)) {\n                val parent = previousView.parent as ViewGroup\n                val newView = newModel.buildView(parent)\n                newView.id = previousView.id\n\n                val index = parent.indexOfChild(previousView)\n                parent.removeViewInLayout(previousView)\n                parent.addView(newView, index, previousView.layoutParams)\n\n                EpoxyViewHolder(parent, newView, false)\n            } else {\n                existingHolder\n            }\n\n        val newView = viewHolder.itemView.apply {\n            isVisible = true\n            id = previousView.id\n        }\n\n        bind(viewHolder, newModel, existingHolder?.model)\n        return newView\n    }\n\n    /**\n     * Takes an [EpoxyModel] added by the lambda, and creates a view for it in the given container.\n     * The container should be empty, and the view will be added to it and bound to the model. If\n     * the container was previously bound to another model, the existing view will be reused and\n     * updated if necessary.\n     *\n     * @param modelProvider this lambda should be used to add a model to the [ModelCollector]\n     * receiver. If no model is added the container will be cleared.\n     */\n    fun insertInto(container: ViewGroup, modelProvider: ModelCollector.() -> Unit) {\n        require(container.childCount <= 1) { \"Container cannot have more than one child\" }\n\n        // This lambda should add a model to the ModelCollector, which will end up calling\n        // \"addInternal\" and set tempModel\n        modelProvider()\n\n        val newModel = tempModel ?: run {\n            container.removeAllViews()\n            return\n        }\n\n        val existingView: View? = container.getChildAt(0)\n        val existingHolder = existingView?.viewHolder\n\n        val viewHolder =\n            if (existingHolder == null || !newModel.hasSameViewType(existingHolder.model)) {\n                container.removeAllViews()\n                val view = newModel.buildView(container)\n                container.addView(view)\n                EpoxyViewHolder(container, view, false)\n            } else {\n                existingHolder\n            }\n\n        bind(viewHolder, newModel, existingHolder?.model)\n        tempModel = null\n    }\n\n    /**\n     * Unbinds any model that is currently bound to this view. If no model is bound this is a no-op.\n     */\n    fun unbind(view: View) {\n        val viewHolder = view.viewHolder ?: return\n        viewHolder.unbind()\n        view.viewHolder = null\n    }\n\n    private fun bind(\n        viewHolder: EpoxyViewHolder,\n        newModel: EpoxyModel<*>,\n        existingModel: EpoxyModel<*>?\n    ) {\n        if (existingModel != newModel) {\n            viewHolder.bind(newModel, existingModel, emptyList(), 0)\n            viewHolder.itemView.viewHolder = viewHolder\n        }\n    }\n\n    private fun EpoxyModel<*>.hasSameViewType(model: EpoxyModel<*>): Boolean =\n        ViewTypeManager.getViewType(this) == ViewTypeManager.getViewType(model)\n\n    internal fun onException(exception: RuntimeException) {\n        globalExceptionHandler(this, exception)\n    }\n\n    companion object {\n        /**\n         * A callback to be notified when a recoverable exception occurs at runtime.  By default\n         * these are ignored and Epoxy will recover, but you can override this to be aware of when\n         * they happen.\n         * <p>\n         * For example, you could choose to rethrow the exception in development builds, or log\n         * them in production.\n         * <p>\n         * A common use for this is being aware of views not being found for the binder to populate\n         * with a model.\n         * <p>\n         * This callback will be used in all [EpoxyViewBinder] classes.\n         */\n        var globalExceptionHandler: ((EpoxyViewBinder, RuntimeException) -> Unit) = { _, _ -> }\n    }\n}\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/java/com/airbnb/epoxy/EpoxyViewBinderExtensions.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.content.res.Resources\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.annotation.IdRes\nimport androidx.core.app.ComponentActivity\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.OnLifecycleEvent\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n */\nfun ComponentActivity.epoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n */\nfun Fragment.epoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n */\nfun ViewGroup.epoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n *\n * @return a view binder or null if a view with the [viewId] could not be found.\n */\nfun ComponentActivity.optionalEpoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    val view = findViewById<View>(android.R.id.content)\n    // View id is not present, we just return null in that case.\n    if (view.maybeFindViewByIdName<View>(viewId, fallbackToNameLookup) == null) return@lazy null\n\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n *\n * @return a view binder or null if a view with the [viewId] could not be found.\n */\nfun Fragment.optionalEpoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: (LifecycleAwareEpoxyViewBinder.() -> Unit) = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    val view = view ?: error(\"Fragment view has not been created\")\n    // View id is not present, we just return null in that case.\n    if (view.maybeFindViewByIdName<View>(viewId, fallbackToNameLookup) == null) return@lazy null\n\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\n/**\n * Shortcut for creating a [LifecycleAwareEpoxyViewBinder] in a lazy way.\n * See [LifecycleAwareEpoxyViewBinder] for pass-through parameter documentation.\n *\n * @param initializer a lambda that is run directly after instantiation of the\n * [LifecycleAwareEpoxyViewBinder].\n *\n * @return a view binder or null if a view with the [viewId] could not be found.\n */\nfun ViewGroup.optionalEpoxyView(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit = { },\n    modelProvider: ModelCollector.(Context) -> Unit\n) = lazy {\n    val view = this\n    // View id is not present, we just return null in that case.\n    if (view.maybeFindViewByIdName<View>(viewId, fallbackToNameLookup) == null) return@lazy null\n\n    return@lazy epoxyViewInternal(\n        viewId = viewId,\n        useVisibilityTracking = useVisibilityTracking,\n        fallbackToNameLookup = fallbackToNameLookup,\n        initializer = initializer,\n        modelProvider = modelProvider\n    )\n}\n\nprivate fun ComponentActivity.epoxyViewInternal(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit,\n    modelProvider: ModelCollector.(Context) -> Unit\n) = LifecycleAwareEpoxyViewBinder(\n    this,\n    { findViewById(android.R.id.content) },\n    viewId,\n    useVisibilityTracking = useVisibilityTracking,\n    fallbackToNameLookup = fallbackToNameLookup,\n    modelProvider = modelProvider\n).apply(initializer)\n\nprivate fun Fragment.epoxyViewInternal(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit,\n    modelProvider: ModelCollector.(Context) -> Unit\n) = LifecycleAwareEpoxyViewBinder(\n    viewLifecycleOwner,\n    { view },\n    viewId,\n    useVisibilityTracking = useVisibilityTracking,\n    fallbackToNameLookup = fallbackToNameLookup,\n    modelProvider = modelProvider\n).apply(initializer)\n\nprivate fun ViewGroup.epoxyViewInternal(\n    @IdRes viewId: Int,\n    useVisibilityTracking: Boolean = false,\n    fallbackToNameLookup: Boolean = false,\n    initializer: LifecycleAwareEpoxyViewBinder.() -> Unit,\n    modelProvider: ModelCollector.(Context) -> Unit\n) = LifecycleAwareEpoxyViewBinder(\n    (this.context.unwrapContextForLifecycle() as? LifecycleOwner)\n        ?: error(\"LifecycleOwner required as view's context \"),\n    { this },\n    viewId,\n    useVisibilityTracking = useVisibilityTracking,\n    fallbackToNameLookup = fallbackToNameLookup,\n    modelProvider = modelProvider\n).apply(initializer)\n\n/**\n * Attempts to find this view's parent Activity in order to find its lifecycle owner. If this view's\n * `context` is a ContextWrapper it will continually unwrap it until it finds the Activity. If\n * no Activity is found it will return the the view's context.\n */\nprivate fun Context.unwrapContextForLifecycle(): Context {\n    var workingContext = this\n    while (workingContext is ContextWrapper) {\n        if (workingContext is Activity) {\n            return workingContext\n        }\n        workingContext = workingContext.baseContext\n    }\n    return this\n}\n\n/**\n * This class uses an epoxy model to update a view. The view reference is cleared when the fragment\n * is stopped. Call [invalidate] to have the model rebuilt and rebound to the view.\n *\n * @param rootView a lambda returning the parent [ViewGroup] that will be used to search for the\n * [viewId].\n * @param viewId the ID of the view stub that the Epoxy view should replace. This tells the\n * view binder where in the layout to put the view. This should correspond to a view of type\n * [EpoxyViewStub] for state restoration reasons.\n * @param useVisibilityTracking true to get visibility callbacks using a partial impression\n * percentage threshold of 100%, false to not track view visibility. See\n * [EpoxyViewBinderVisibilityTracker] for more information.\n * @param fallbackToNameLookup true to also include searching by the entry name\n * ([Resources.getResourceEntryName]) should the [viewId] not be found. Useful for dynamic features\n * as it's possible the generated ID is not the same should the same view ID exist in both the base\n * APK and the dynamic feature.\n * @param modelProvider a lambda for building the [EpoxyModel]. It expects a single model to be\n * added to the controller receiver. If no model is added the view will be hidden.\n */\nclass LifecycleAwareEpoxyViewBinder(\n    private val lifecycleOwner: LifecycleOwner,\n    private val rootView: (() -> View?),\n    @IdRes private val viewId: Int,\n    private val useVisibilityTracking: Boolean = false,\n    private val fallbackToNameLookup: Boolean = false,\n    private val modelProvider: ModelCollector.(Context) -> Unit,\n) : LifecycleObserver {\n    private val viewBinder = EpoxyViewBinder()\n    private var lazyView: View? = null\n\n    private val visibilityTracker: EpoxyViewBinderVisibilityTracker by lazy {\n        EpoxyViewBinderVisibilityTracker().apply {\n            this.partialImpressionThresholdPercentage = 100\n        }\n    }\n\n    val view: View\n        get() {\n            if (lazyView == null) {\n                val nonNullRootView = rootView() ?: error(\"Root view is not created\")\n                lazyView = nonNullRootView.maybeFindViewByIdName(viewId, fallbackToNameLookup)\n                    ?: error(\n                        \"View could not be found, fallbackToNameLookup: $fallbackToNameLookup,\" +\n                            \" view id name: ${nonNullRootView.resources.getResourceEntryName(viewId)}\"\n                    )\n                // Propagate an error if a non EpoxyViewStub is used\n                if (lazyView !is EpoxyViewStub) {\n                    val resourceNameWithFallback = try {\n                        nonNullRootView.resources.getResourceName(viewId)\n                    } catch (e: Resources.NotFoundException) {\n                        \"$viewId (name not found)\"\n                    }\n                    viewBinder.onException(\n                        IllegalStateException(\n                            \"View binder should be using EpoxyViewStub. \" +\n                                \"View ID: $resourceNameWithFallback\"\n                        )\n                    )\n                }\n\n                // Register this for view lifecycle callbacks so that it can clear the view when it\n                // is destroyed. This both prevents a memory leak, and ensures that if the view is\n                // recreated it can look up the reference again. This MUST register the observer\n                // again each time the view is created because the fragment's viewLifecycleOwner\n                // is updated to a new instance for each new fragment view.\n                lifecycleOwner.lifecycle.addObserver(this)\n            }\n\n            return lazyView!!\n        }\n\n    /**\n     * Replace or update the [View] with the model produced by the [modelProvider] lambda, depending\n     * on if the view for the model is the same as the existing view.\n     *\n     * @see [EpoxyViewBinder.replaceView]\n     */\n    fun invalidate() {\n        lazyView = viewBinder.replaceView(view, modelProvider).also {\n            if (useVisibilityTracking) {\n                visibilityTracker.attach(it)\n            }\n        }\n    }\n\n    /**\n     * Unbinds the [EpoxyViewBinder]. It is normally not necessary to call this as this object\n     * registers itself with the provided [lifecycleOwner].\n     */\n    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)\n    fun onViewDestroyed() {\n        lazyView?.let { viewBinder.unbind(it) }\n        lazyView = null\n        if (useVisibilityTracking) {\n            visibilityTracker.detach()\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/java/com/airbnb/epoxy/EpoxyViewBinderVisibilityTracker.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.util.Log\nimport android.util.SparseArray\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.ViewTreeObserver\nimport androidx.annotation.IdRes\nimport androidx.annotation.IntRange\nimport androidx.core.view.isVisible\nimport androidx.recyclerview.widget.RecyclerView\nimport com.airbnb.viewmodeladapter.R\nimport java.util.HashMap\n\n/**\n * A simple way to track visibility events on [EpoxyModel] within an [EpoxyViewBinder].\n *\n * [EpoxyViewBinderVisibilityTracker] works with any [View] backed by an [EpoxyModel]. Once attached\n * the events will be forwarded to the Epoxy model (or to the Epoxy view when using annotations).\n *\n * **There are a few exceptions where events are not forwarded:**\n *  * If a model is replaced with a model of the same class a new impression will not be logged.\n *  This is due to the view being the same instance and no insight into view holder changes.\n *  * View binders in scrollable views will only forward the initial visibility state. New events\n *  will not be emitted on scroll actions. This is due to not knowing when the outer view scrolls.\n */\nclass EpoxyViewBinderVisibilityTracker {\n\n    /** Maintain visibility item indexed by view id (identity hashcode)  */\n    private val visibilityIdToItemMap = SparseArray<EpoxyVisibilityItem>()\n\n    /**\n     * Enable or disable visibility changed event. Default is `true`, disable it if you don't need\n     * (triggered by every pixel scrolled).\n     *\n     * @see OnVisibilityChanged\n     *\n     * @see OnModelVisibilityChangedListener\n     */\n    var onChangedEnabled = true\n\n    /** The view that's currently attached and whose layout is being observed. */\n    private var attachedView: View? = null\n\n    /** The listener for the currently attached view. */\n    private var attachedListener: Listener? = null\n\n    /** All nested visibility trackers  */\n    private val nestedTrackers: MutableMap<RecyclerView, EpoxyVisibilityTracker> = HashMap()\n\n    /**\n     * The threshold of percentage visible area to identify the partial impression view state. This\n     * is in the range of [0..100] and defaults to `null`, which disables\n     * [VisibilityState.PARTIAL_IMPRESSION_VISIBLE] and\n     * [VisibilityState.PARTIAL_IMPRESSION_INVISIBLE] events.\n     */\n    @setparam:IntRange(from = 0, to = 100)\n    var partialImpressionThresholdPercentage: Int? = null\n\n    /**\n     * Attaches the tracker.\n     *\n     * @param view The view that is backed by an [EpoxyModel].\n     */\n    fun attach(view: View) {\n        if (attachedView !== view) {\n            // Detach the old view if it exists because there is a different view\n            detach()\n        }\n        attachedView = view\n        attachedListener = Listener(view)\n\n        // When reattaching the view, process the children even if the view instance is the same.\n        // Since the view could have been recycled to be bound to another model, make sure the\n        // callback is happening on the appropriate model instance.\n        processChild(view, false, \"attach\")\n        (view as? RecyclerView)?.let {\n            processChildRecyclerViewAttached(it)\n        }\n    }\n\n    /**\n     * Detaches the tracker.\n     */\n    fun detach() {\n        attachedView?.let { view ->\n            processChild(view, true, \"detach\")\n            (view as? RecyclerView)?.let {\n                processChildRecyclerViewDetached(it)\n            }\n        }\n        attachedView = null\n        attachedListener?.detach()\n    }\n\n    /**\n     * Process visibility events for a view and propagate to children of a model group if needed.\n     */\n    private fun processChild(child: View, detachEvent: Boolean, eventOriginForDebug: String) {\n        child.viewHolder?.let { viewHolder ->\n            val epoxyHolder = viewHolder.holder\n            processChild(child, detachEvent, eventOriginForDebug, viewHolder)\n            if (epoxyHolder is ModelGroupHolder) {\n                processModelGroupChildren(epoxyHolder, detachEvent, eventOriginForDebug)\n            }\n        }\n    }\n\n    /**\n     * Loop through the children of the model group and process visibility events on each one in\n     * relation to the model group's layout. This will attach or detach trackers to any nested\n     * [RecyclerView]s.\n     *\n     * @param epoxyHolder         the [ModelGroupHolder] with children to process\n     * @param detachEvent         true if the child was just detached\n     * @param eventOriginForDebug a debug strings used for logs\n     */\n    private fun processModelGroupChildren(\n        epoxyHolder: ModelGroupHolder,\n        detachEvent: Boolean,\n        eventOriginForDebug: String\n    ) {\n        // Iterate through models in the group and process each of them instead of the group\n        for (groupChildHolder in epoxyHolder.viewHolders) {\n            // Since the group is likely using a ViewGroup other than a RecyclerView we need to\n            // handle the potential of a nested RecyclerView.\n            (groupChildHolder.itemView as? RecyclerView)?.let {\n                if (detachEvent) {\n                    processChildRecyclerViewDetached(it)\n                } else {\n                    processChildRecyclerViewAttached(it)\n                }\n            }\n            processChild(\n                groupChildHolder.itemView,\n                detachEvent,\n                eventOriginForDebug,\n                groupChildHolder\n            )\n        }\n    }\n\n    /**\n     * Process visibility events for a view and propagate to a nested tracker if the view is a\n     * [RecyclerView].\n     */\n    private fun processChild(\n        child: View,\n        detachEvent: Boolean,\n        eventOriginForDebug: String,\n        viewHolder: EpoxyViewHolder\n    ) {\n        val changed = processVisibilityEvents(viewHolder, detachEvent, eventOriginForDebug)\n        if (changed && child is RecyclerView) {\n            val tracker = nestedTrackers[child]\n            tracker?.requestVisibilityCheck()\n        }\n    }\n\n    /** Attach a tracker to a nested [RecyclerView]. */\n    private fun processChildRecyclerViewAttached(childRecyclerView: RecyclerView) {\n        // Register itself in the EpoxyVisibilityTracker. This will take care of nested list\n        // tracking (ex: carousel)\n        var tracker = getTracker(childRecyclerView)\n        if (tracker == null) {\n            tracker = EpoxyVisibilityTracker()\n            tracker.partialImpressionThresholdPercentage = partialImpressionThresholdPercentage\n            tracker.attach(childRecyclerView)\n        }\n        nestedTrackers[childRecyclerView] = tracker\n    }\n\n    /** Detach trackers from a nested [RecyclerView]. */\n    private fun processChildRecyclerViewDetached(childRecyclerView: RecyclerView) {\n        nestedTrackers.remove(childRecyclerView)\n    }\n\n    /**\n     * Call this method every time something related to the UI changes\n     * (visibility, screen position, etc).\n     *\n     * @param epoxyHolder the view holder for the view.\n     * @return true if changed\n     */\n    private fun processVisibilityEvents(\n        epoxyHolder: EpoxyViewHolder,\n        detachEvent: Boolean,\n        eventOriginForDebug: String\n    ): Boolean {\n        if (DEBUG_LOG) {\n            Log.d(\n                TAG,\n                \"$eventOriginForDebug.processVisibilityEvents \" +\n                    \"${System.identityHashCode(epoxyHolder)}, $detachEvent\"\n            )\n        }\n        val itemView = epoxyHolder.itemView\n        val id = System.identityHashCode(itemView)\n        var vi = visibilityIdToItemMap[id]\n        if (vi == null) {\n            // New view discovered, assign an EpoxyVisibilityItem\n            vi = EpoxyVisibilityItem()\n            visibilityIdToItemMap.put(id, vi)\n        }\n        var changed = false\n        val parent = itemView.parent as? ViewGroup ?: return changed\n        if (vi.update(itemView, parent, detachEvent)) {\n            // View is measured, process events\n            vi.handleVisible(epoxyHolder, detachEvent)\n            if (partialImpressionThresholdPercentage != null) {\n                vi.handlePartialImpressionVisible(\n                    epoxyHolder,\n                    detachEvent,\n                    partialImpressionThresholdPercentage!!\n                )\n            }\n            vi.handleFocus(epoxyHolder, detachEvent)\n            vi.handleFullImpressionVisible(epoxyHolder, detachEvent)\n            changed = vi.handleChanged(epoxyHolder, onChangedEnabled)\n        }\n        return changed\n    }\n\n    private inner class Listener(private val view: View) : ViewTreeObserver.OnGlobalLayoutListener {\n\n        init {\n            view.viewTreeObserver.addOnGlobalLayoutListener(this)\n        }\n\n        override fun onGlobalLayout() {\n            processChild(view, !view.isVisible, \"onGlobalLayout\")\n        }\n\n        fun detach() {\n            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {\n                view.viewTreeObserver.removeOnGlobalLayoutListener(this)\n            } else {\n                view.viewTreeObserver.removeGlobalOnLayoutListener(this)\n            }\n        }\n    }\n\n    companion object {\n        private const val TAG = \"EpoxyVBVisTracker\"\n\n        // Not actionable at runtime. It is only useful for internal test-troubleshooting.\n        const val DEBUG_LOG = false\n\n        @IdRes\n        private val TAG_ID = R.id.epoxy_visibility_tracker\n\n        private fun getTracker(recyclerView: RecyclerView): EpoxyVisibilityTracker? {\n            return recyclerView.getTag(TAG_ID) as EpoxyVisibilityTracker?\n        }\n    }\n}\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/java/com/airbnb/epoxy/EpoxyViewStub.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.Context\nimport android.os.Parcelable\nimport android.util.AttributeSet\nimport android.view.View\n\n/**\n * A view to be used with [EpoxyViewBinder] when an epoxy model is used outside of a RecyclerView. This view will be\n * replaced completely when a model is bound to it.\n */\nclass EpoxyViewStub @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : View(context, attrs, defStyleAttr) {\n\n    override fun onRestoreInstanceState(state: Parcelable?) {\n        // Restoring the state is not supported due to EpoxyViewBinder having replaced this view with another view type.\n        // If the activity/fragment is restoring its state, it's possible that EpoxyViewBinder has not yet replaced this\n        // view with the type that was used prior to saving the state. This would mean that the view types will differ\n        // during the state restoration process since EpoxyViewBinder uses the same view ID for the replacement view.\n        // This can cause crashes because the saved state types will differ (e.g. a RecyclerView's SavedState cannot be\n        // applied to a normal View). To solve this, ignore any state restoration as this is an empty view and never\n        // shows anything.\n        super.onRestoreInstanceState(null)\n    }\n}\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/java/com/airbnb/epoxy/ViewExtensions.kt",
    "content": "package com.airbnb.epoxy\n\nimport android.content.res.Resources\nimport android.util.Log\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.core.view.children\nimport com.airbnb.epoxy.viewbinder.R\n\n/**\n * Shortcut for getting/setting an [EpoxyViewHolder] on a [View]'s tag.\n */\ninternal var View.viewHolder: EpoxyViewHolder?\n    set(value) = setTag(R.id.epoxy_view_binder, value)\n    get() = getTag(R.id.epoxy_view_binder) as EpoxyViewHolder?\n\n/**\n * Finds a view with the resource ID using [ViewGroup.findViewById]. Should a view _not_ be found\n * and the [fallbackToNameLookup] is true, then this recursively iterates through all children and\n * tries to find a match based on [View.idName]. This is useful if using dynamic features. For\n * example, if there is a layout provided by a dynamic feature with an ID for a view, and a view\n * in the base APK that also uses that same view ID, the ID resource will be different but\n * the name will be the same.\n */\n@PublishedApi\ninternal inline fun <reified V : View> View.maybeFindViewByIdName(\n    id: Int,\n    fallbackToNameLookup: Boolean\n): V? =\n    findViewById(id) ?: run {\n        if (!fallbackToNameLookup || id == -1) return@run null\n\n        try {\n            resources?.getResourceEntryName(id)\n        } catch (e: Resources.NotFoundException) {\n            Log.e(\n                \"ViewBinderViewExt\",\n                \"Id not found in ${this::class}, fallbackToNameLookup: $fallbackToNameLookup, \" +\n                    \"error message: ${e.localizedMessage}\"\n            )\n            null\n        }?.let { idName ->\n            findViewByIdName(this, idName)\n        }\n    }\n\n/**\n * Searches itself and all children, including nested children, for a view that has the [idName] for\n * its [View.idName]. Returns the found view or null if no view is found.\n */\n@PublishedApi\ninternal inline fun <reified V : View> findViewByIdName(view: View, idName: String): V? {\n    // The view instance check is not necessary but is done to avoid looking up id name for all\n    // views as an optimization\n    if (view is V && view.idName == idName) return view\n\n    if (view is ViewGroup) {\n        return view.allRecursiveChildren.filterIsInstance<V>()\n            .firstOrNull { it.idName == idName }\n    }\n\n    return null\n}\n\n/**\n * Use [Resources.getResourceEntryName] to get the name of the ID from the resource ID. Returns\n * null if the View's ID is -1 or does not exist.\n */\n@PublishedApi\ninternal val View.idName: String?\n    get() = try {\n        if (id != -1) resources?.getResourceEntryName(id) else null\n    } catch (e: Resources.NotFoundException) {\n        null\n    }\n\n/**\n * Returns every child view nested at all layers inside this ViewGroup.\n */\n@PublishedApi\ninternal val ViewGroup.allRecursiveChildren: Sequence<View>\n    get() {\n        return children.flatMap {\n            sequenceOf(it) + if (it is ViewGroup) it.allRecursiveChildren else emptySequence()\n        }\n    }\n"
  },
  {
    "path": "epoxy-viewbinder/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"epoxy_view_binder\" type=\"id\" />\n</resources>"
  },
  {
    "path": "epoxy-viewbinder/src/test/java/com/example/epoxy_viewbinder/EpoxyViewBinderTest.kt",
    "content": "package com.example.epoxy_viewbinder\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.ViewParent\nimport android.widget.FrameLayout\nimport androidx.test.core.app.ApplicationProvider\nimport com.airbnb.epoxy.EpoxyHolder\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.EpoxyViewBinder\nimport org.junit.After\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertNotNull\nimport org.junit.Assert.assertNull\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.robolectric.RobolectricTestRunner\n\n@RunWith(RobolectricTestRunner::class)\nclass EpoxyViewBinderTest {\n\n    private val epoxyViewBinder = EpoxyViewBinder()\n\n    private val context: Context\n        get() = ApplicationProvider.getApplicationContext()\n    private val view = View(context)\n    private val viewGroup = FrameLayout(context)\n    private val currentView: View\n        get() = viewGroup.getChildAt(0) // We always have children in viewGroup\n\n    private val viewModel = EpoxyModelMock()\n    private val viewHolderModel = EpoxyModelWithHolderMock()\n\n    @Before\n    fun setUp() {\n        viewGroup.addView(view)\n    }\n\n    @After\n    fun tearDown() {\n        viewGroup.removeAllViews()\n    }\n\n    @Test\n    fun bindWithView() {\n        epoxyViewBinder.replaceView(view, viewModel)\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        // A new view is added\n        assertEquals(viewGroup, currentView.parent)\n        // New view is bound to EpoxyModel\n        assertEquals(currentView, viewModel.boundView)\n    }\n\n    @Test\n    fun bindWithView_usingModelProvider() {\n        epoxyViewBinder.replaceView(view) {\n            add(viewModel)\n        }\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        // A new view is added\n        assertEquals(viewGroup, currentView.parent)\n        // New view is bound to EpoxyModel\n        assertEquals(currentView, viewModel.boundView)\n    }\n\n    @Test\n    fun bindWithViewHolder() {\n        epoxyViewBinder.replaceView(view, viewHolderModel)\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        // A new view is added\n        assertEquals(viewGroup, currentView.parent)\n        // New view is bound to ViewHolder\n        assertEquals(currentView, viewHolderModel.boundHolder?.boundView)\n    }\n\n    @Test\n    fun bindWithViewHolder_usingModelProvider() {\n        epoxyViewBinder.replaceView(view) {\n            add(viewHolderModel)\n        }\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        // A new view is added\n        assertEquals(viewGroup, currentView.parent)\n        // New view is bound to ViewHolder\n        assertEquals(currentView, viewHolderModel.boundHolder?.boundView)\n    }\n\n    @Test\n    fun bindWithViewGroup() {\n        val newView = epoxyViewBinder.replaceOrCreateView(viewGroup, view, viewModel)\n\n        // Old view is retained as it doesn't have a model bound to it\n        assertNotNull(view.parent)\n        assertEquals(viewGroup, currentView.parent)\n        // No new view is added\n        assertEquals(1, viewGroup.childCount)\n        assertNull(newView.parent)\n        // New view is bound to EpoxyModel\n        assertEquals(newView, viewModel.boundView)\n    }\n\n    @Test\n    fun bindWithViewGroup_modelUpdate() {\n        epoxyViewBinder.replaceView(view, viewModel)\n        val newViewModel = EpoxyModelMock()\n        val newView = epoxyViewBinder.replaceOrCreateView(viewGroup, currentView, newViewModel)\n\n        // No new view added and current view is still in the layout\n        assertEquals(1, viewGroup.childCount)\n        assertEquals(viewGroup, currentView.parent)\n        assertEquals(currentView, newView)\n        assertEquals(currentView, newViewModel.boundView)\n    }\n\n    @Test\n    fun unbindWithoutBindWillNoOp() {\n        epoxyViewBinder.unbind(view)\n\n        // Won't crash because we are no-op if no model is bound\n    }\n\n    @Test\n    fun unbindWithViewBound() {\n        epoxyViewBinder.replaceView(view, viewModel)\n        epoxyViewBinder.unbind(currentView)\n\n        // View is unbound from EpoxyModel\n        assertNull(viewModel.boundView)\n    }\n\n    @Test\n    fun unbindWithViewHolderBound() {\n        epoxyViewBinder.replaceView(view, viewHolderModel)\n        epoxyViewBinder.unbind(currentView)\n\n        // Holder is unbound from Model\n        assertNull(viewHolderModel.boundHolder)\n    }\n\n    @Test\n    fun insertInto() {\n        epoxyViewBinder.insertInto(viewGroup) {\n            add(viewModel)\n        }\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        // A new view is added\n        assertEquals(viewGroup, currentView.parent)\n        // New view is bound to EpoxyModel\n        assertEquals(currentView, viewModel.boundView)\n    }\n\n    @Test\n    fun insertInto_noModelAddedClearsContainer() {\n        epoxyViewBinder.insertInto(viewGroup) { }\n\n        // Old view is removed from parent\n        assertNull(view.parent)\n        assertEquals(0, viewGroup.childCount)\n    }\n\n    @Test(expected = IllegalArgumentException::class)\n    fun insertInto_tooManyChildren() {\n        viewGroup.addView(View(context))\n\n        epoxyViewBinder.insertInto(viewGroup) {\n            add(viewModel)\n        }\n    }\n}\n\nprivate class EpoxyHolderMock : EpoxyHolder() {\n    var boundView: View? = null\n    override fun bindView(itemView: View) {\n        boundView = itemView\n    }\n}\n\nprivate class EpoxyModelMock : EpoxyModel<View>() {\n    var boundView: View? = null\n\n    override fun getDefaultLayout() = 1\n\n    override fun buildView(parent: ViewGroup) = createView()\n\n    override fun bind(view: View) {\n        boundView = view\n    }\n\n    override fun unbind(view: View) {\n        if (boundView == view) {\n            boundView = null\n        }\n    }\n}\n\nprivate class EpoxyModelWithHolderMock : EpoxyModelWithHolder<EpoxyHolderMock>() {\n    var boundHolder: EpoxyHolderMock? = null\n\n    override fun getDefaultLayout() = 2\n\n    override fun buildView(parent: ViewGroup) = createView()\n\n    override fun createNewHolder(parent: ViewParent) = EpoxyHolderMock()\n\n    override fun bind(holder: EpoxyHolderMock) {\n        boundHolder = holder\n    }\n\n    override fun unbind(holder: EpoxyHolderMock) {\n        if (boundHolder == holder) {\n            boundHolder = null\n        }\n    }\n}\n\nprivate fun createView() = View(ApplicationProvider.getApplicationContext())\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.13-all.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "VERSION_NAME=5.2.1\nGROUP=com.airbnb.android\nPOM_DESCRIPTION=Epoxy is a system for composing complex screens with a ReyclerView in Android.\nPOM_URL=https://github.com/airbnb/epoxy\nPOM_SCM_URL=https://github.com/airbnb/epoxy\nPOM_SCM_CONNECTION=scm:git@github.com:airbnb/epoxy.git\nPOM_SCM_DEV_CONNECTION=scm:git@github.com:airbnb/epoxy.git\nPOM_LICENCE_NAME=Apache-2.0\nPOM_LICENCE_URL=https://github.com/airbnb/epoxy/blob/master/LICENSE\nPOM_LICENCE_DIST=repo\nPOM_DEVELOPER_ID=airbnb\nPOM_DEVELOPER_NAME=Airbnb\nPOM_DEVELOPER_EMAIL=android@airbnb.com\nPOM_INCEPTION_YEAR=2016\n\nandroid.useAndroidX=true\nandroid.enableJetifier=false\nandroid.nonFinalResIds=false\n\norg.gradle.parallel=true\norg.gradle.caching=true\norg.gradle.configuration-cache=true\n\n# Publishing configuration for vanniktech/gradle-maven-publish-plugin\nmavenCentralPublishing=true\n# Signing can be disabled with -PdoNotSignRelease=true\nsignAllPublications=true\nmavenCentralAutomaticPublishing=true\n\n# Dokka fails without a larger metaspace https://github.com/Kotlin/dokka/issues/1405\norg.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=2g\nkapt.include.compile.classpath=false\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    \n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "kotlinsample/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "kotlinsample/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\n\nandroid {\n  namespace 'com.airbnb.epoxy.kotlinsample'\n\n  defaultConfig {\n    applicationId \"com.airbnb.epoxy.kotlinsample\"\n    compileSdk rootProject.COMPILE_SDK_VERSION\n    minSdkVersion rootProject.MIN_SDK_VERSION\n    targetSdkVersion rootProject.TARGET_SDK_VERSION\n    versionCode 1\n    versionName \"1.0\"\n  }\n\n  dataBinding {\n    enabled = true\n  }\n  viewBinding {\n    enabled = true\n  }\n\n}\n\nkotlin {\n  jvmToolchain(17)\n}\n\ndependencies {\n  implementation rootProject.deps.androidRecyclerView\n  implementation rootProject.deps.androidAppcompat\n  implementation project(':epoxy-databinding')\n  implementation project(':epoxy-adapter')\n  implementation project(':epoxy-annotations')\n  implementation project(':epoxy-viewbinder')\n\n  kapt project(':epoxy-processor')\n  kaptTest project(\":epoxy-processor\")\n\n  testImplementation rootProject.deps.robolectric\n  testImplementation rootProject.deps.junit\n  testImplementation rootProject.deps.mockito\n}\n"
  },
  {
    "path": "kotlinsample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "kotlinsample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity android:name=\".StickyHeaderActivity\"/>\n        <activity android:name=\".DragAndDropActivity\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/DragAndDropActivity.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.View\nimport android.widget.Toast\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.EpoxyTouchHelper\nimport com.airbnb.epoxy.TypedEpoxyController\n\nclass DragAndDropActivity : AppCompatActivity() {\n    private lateinit var recyclerView: EpoxyRecyclerView\n    private var fruits = mutableListOf(\n        \"Apples\",\n        \"Blueberries\",\n        \"Bananas\",\n        \"Oranges\",\n        \"Dragon fruit\",\n        \"Mango\",\n        \"Avocado\",\n        \"Lychee\"\n    )\n\n    private var epoxyController = object : TypedEpoxyController<List<String>>() {\n\n        override fun buildModels(data: List<String>?) {\n            data?.forEach { fruit ->\n                dataBindingItem {\n                    id(\"data binding $fruit\")\n                    text(fruit)\n                    onClick { _ ->\n                        Toast.makeText(\n                            this@DragAndDropActivity,\n                            \"clicked $fruit\",\n                            Toast.LENGTH_LONG\n                        ).show()\n                    }\n                    onVisibilityStateChanged { model, view, visibilityState ->\n                        Log.d(TAG, \"$model -> $visibilityState\")\n                    }\n                }\n            }\n        }\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity)\n        findViewById<View>(R.id.epoxy_view_stub)?.visibility = View.GONE\n\n        recyclerView = findViewById(R.id.recycler_view)\n\n        EpoxyTouchHelper.initDragging(epoxyController)\n            .withRecyclerView(recyclerView)\n            .forVerticalList()\n            .forAllModels()\n            .andCallbacks(object : EpoxyTouchHelper.DragCallbacks<EpoxyModel<*>>() {\n                override fun onModelMoved(\n                    fromPosition: Int,\n                    toPosition: Int,\n                    modelBeingMoved: EpoxyModel<*>?,\n                    itemView: View?\n                ) {\n                    Log.d(TAG, \"onModelMoved from:$fromPosition -> to:$toPosition\")\n                    val removed = fruits.removeAt(fromPosition)\n                    fruits.add(toPosition, removed)\n                    epoxyController.setData(fruits)\n                }\n            })\n\n        recyclerView.layoutManager = LinearLayoutManager(this)\n        recyclerView.setController(epoxyController)\n        epoxyController.setData(fruits)\n    }\n\n    companion object {\n        private const val TAG = \"DragAndDropActivity\"\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/EpoxyDataBindingPatterns.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport com.airbnb.epoxy.EpoxyDataBindingPattern\n\n@EpoxyDataBindingPattern(rClass = R::class, layoutPrefix = \"epoxy_layout\")\nobject EpoxyDataBindingPatterns\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/MainActivity.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.content.Intent\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.util.Log\nimport android.widget.Toast\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.EpoxyVisibilityTracker\nimport com.airbnb.epoxy.epoxyView\nimport com.airbnb.epoxy.group\nimport com.airbnb.epoxy.kotlinsample.helpers.carouselNoSnapBuilder\nimport com.airbnb.epoxy.kotlinsample.models.ItemDataClass\nimport com.airbnb.epoxy.kotlinsample.models.ItemViewBindingDataClass\nimport com.airbnb.epoxy.kotlinsample.models.carouselItemCustomView\nimport com.airbnb.epoxy.kotlinsample.models.coloredSquareView\nimport com.airbnb.epoxy.kotlinsample.models.decoratedLinearGroup\nimport com.airbnb.epoxy.kotlinsample.models.itemCustomView\nimport com.airbnb.epoxy.kotlinsample.models.itemEpoxyHolder\nimport com.airbnb.epoxy.kotlinsample.models.itemViewBindingEpoxyHolder\nimport com.airbnb.epoxy.kotlinsample.models.manualLayoutParamsView\n\nclass MainActivity : AppCompatActivity() {\n    private lateinit var recyclerView: EpoxyRecyclerView\n\n    private val viewBinder by epoxyView(\n        viewId = R.id.epoxy_view_stub,\n        initializer = { },\n        modelProvider = {\n            itemCustomView {\n                id(\"view binder\")\n                color(Color.BLACK)\n                title(\"Epoxy view outside of the RecyclerView\")\n                onVisibilityStateChanged { _, _, visibilityState ->\n                    Log.d(TAG, \"ViewBinder -> $visibilityState\")\n                }\n                listener { _ ->\n                    Toast.makeText(this@MainActivity, \"ViewBinder clicked\", Toast.LENGTH_LONG).show()\n                }\n            }\n        },\n        useVisibilityTracking = true\n    )\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity)\n\n        viewBinder.invalidate()\n\n        recyclerView = findViewById(R.id.recycler_view)\n\n        // Attach the visibility tracker to the RecyclerView. This will enable visibility events.\n        val epoxyVisibilityTracker = EpoxyVisibilityTracker()\n        epoxyVisibilityTracker.partialImpressionThresholdPercentage = 75\n        epoxyVisibilityTracker.attach(recyclerView)\n\n        recyclerView.withModels {\n\n            manualLayoutParamsView {\n                id(\"manualLayoutParams\")\n                title(\"This is a ModelView using ManualLayoutParams\")\n            }\n\n            group {\n                id(\"epoxyModelGroupDsl\")\n                layout(R.layout.vertical_linear_group)\n\n                coloredSquareView {\n                    id(\"coloredSquareView 1\")\n                    color(Color.DKGRAY)\n                    onVisibilityStateChanged { model, _, visibilityState ->\n                        Log.d(TAG, \"$model -> $visibilityState\")\n                    }\n                }\n\n                coloredSquareView {\n                    id(\"coloredSquareView 2\")\n                    color(Color.GRAY)\n                }\n\n                coloredSquareView {\n                    id(\"coloredSquareView 3\")\n                    color(Color.LTGRAY)\n                }\n\n                carouselNoSnapBuilder {\n                    id(\"nested carousel\")\n                    val lastPage = 10\n                    for (i in 0 until lastPage) {\n                        carouselItemCustomView {\n                            id(\"nested carousel $i\")\n                            title(\"Page $i / $lastPage\")\n                            onVisibilityStateChanged { model, _, visibilityState ->\n                                Log.d(TAG, \"pos: $i ${model.javaClass} -> $visibilityState\")\n                            }\n                        }\n                    }\n                }\n            }\n\n            decoratedLinearGroup {\n                id(\"epoxyModelGroupWithLayoutDsl\")\n\n                coloredSquareView {\n                    id(\"coloredSquareView 1\")\n                    color(Color.DKGRAY)\n                }\n\n                coloredSquareView {\n                    id(\"coloredSquareView 2\")\n                    color(Color.GRAY)\n                }\n\n                coloredSquareView {\n                    id(\"coloredSquareView 3\")\n                    color(Color.LTGRAY)\n                }\n            }\n\n            for (i in 0 until 100) {\n                dataBindingItem {\n                    id(\"data binding $i\")\n                    text(\"this is a data binding model2\")\n                    onClick { _ ->\n                        Toast.makeText(this@MainActivity, \"clicked\", Toast.LENGTH_LONG).show()\n                    }\n                    onVisibilityStateChanged { model, view, visibilityState ->\n                        Log.d(TAG, \"$model -> $visibilityState\")\n                    }\n                }\n\n                itemCustomView {\n                    id(\"custom view $i\")\n                    color(Color.GREEN)\n                    title(\"Open sticky header activity\")\n                    listener { _ ->\n                        Toast.makeText(this@MainActivity, \"clicked\", Toast.LENGTH_LONG).show()\n                        startActivity(Intent(this@MainActivity, StickyHeaderActivity::class.java))\n                    }\n                }\n\n                itemCustomView {\n                    id(\"custom view $i\")\n                    color(Color.MAGENTA)\n                    title(\"Open Drag and Dropt activity\")\n                    listener { _ ->\n                        Toast.makeText(this@MainActivity, \"clicked\", Toast.LENGTH_LONG).show()\n                        startActivity(Intent(this@MainActivity, DragAndDropActivity::class.java))\n                    }\n                }\n\n                itemEpoxyHolder {\n                    id(\"view holder $i\")\n                    title(\"this is a View Holder item\")\n                    listener {\n                        Toast.makeText(this@MainActivity, \"clicked\", Toast.LENGTH_LONG)\n                            .show()\n                    }\n                }\n\n                itemViewBindingEpoxyHolder {\n                    id(\"view binding $i\")\n                    title(\"This is a ViewBinding item\")\n                    listener {\n                        Toast.makeText(this@MainActivity, \"clicked\", Toast.LENGTH_LONG)\n                            .show()\n                    }\n                }\n\n                carouselNoSnapBuilder {\n                    id(\"carousel $i\")\n                    val lastPage = 10\n                    for (j in 0 until lastPage) {\n                        carouselItemCustomView {\n                            id(\"carousel $i-$j\")\n                            title(\"Page $j / $lastPage\")\n                        }\n                    }\n                }\n\n                // Since data classes do not use code generation, there's no extension generated here\n                ItemDataClass(\"this is a Data Class Item\")\n                    .id(\"data class $i\")\n                    .addTo(this)\n\n                ItemViewBindingDataClass(\"This is a Data Class Item using ViewBinding\")\n                    .id(\"data class view binding $i\")\n                    .addTo(this)\n            }\n        }\n    }\n\n    companion object {\n        private const val TAG = \"MainActivity\"\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/StickyHeaderActivity.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\nimport com.airbnb.epoxy.EpoxyRecyclerView\nimport com.airbnb.epoxy.stickyheader.StickyHeaderLinearLayoutManager\n\n/**\n * Shows an activity with sticky header using\n * [StickyHeaderLinearLayoutManager]\n */\nclass StickyHeaderActivity : AppCompatActivity() {\n    private lateinit var recyclerView: EpoxyRecyclerView\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity)\n\n        findViewById<View>(R.id.epoxy_view_stub)?.visibility = View.GONE\n\n        recyclerView = findViewById(R.id.recycler_view)\n\n//        Sample usage when using [EpoxyAdapter]\n//        recyclerView.layoutManager = StickyHeaderLinearLayoutManager(this)\n//        recyclerView.adapter = StickyHeaderAdapter(this)\n\n        recyclerView.layoutManager = StickyHeaderLinearLayoutManager(this)\n        recyclerView.setController(StickyHeaderController(this))\n        recyclerView.requestModelBuild()\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/StickyHeaderAdapter.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.content.Context\nimport android.widget.Toast\nimport com.airbnb.epoxy.EpoxyAdapter\nimport com.airbnb.epoxy.kotlinsample.models.ItemEpoxyHolder_\nimport com.airbnb.epoxy.kotlinsample.models.StickyItemEpoxyHolder\nimport com.airbnb.epoxy.kotlinsample.models.StickyItemEpoxyHolder_\nimport com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks\n\n/**\n * Showcases [EpoxyAdapter] with sticky header support\n */\nclass StickyHeaderAdapter(\n    private val context: Context\n) : EpoxyAdapter(), StickyHeaderCallbacks {\n\n    init {\n        enableDiffing()\n        for (i in 0 until 100) {\n            addModel(\n                when {\n                    i % 5 == 0 -> StickyItemEpoxyHolder_().apply {\n                        id(\"sticky-header $i\")\n                        title(\"Sticky header $i\")\n                        listener {\n                            Toast.makeText(context, \"clicked\", Toast.LENGTH_LONG).show()\n                        }\n                    }\n                    else -> ItemEpoxyHolder_().apply {\n                        id(\"view holder $i\")\n                        title(\"this is a View Holder item\")\n                        listener {\n                            Toast.makeText(context, \"clicked\", Toast.LENGTH_LONG)\n                                .show()\n                        }\n                    }\n                }\n            )\n        }\n        notifyModelsChanged()\n    }\n\n    // Feel feel to use any logic here to determine if the [position] is sticky view or not\n    override fun isStickyHeader(position: Int) = models[position] is StickyItemEpoxyHolder\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/StickyHeaderController.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.content.Context\nimport android.widget.Toast\nimport com.airbnb.epoxy.EpoxyController\nimport com.airbnb.epoxy.kotlinsample.models.StickyItemEpoxyHolder\nimport com.airbnb.epoxy.kotlinsample.models.itemEpoxyHolder\nimport com.airbnb.epoxy.kotlinsample.models.stickyItemEpoxyHolder\nimport com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks\n\n/**\n * Showcases [EpoxyController] with sticky header support\n */\nclass StickyHeaderController(\n    private val context: Context\n) : EpoxyController(), StickyHeaderCallbacks {\n\n    override fun buildModels() {\n        for (i in 0 until 100) {\n            when {\n                i % 5 == 0 -> stickyItemEpoxyHolder {\n                    id(\"sticky-header $i\")\n                    title(\"Sticky header $i\")\n                    listener {\n                        Toast.makeText(this@StickyHeaderController.context, \"clicked\", Toast.LENGTH_LONG).show()\n                    }\n                }\n                else -> itemEpoxyHolder {\n                    id(\"view holder $i\")\n                    title(\"this is a View Holder item\")\n                    listener {\n                        Toast.makeText(this@StickyHeaderController.context, \"clicked\", Toast.LENGTH_LONG)\n                            .show()\n                    }\n                }\n            }\n        }\n    }\n\n    // Feel feel to use any logic here to determine if the [position] is sticky view or not\n    override fun isStickyHeader(position: Int) = adapter.getModelAtPosition(position) is StickyItemEpoxyHolder\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/EpoxyCarouselNoSnapBuilder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.helpers\n\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.ModelCollector\nimport com.airbnb.epoxy.kotlinsample.views.CarouselNoSnapModelBuilder\nimport com.airbnb.epoxy.kotlinsample.views.CarouselNoSnapModel_\n\n/**\n * Example that illustrate how to add a builder for nested list (ex: carousel) that allow building\n * it using DSL :\n *\n *   carouselBuilder {\n *     id(...)\n *     for (...) {\n *       carouselItemCustomView {\n *         id(...)\n *       }\n *     }\n *   }\n *\n * @link https://github.com/airbnb/epoxy/issues/847\n */\nfun ModelCollector.carouselNoSnapBuilder(builder: EpoxyCarouselNoSnapBuilder.() -> Unit): CarouselNoSnapModel_ {\n    val carouselBuilder = EpoxyCarouselNoSnapBuilder().apply { builder() }\n    add(carouselBuilder.carouselNoSnapModel)\n    return carouselBuilder.carouselNoSnapModel\n}\n\nclass EpoxyCarouselNoSnapBuilder(\n    internal val carouselNoSnapModel: CarouselNoSnapModel_ = CarouselNoSnapModel_()\n) : ModelCollector, CarouselNoSnapModelBuilder by carouselNoSnapModel {\n    private val models = mutableListOf<EpoxyModel<*>>()\n\n    override fun add(model: EpoxyModel<*>) {\n        models.add(model)\n\n        // Set models list every time a model is added so that it can run debug validations to\n        // ensure it is still valid to mutate the carousel model.\n        carouselNoSnapModel.models(models)\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/KotlinEpoxyHolder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.helpers\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyHolder\nimport kotlin.properties.ReadOnlyProperty\nimport kotlin.reflect.KProperty\n\n/**\n * A pattern for easier view binding with an [EpoxyHolder]\n *\n * See [com.airbnb.epoxy.kotlinsample.models.ItemEpoxyHolder] for a usage example.\n */\nabstract class KotlinEpoxyHolder : EpoxyHolder() {\n    private lateinit var view: View\n\n    override fun bindView(itemView: View) {\n        view = itemView\n    }\n\n    protected fun <V : View> bind(id: Int): ReadOnlyProperty<KotlinEpoxyHolder, V> =\n        Lazy { holder: KotlinEpoxyHolder, prop ->\n            holder.view.findViewById(id) as V?\n                ?: throw IllegalStateException(\"View ID $id for '${prop.name}' not found.\")\n        }\n\n    /**\n     * Taken from Kotterknife.\n     * https://github.com/JakeWharton/kotterknife\n     */\n    private class Lazy<V>(\n        private val initializer: (KotlinEpoxyHolder, KProperty<*>) -> V\n    ) : ReadOnlyProperty<KotlinEpoxyHolder, V> {\n        private object EMPTY\n\n        private var value: Any? = EMPTY\n\n        override fun getValue(thisRef: KotlinEpoxyHolder, property: KProperty<*>): V {\n            if (value == EMPTY) {\n                value = initializer(thisRef, property)\n            }\n            @Suppress(\"UNCHECKED_CAST\")\n            return value as V\n        }\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/KotlinModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.helpers\n\nimport android.view.View\nimport androidx.annotation.IdRes\nimport androidx.annotation.LayoutRes\nimport com.airbnb.epoxy.EpoxyModel\nimport kotlin.properties.ReadOnlyProperty\nimport kotlin.reflect.KProperty\n\n/**\n * A pattern for using epoxy models with Kotlin with no annotations or code generation.\n *\n * See [com.airbnb.epoxy.kotlinsample.models.ItemDataClass] for a usage example.\n */\nabstract class KotlinModel(\n    @LayoutRes private val layoutRes: Int\n) : EpoxyModel<View>() {\n\n    private var view: View? = null\n\n    abstract fun bind()\n\n    override fun bind(view: View) {\n        this.view = view\n        bind()\n    }\n\n    override fun unbind(view: View) {\n        this.view = null\n    }\n\n    override fun getDefaultLayout() = layoutRes\n\n    protected fun <V : View> bind(@IdRes id: Int) = object : ReadOnlyProperty<KotlinModel, V> {\n        override fun getValue(thisRef: KotlinModel, property: KProperty<*>): V {\n            // This is not efficient because it looks up the view by id every time (it loses\n            // the pattern of a \"holder\" to cache that look up). But it is simple to use and could\n            // be optimized with a map\n            @Suppress(\"UNCHECKED_CAST\")\n            return view?.findViewById(id) as V?\n                ?: throw IllegalStateException(\"View ID $id for '${property.name}' not found.\")\n        }\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/ViewBindingEpoxyModelWithHolder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.helpers\n\nimport android.view.View\nimport android.view.ViewParent\nimport androidx.viewbinding.ViewBinding\nimport com.airbnb.epoxy.EpoxyHolder\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport java.lang.reflect.Method\nimport java.lang.reflect.ParameterizedType\nimport java.util.concurrent.ConcurrentHashMap\n\nabstract class ViewBindingEpoxyModelWithHolder<in T : ViewBinding> :\n    EpoxyModelWithHolder<ViewBindingHolder>() {\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun bind(holder: ViewBindingHolder) {\n        (holder.viewBinding as T).bind()\n    }\n\n    abstract fun T.bind()\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun unbind(holder: ViewBindingHolder) {\n        (holder.viewBinding as T).unbind()\n    }\n\n    open fun T.unbind() {}\n\n    override fun createNewHolder(parent: ViewParent): ViewBindingHolder {\n        return ViewBindingHolder(this::class.java)\n    }\n}\n\n// Static cache of a method pointer for each type of item used.\nprivate val sBindingMethodByClass = ConcurrentHashMap<Class<*>, Method>()\n\n@Suppress(\"UNCHECKED_CAST\")\n@Synchronized\nprivate fun getBindMethodFrom(javaClass: Class<*>): Method =\n    sBindingMethodByClass.getOrPut(javaClass) {\n        val actualTypeOfThis = getSuperclassParameterizedType(javaClass)\n        val viewBindingClass = actualTypeOfThis.actualTypeArguments[0] as Class<ViewBinding>\n        viewBindingClass.getDeclaredMethod(\"bind\", View::class.java)\n            ?: error(\"The binder class ${javaClass.canonicalName} should have a method bind(View)\")\n    }\n\nprivate fun getSuperclassParameterizedType(klass: Class<*>): ParameterizedType {\n    val genericSuperclass = klass.genericSuperclass\n    return (genericSuperclass as? ParameterizedType)\n        ?: getSuperclassParameterizedType(genericSuperclass as Class<*>)\n}\n\nclass ViewBindingHolder(private val epoxyModelClass: Class<*>) : EpoxyHolder() {\n    // Using reflection to get the static binding method.\n    // Lazy so it's computed only once by instance, when the 1st ViewHolder is actually created.\n    private val bindingMethod by lazy { getBindMethodFrom(epoxyModelClass) }\n\n    internal lateinit var viewBinding: ViewBinding\n    override fun bindView(itemView: View) {\n        // The 1st param is null because the binding method is static.\n        viewBinding = bindingMethod.invoke(null, itemView) as ViewBinding\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/ViewBindingKotlinModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.helpers\n\nimport android.view.View\nimport androidx.annotation.LayoutRes\nimport androidx.viewbinding.ViewBinding\nimport com.airbnb.epoxy.EpoxyModel\nimport com.airbnb.epoxy.kotlinsample.R\nimport java.lang.reflect.Method\nimport java.lang.reflect.ParameterizedType\nimport java.util.concurrent.ConcurrentHashMap\n\n/**\n * A pattern for using epoxy models with Kotlin with no annotations or code generation.\n *\n * See [com.airbnb.epoxy.kotlinsample.models.ItemViewBindingDataClass] for a usage example.\n *\n * If You use Proguard or R8, be sure to keep the bind method available with the following configuration:\n *\n * -keepclassmembers class * extends androidx.viewbinding.ViewBinding {\n *    public static *** bind(android.view.View);\n * }\n */\nabstract class ViewBindingKotlinModel<T : ViewBinding>(\n    @LayoutRes private val layoutRes: Int\n) : EpoxyModel<View>() {\n    // Using reflection to get the static binding method.\n    // Lazy so it's computed only once by instance, when the 1st ViewHolder is actually created.\n    private val bindingMethod by lazy { getBindMethodFrom(this::class.java) }\n\n    abstract fun T.bind()\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun bind(view: View) {\n        var binding = view.getTag(R.id.epoxy_viewbinding) as? T\n        if (binding == null) {\n            binding = bindingMethod.invoke(null, view) as T\n            view.setTag(R.id.epoxy_viewbinding, binding)\n        }\n        binding.bind()\n    }\n\n    override fun getDefaultLayout() = layoutRes\n}\n\n// Static cache of a method pointer for each type of item used.\nprivate val sBindingMethodByClass = ConcurrentHashMap<Class<*>, Method>()\n\n@Suppress(\"UNCHECKED_CAST\")\n@Synchronized\nprivate fun getBindMethodFrom(javaClass: Class<*>): Method =\n    sBindingMethodByClass.getOrPut(javaClass) {\n        val actualTypeOfThis = getSuperclassParameterizedType(javaClass)\n        val viewBindingClass = actualTypeOfThis.actualTypeArguments[0] as Class<ViewBinding>\n        viewBindingClass.getDeclaredMethod(\"bind\", View::class.java)\n            ?: error(\"The binder class ${javaClass.canonicalName} should have a method bind(View)\")\n    }\n\nprivate fun getSuperclassParameterizedType(klass: Class<*>): ParameterizedType {\n    val genericSuperclass = klass.genericSuperclass\n    return (genericSuperclass as? ParameterizedType)\n        ?: getSuperclassParameterizedType(genericSuperclass as Class<*>)\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/CarouselItemCustomView.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.util.Log\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport com.airbnb.epoxy.AfterPropsSet\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.OnViewRecycled\nimport com.airbnb.epoxy.OnVisibilityChanged\nimport com.airbnb.epoxy.OnVisibilityStateChanged\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.VisibilityState\nimport com.airbnb.epoxy.kotlinsample.R\n\n@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)\nclass CarouselItemCustomView @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : LinearLayout(context, attrs, defStyleAttr) {\n\n    private val onVisibilityEventDrawable = OnVisibilityEventDrawable(context)\n\n    private val textView: TextView\n\n    init {\n        inflate(context, R.layout.carousel_custom_view_item, this)\n        orientation = VERTICAL\n        textView = (findViewById(R.id.title))\n        textView.setCompoundDrawables(null, null, null, onVisibilityEventDrawable)\n        textView.compoundDrawablePadding = (4 * resources.displayMetrics.density).toInt()\n    }\n\n    @TextProp\n    lateinit var title: CharSequence\n\n    @AfterPropsSet\n    fun useProps() {\n        textView.text = title\n    }\n\n    @OnVisibilityStateChanged\n    fun onVisibilityStateChanged(\n        @VisibilityState.Visibility visibilityState: Int\n    ) {\n        when (visibilityState) {\n            VisibilityState.VISIBLE -> {\n                Log.d(TAG, \"$title Visible\")\n                onVisibilityEventDrawable.visible = true\n            }\n            VisibilityState.INVISIBLE -> {\n                Log.d(TAG, \"$title Invisible\")\n                onVisibilityEventDrawable.visible = false\n            }\n            VisibilityState.FOCUSED_VISIBLE -> {\n                Log.d(TAG, \"$title FocusedVisible\")\n                onVisibilityEventDrawable.focusedVisible = true\n            }\n            VisibilityState.UNFOCUSED_VISIBLE -> {\n                Log.d(TAG, \"$title UnfocusedVisible\")\n                onVisibilityEventDrawable.focusedVisible = false\n            }\n            VisibilityState.PARTIAL_IMPRESSION_VISIBLE -> {\n                Log.d(TAG, \"$title PartialImpressionVisible\")\n                onVisibilityEventDrawable.partialImpression = true\n            }\n            VisibilityState.PARTIAL_IMPRESSION_INVISIBLE -> {\n                Log.d(TAG, \"$title PartialImpressionInVisible\")\n                onVisibilityEventDrawable.partialImpression = false\n            }\n            VisibilityState.FULL_IMPRESSION_VISIBLE -> {\n                Log.d(TAG, \"$title FullImpressionVisible\")\n                onVisibilityEventDrawable.fullImpression = true\n            }\n        }\n    }\n\n    @OnVisibilityChanged\n    fun onVisibilityChanged(\n        percentVisibleHeight: Float,\n        percentVisibleWidth: Float,\n        visibleHeight: Int,\n        visibleWidth: Int\n    ) {\n        Log.d(\n            TAG,\n            \"$title onChanged ${percentVisibleHeight.toInt()} ${percentVisibleWidth.toInt()} \" +\n                \"$visibleHeight $visibleWidth ${System.identityHashCode(this)}\"\n        )\n        with(onVisibilityEventDrawable) {\n            if ((percentVisibleHeight < 100 || percentVisibleWidth < 100) && fullImpression) {\n                fullImpression = false\n            }\n            percentHeight = percentVisibleHeight\n            percentWidth = percentVisibleWidth\n        }\n    }\n\n    @OnViewRecycled\n    fun clear() {\n        onVisibilityEventDrawable.reset()\n    }\n\n    companion object {\n        private const val TAG = \"CarouselItemCustomView\"\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ColoredSquareView.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.util.AttributeSet\nimport android.view.View\nimport androidx.annotation.ColorInt\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.kotlinsample.R\n\n@ModelView(defaultLayout = R.layout.colored_square_view)\nclass ColoredSquareView @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : View(context, attrs, defStyleAttr) {\n\n    @JvmOverloads\n    @ModelProp\n    fun color(@ColorInt color: Int = Color.RED) {\n        setBackgroundColor(color)\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/DecoratedLinearGroupModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.GroupModel\nimport com.airbnb.epoxy.kotlinsample.R\n\n@EpoxyModelClass\nabstract class DecoratedLinearGroupModel : GroupModel(R.layout.decorated_linear_group)\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemCustomView.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.util.AttributeSet\nimport android.util.Log\nimport android.view.View\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.annotation.ColorInt\nimport com.airbnb.epoxy.AfterPropsSet\nimport com.airbnb.epoxy.CallbackProp\nimport com.airbnb.epoxy.ModelProp\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.OnViewRecycled\nimport com.airbnb.epoxy.OnVisibilityChanged\nimport com.airbnb.epoxy.OnVisibilityStateChanged\nimport com.airbnb.epoxy.TextProp\nimport com.airbnb.epoxy.VisibilityState\nimport com.airbnb.epoxy.kotlinsample.R\n\n// The ModelView annotation is used on Views to have models generated from those views.\n// This is pretty straightforward with Kotlin, but properties need some special handling.\n@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)\nclass ItemCustomView @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : LinearLayout(context, attrs, defStyleAttr) {\n\n    private val onVisibilityEventDrawable = OnVisibilityEventDrawable(context)\n\n    private val textView: TextView\n\n    init {\n        inflate(context, R.layout.custom_view_item, this)\n        orientation = VERTICAL\n        textView = (findViewById(R.id.title))\n        textView.setCompoundDrawables(null, null, onVisibilityEventDrawable, null)\n        textView.compoundDrawablePadding = (4 * resources.displayMetrics.density).toInt()\n    }\n\n    // You can annotate your methods with @ModelProp\n    // A default model property value can be set by using Kotlin default arguments, but you\n    // must use JvmOverloads for Epoxy to handle it correctly.\n    @JvmOverloads\n    @ModelProp\n    fun color(@ColorInt color: Int = Color.RED) {\n        textView.setTextColor(color)\n    }\n\n    // Or if you need to store data in properties there are two options\n\n    // 1.You can make it nullable like this and annotate the setter\n    var listener: View.OnClickListener? = null\n        @CallbackProp set\n\n    // 2. Or you can use lateinit\n    @TextProp\n    lateinit var title: CharSequence\n\n    @AfterPropsSet\n    fun useProps() {\n        // This is optional, and is called after the annotated properties above are set.\n        // This is useful for using several properties in one method to guarantee they are all set first.\n        textView.text = title\n        textView.setOnClickListener(listener)\n    }\n\n    @OnVisibilityStateChanged\n    fun onVisibilityStateChanged(\n        @VisibilityState.Visibility visibilityState: Int\n    ) {\n        when (visibilityState) {\n            VisibilityState.VISIBLE -> {\n                Log.d(TAG, \"$title Visible\")\n                onVisibilityEventDrawable.visible = true\n            }\n            VisibilityState.INVISIBLE -> {\n                Log.d(TAG, \"$title Invisible\")\n                onVisibilityEventDrawable.visible = false\n            }\n            VisibilityState.FOCUSED_VISIBLE -> {\n                Log.d(TAG, \"$title FocusedVisible\")\n                onVisibilityEventDrawable.focusedVisible = true\n            }\n            VisibilityState.UNFOCUSED_VISIBLE -> {\n                Log.d(TAG, \"$title UnfocusedVisible\")\n                onVisibilityEventDrawable.focusedVisible = false\n            }\n            VisibilityState.PARTIAL_IMPRESSION_VISIBLE -> {\n                Log.d(TAG, \"$title PartialImpressionVisible\")\n                onVisibilityEventDrawable.partialImpression = true\n            }\n            VisibilityState.PARTIAL_IMPRESSION_INVISIBLE -> {\n                Log.d(TAG, \"$title PartialImpressionInVisible\")\n                onVisibilityEventDrawable.partialImpression = false\n            }\n            VisibilityState.FULL_IMPRESSION_VISIBLE -> {\n                Log.d(TAG, \"$title FullImpressionVisible\")\n                onVisibilityEventDrawable.fullImpression = true\n            }\n        }\n    }\n\n    @OnVisibilityChanged\n    fun onVisibilityChanged(\n        percentVisibleHeight: Float,\n        percentVisibleWidth: Float,\n        visibleHeight: Int,\n        visibleWidth: Int\n    ) {\n        Log.d(\n            TAG,\n            \"$title onChanged ${percentVisibleHeight.toInt()} ${percentVisibleWidth.toInt()} \" +\n                \"$visibleHeight $visibleWidth ${System.identityHashCode(\n                    this\n                )}\"\n        )\n        with(onVisibilityEventDrawable) {\n            if ((percentVisibleHeight < 100 || percentVisibleWidth < 100) && fullImpression) {\n                fullImpression = false\n            }\n            percentHeight = percentVisibleHeight\n            percentWidth = percentVisibleWidth\n        }\n    }\n\n    @OnViewRecycled\n    fun clear() {\n        onVisibilityEventDrawable.reset()\n    }\n\n    companion object {\n        private const val TAG = \"ItemCustomView\"\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemDataClass.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.widget.TextView\nimport com.airbnb.epoxy.kotlinsample.R\nimport com.airbnb.epoxy.kotlinsample.helpers.KotlinModel\n\n// This does not require annotations or annotation processing.\n// The data class is required to generated equals/hashcode which Epoxy needs for diffing.\n// Views are easily declared via property delegates\ndata class ItemDataClass(\n    val title: String\n) : KotlinModel(R.layout.data_class_item) {\n\n    val titleView by bind<TextView>(R.id.title)\n\n    override fun bind() {\n        titleView.text = title\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemEpoxyHolder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.widget.TextView\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.kotlinsample.R\nimport com.airbnb.epoxy.kotlinsample.helpers.KotlinEpoxyHolder\n\n// This more traditional style uses an Epoxy view holder pattern.\n// The KotlinHolder is used to cache the view look ups, but uses property delegates to simplify it.\n// The annotations allow for code generation of a subclass, which has equals/hashcode, and some other\n// helpers. An extension function is also generated to make it easier to use this in an EpoxyController.\n@EpoxyModelClass(layout = R.layout.view_holder_item)\nabstract class ItemEpoxyHolder : EpoxyModelWithHolder<Holder>() {\n\n    @EpoxyAttribute lateinit var listener: () -> Unit\n    @EpoxyAttribute lateinit var title: String\n\n    override fun bind(holder: Holder) {\n        holder.titleView.setText(title)\n        holder.titleView.setOnClickListener { listener() }\n    }\n}\n\nclass Holder : KotlinEpoxyHolder() {\n    val titleView by bind<TextView>(R.id.title)\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemViewBindingDataClass.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport com.airbnb.epoxy.kotlinsample.R\nimport com.airbnb.epoxy.kotlinsample.databinding.DataClassViewBindingItemBinding\nimport com.airbnb.epoxy.kotlinsample.helpers.ViewBindingKotlinModel\n\n// This does not require annotations or annotation processing.\n// The data class is required to generated equals/hashcode which Epoxy needs for diffing.\n// Views are easily declared via property delegates\ndata class ItemViewBindingDataClass(\n    val title: String\n) : ViewBindingKotlinModel<DataClassViewBindingItemBinding>(R.layout.data_class_view_binding_item) {\n    override fun DataClassViewBindingItemBinding.bind() {\n        title.text = this@ItemViewBindingDataClass.title\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemViewBindingEpoxyHolder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.kotlinsample.R\nimport com.airbnb.epoxy.kotlinsample.databinding.ViewBindingHolderItemBinding\nimport com.airbnb.epoxy.kotlinsample.helpers.ViewBindingEpoxyModelWithHolder\n\n@EpoxyModelClass(layout = R.layout.view_binding_holder_item)\nabstract class ItemViewBindingEpoxyHolder : ViewBindingEpoxyModelWithHolder<ViewBindingHolderItemBinding>() {\n\n    @EpoxyAttribute lateinit var listener: () -> Unit\n    @EpoxyAttribute lateinit var title: String\n\n    override fun ViewBindingHolderItemBinding.bind() {\n        title.text = this@ItemViewBindingEpoxyHolder.title\n        title.setOnClickListener { listener() }\n    }\n\n    override fun ViewBindingHolderItemBinding.unbind() {\n        // Don't leak listeners as this view goes back to the view pool\n        title.setOnClickListener(null)\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ManualLayoutParamsView.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.ViewGroup\nimport androidx.appcompat.widget.AppCompatTextView\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.TextProp\n\n@ModelView(autoLayout = ModelView.Size.MANUAL)\nclass ManualLayoutParamsView @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyle: Int = 0\n) : AppCompatTextView(context, attrs, defStyle) {\n\n    init {\n        layoutParams = ViewGroup.MarginLayoutParams(\n            ViewGroup.MarginLayoutParams.MATCH_PARENT,\n            ViewGroup.MarginLayoutParams.WRAP_CONTENT\n        ).apply {\n            setMargins(50, 50, 50, 50)\n        }\n    }\n\n    @TextProp\n    fun setTitle(title: CharSequence?) {\n        text = title\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/OnVisibilityEventDrawable.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.content.Context\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.ColorFilter\nimport android.graphics.Paint\nimport android.graphics.PixelFormat\nimport android.graphics.drawable.Drawable\n\n/**\n * Drawable for sample app that draw the current visibility state :\n * - circle #1 : visible\n * - circle #2 : focused\n * - circle #3 : partial impression\n * - circle #4 : full impression\n * - rectangle : visibility percentage\n */\nclass OnVisibilityEventDrawable(context: Context) : Drawable() {\n\n    private val density = context.resources.displayMetrics.density\n    private val diameter = density * 12\n    private val padding = density * 2\n    private val paint = Paint().apply {\n        color = Color.LTGRAY\n        isAntiAlias = true\n        strokeWidth = density\n    }\n    private val circleCount = 4\n\n    init {\n        setBounds(0, 0, padding.toInt() * (circleCount + 1) + diameter.toInt() * circleCount, diameter.toInt())\n    }\n\n    var visible = false\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    var focusedVisible = false\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    var partialImpression = false\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    var fullImpression = false\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    var percentHeight = 0.0f\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    var percentWidth = 0.0f\n        set(value) {\n            field = value\n            invalidateSelf()\n        }\n\n    fun reset() {\n        visible = false\n        focusedVisible = false\n        partialImpression = false\n        fullImpression = false\n        percentHeight = 0.0f\n        percentWidth = 0.0f\n        invalidateSelf()\n    }\n\n    override fun draw(canvas: Canvas) {\n\n        val y = diameter / 2\n        var x = diameter / 2 + padding\n\n        paint.style = if (visible) Paint.Style.FILL_AND_STROKE else Paint.Style.STROKE\n        canvas.drawCircle(x, y, diameter / 2, paint)\n\n        x += diameter + padding\n        paint.style = if (partialImpression) Paint.Style.FILL_AND_STROKE else Paint.Style.STROKE\n        canvas.drawCircle(x, y, diameter / 2, paint)\n\n        x += diameter + padding\n        paint.style = if (focusedVisible) Paint.Style.FILL_AND_STROKE else Paint.Style.STROKE\n        canvas.drawCircle(x, y, diameter / 2, paint)\n\n        x += diameter + padding\n        paint.style = if (fullImpression) Paint.Style.FILL_AND_STROKE else Paint.Style.STROKE\n        canvas.drawCircle(x, y, diameter / 2, paint)\n\n        paint.style = Paint.Style.STROKE\n        canvas.drawRect(\n            0.0f,\n            0.0f,\n            bounds.width() * percentWidth / 100,\n            bounds.height().toFloat() * percentHeight / 100,\n            paint\n        )\n    }\n\n    override fun setAlpha(alpha: Int) = Unit\n\n    override fun getOpacity() = PixelFormat.TRANSLUCENT\n\n    override fun setColorFilter(colorFilter: ColorFilter?) = Unit\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/StickyItemEpoxyHolder.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.models\n\nimport android.widget.TextView\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\nimport com.airbnb.epoxy.kotlinsample.R\nimport com.airbnb.epoxy.kotlinsample.helpers.KotlinEpoxyHolder\n\n// This more traditional style uses an Epoxy view holder pattern.\n// The KotlinHolder is used to cache the view look ups, but uses property delegates to simplify it.\n// The annotations allow for code generation of a subclass, which has equals/hashcode, and some other\n// helpers. An extension function is also generated to make it easier to use this in an EpoxyController.\n@EpoxyModelClass(layout = R.layout.sticky_view_holder_item)\nabstract class StickyItemEpoxyHolder : EpoxyModelWithHolder<StickyItemEpoxyHolder.StickyHolder>() {\n\n    @EpoxyAttribute lateinit var listener: () -> Unit\n    @EpoxyAttribute lateinit var title: String\n\n    override fun bind(holder: StickyHolder) {\n        holder.titleView.text = title\n        holder.titleView.setOnClickListener { listener() }\n    }\n\n    class StickyHolder : KotlinEpoxyHolder() {\n        val titleView by bind<TextView>(R.id.title)\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/views/CarouselNoSnap.kt",
    "content": "package com.airbnb.epoxy.kotlinsample.views\n\nimport android.content.Context\nimport com.airbnb.epoxy.Carousel\nimport com.airbnb.epoxy.ModelView\nimport com.airbnb.epoxy.ModelView.Size\n\n@ModelView(saveViewState = true, autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT)\nclass CarouselNoSnap(context: Context) : Carousel(context) {\n\n    override fun getSnapHelperFactory(): Nothing? = null\n}\n"
  },
  {
    "path": "kotlinsample/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "kotlinsample/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:aapt=\"http://schemas.android.com/aapt\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "kotlinsample/src/main/res/layout/activity.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.airbnb.epoxy.EpoxyViewStub\n        android:id=\"@+id/epoxy_view_stub\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\"/>\n    <com.airbnb.epoxy.EpoxyRecyclerView\n        android:id=\"@+id/recycler_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n</LinearLayout>\n\n\n"
  },
  {
    "path": "kotlinsample/src/main/res/layout/carousel_custom_view_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n</merge>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/colored_square_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.airbnb.epoxy.kotlinsample.models.ColoredSquareView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"56dp\"\n    android:layout_height=\"56dp\" />"
  },
  {
    "path": "kotlinsample/src/main/res/layout/custom_view_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n</merge>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/data_class_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n\n</LinearLayout>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/data_class_view_binding_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n\n</LinearLayout>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/decorated_linear_group.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"#80000000\"\n    android:orientation=\"horizontal\"\n    android:padding=\"8dp\" />\n"
  },
  {
    "path": "kotlinsample/src/main/res/layout/epoxy_layout_data_binding_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <data>\n\n        <variable\n            name=\"text\"\n            type=\"String\" />\n        <variable\n            name=\"onClick\"\n            type=\"android.view.View.OnClickListener\" />\n\n    </data>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <TextView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:padding=\"20dp\"\n            android:onClick=\"@{onClick}\"\n            android:text=\"@{text}\"\n            android:background=\"?attr/selectableItemBackground\"/>\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"#80000000\"/>\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/sticky_view_holder_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\"\n    android:background=\"@android:color/white\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n</LinearLayout>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/vertical_linear_group.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\" />"
  },
  {
    "path": "kotlinsample/src/main/res/layout/view_binding_holder_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n\n</LinearLayout>"
  },
  {
    "path": "kotlinsample/src/main/res/layout/view_holder_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"?attr/selectableItemBackground\"\n        android:padding=\"20dp\" />\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#80000000\" />\n\n</LinearLayout>"
  },
  {
    "path": "kotlinsample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "kotlinsample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "kotlinsample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "kotlinsample/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"epoxy_viewbinding\" type=\"id\" />\n</resources>"
  },
  {
    "path": "kotlinsample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Kotlin Sample</string>\n</resources>\n"
  },
  {
    "path": "kotlinsample/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "kotlinsample/src/test/java/com/airbnb/epoxy/kotlinsample/AnnotationModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.view.View\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.FloatRange\nimport androidx.annotation.StringRes\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyHolder\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\n\n@EpoxyModelClass(layout = R.layout.activity)\nabstract class AnnotationModel(\n    @StringRes val resId: Int,\n    @FloatRange(from = 0.0, to = 1.0) val range: Float\n) : EpoxyModelWithHolder<AnnotationHolder>() {\n\n    @EpoxyAttribute @DrawableRes var drawable: Int? = null\n}\n\nclass AnnotationHolder : EpoxyHolder() {\n    override fun bindView(itemView: View) {\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/test/java/com/airbnb/epoxy/kotlinsample/ConstructorWithLambdaModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyHolder\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\n\n@EpoxyModelClass(layout = R.layout.activity)\nabstract class KotlinConstructorSample(val listener: (someBool: Boolean, anotherInt: Int) -> Unit) :\n    EpoxyModelWithHolder<KotlinConstructorHolder>()\n\nclass KotlinConstructorHolder() : EpoxyHolder() {\n    override fun bindView(itemView: View) {\n    }\n}\n"
  },
  {
    "path": "kotlinsample/src/test/java/com/airbnb/epoxy/kotlinsample/ConstructorWithoutLamdaModel.kt",
    "content": "package com.airbnb.epoxy.kotlinsample\n\nimport android.view.View\nimport com.airbnb.epoxy.EpoxyAttribute\nimport com.airbnb.epoxy.EpoxyHolder\nimport com.airbnb.epoxy.EpoxyModelClass\nimport com.airbnb.epoxy.EpoxyModelWithHolder\n\n@EpoxyModelClass(layout = R.layout.activity)\nabstract class KotlinNonConstructorSample() :\n    EpoxyModelWithHolder<KotlinNonConstructorSampleHolder>() {\n    @EpoxyAttribute\n    lateinit var listener: ((boolean: Boolean) -> Unit)\n}\n\nclass KotlinNonConstructorSampleHolder : EpoxyHolder() {\n    override fun bindView(itemView: View) {\n    }\n}\n"
  },
  {
    "path": "ktlint.gradle",
    "content": "repositories {\n  mavenCentral()\n}\n\nconfigurations {\n  ktlint\n}\n\ndependencies {\n  ktlint \"com.pinterest:ktlint:0.42.1\"\n  // additional 3rd party ruleset(s) can be specified here\n  // just add them to the classpath (e.g. ktlint 'groupId:artifactId:version') and\n  // ktlint will pick them up\n}\n\ntask ktlint(type: JavaExec, group: \"verification\") {\n  description = \"Check Kotlin code style.\"\n  classpath = configurations.ktlint\n  main = \"com.pinterest.ktlint.Main\"\n  args \"src/**/*.kt\", \"!src/**/resources/**\"\n  // to generate report in checkstyle format prepend following args:\n  // \"--reporter=plain\", \"--reporter=checkstyle,output=${buildDir}/ktlint.xml\"\n  // see https://github.com/pinterest/ktlint#usage for more\n}\n\ntask ktlintFormat(type: JavaExec, group: \"formatting\") {\n  description = \"Fix Kotlin code style deviations.\"\n  classpath = configurations.ktlint\n  main = \"com.pinterest.ktlint.Main\"\n  args \"-F\", \"src/**/*.kt\", \"!src/**/resources/**\"\n}"
  },
  {
    "path": "publishing.gradle",
    "content": "// Sets up publishing of release artifacts.\n// Note: Keep this script in sync across all airbnb open source projects.\napply plugin: 'com.vanniktech.maven.publish'\n\n\n// https://vanniktech.github.io/gradle-maven-publish-plugin/other/\npublishing {\n    repositories {\n        maven {\n            // The \"name\" value creates a task like `publishAllPublicationsTo[Name]Repository\n            // In this case, publishAllPublicationsToAirbnbArtifactoryRepository\n            name = 'airbnbArtifactory'\n            url = version.toString().endsWith(\"SNAPSHOT\") ? findProperty(\"ARTIFACTORY_SNAPSHOT_URL\") : findProperty(\"ARTIFACTORY_RELEASE_URL\")\n            credentials {\n                username = findProperty(\"ARTIFACTORY_USERNAME\")\n                password = findProperty(\"ARTIFACTORY_PASSWORD\")\n            }\n        }\n    }\n}\n\n// Apply conditional signing logic by setting the property at configuration time\n// This must happen before the mavenPublishing plugin reads the property\nif (findProperty(\"doNotSignRelease\").toString().toBoolean()) {\n    println(\"Skipping release signing\")\n    // Override the signAllPublications property to disable signing\n    ext.set(\"signAllPublications\", \"false\")\n} else {\n    println(\"Signing release with gpg\")\n    // signAllPublications is already set to true in gradle.properties\n}"
  },
  {
    "path": "reports/profile/css/base-style.css",
    "content": "\nbody {\n    margin: 0;\n    padding: 0;\n    font-family: sans-serif;\n    font-size: 12pt;\n}\n\nbody, a, a:visited {\n    color: #303030;\n}\n\n#content {\n    padding-left: 50px;\n    padding-right: 50px;\n    padding-top: 30px;\n    padding-bottom: 30px;\n}\n\n#content h1 {\n    font-size: 160%;\n    margin-bottom: 10px;\n}\n\n#footer {\n    margin-top: 100px;\n    font-size: 80%;\n    white-space: nowrap;\n}\n\n#footer, #footer a {\n    color: #a0a0a0;\n}\n\n#line-wrapping-toggle {\n    vertical-align: middle;\n}\n\n#label-for-line-wrapping-toggle {\n    vertical-align: middle;\n}\n\nul {\n    margin-left: 0;\n}\n\nh1, h2, h3 {\n    white-space: nowrap;\n}\n\nh2 {\n    font-size: 120%;\n}\n\nul.tabLinks {\n    padding-left: 0;\n    padding-top: 10px;\n    padding-bottom: 10px;\n    overflow: auto;\n    min-width: 800px;\n    width: auto !important;\n    width: 800px;\n}\n\nul.tabLinks li {\n    float: left;\n    height: 100%;\n    list-style: none;\n    padding-left: 10px;\n    padding-right: 10px;\n    padding-top: 5px;\n    padding-bottom: 5px;\n    margin-bottom: 0;\n    -moz-border-radius: 7px;\n    border-radius: 7px;\n    margin-right: 25px;\n    border: solid 1px #d4d4d4;\n    background-color: #f0f0f0;\n}\n\nul.tabLinks li:hover {\n    background-color: #fafafa;\n}\n\nul.tabLinks li.selected {\n    background-color: #c5f0f5;\n    border-color: #c5f0f5;\n}\n\nul.tabLinks a {\n    font-size: 120%;\n    display: block;\n    outline: none;\n    text-decoration: none;\n    margin: 0;\n    padding: 0;\n}\n\nul.tabLinks li h2 {\n    margin: 0;\n    padding: 0;\n}\n\ndiv.tab {\n}\n\ndiv.selected {\n    display: block;\n}\n\ndiv.deselected {\n    display: none;\n}\n\ndiv.tab table {\n    min-width: 350px;\n    width: auto !important;\n    width: 350px;\n    border-collapse: collapse;\n}\n\ndiv.tab th, div.tab table {\n    border-bottom: solid #d0d0d0 1px;\n}\n\ndiv.tab th {\n    text-align: left;\n    white-space: nowrap;\n    padding-left: 6em;\n}\n\ndiv.tab th:first-child {\n    padding-left: 0;\n}\n\ndiv.tab td {\n    white-space: nowrap;\n    padding-left: 6em;\n    padding-top: 5px;\n    padding-bottom: 5px;\n}\n\ndiv.tab td:first-child {\n    padding-left: 0;\n}\n\ndiv.tab td.numeric, div.tab th.numeric {\n    text-align: right;\n}\n\nspan.code {\n    display: inline-block;\n    margin-top: 0em;\n    margin-bottom: 1em;\n}\n\nspan.code pre {\n    font-size: 11pt;\n    padding-top: 10px;\n    padding-bottom: 10px;\n    padding-left: 10px;\n    padding-right: 10px;\n    margin: 0;\n    background-color: #f7f7f7;\n    border: solid 1px #d0d0d0;\n    min-width: 700px;\n    width: auto !important;\n    width: 700px;\n}\n\nspan.wrapped pre {\n    word-wrap: break-word;\n    white-space: pre-wrap;\n    word-break: break-all;\n}\n\nlabel.hidden {\n    display: none;\n}"
  },
  {
    "path": "reports/profile/css/style.css",
    "content": "\ndiv.tab td.indentPath {\n    padding-left: 3em;\n}\n"
  },
  {
    "path": "reports/profile/js/report.js",
    "content": "(function (window, document) {\n    \"use strict\";\n\n    var tabs = {};\n\n    function changeElementClass(element, classValue) {\n        if (element.getAttribute(\"className\")) {\n            element.setAttribute(\"className\", classValue);\n        } else {\n            element.setAttribute(\"class\", classValue);\n        }\n    }\n\n    function getClassAttribute(element) {\n        if (element.getAttribute(\"className\")) {\n            return element.getAttribute(\"className\");\n        } else {\n            return element.getAttribute(\"class\");\n        }\n    }\n\n    function addClass(element, classValue) {\n        changeElementClass(element, getClassAttribute(element) + \" \" + classValue);\n    }\n\n    function removeClass(element, classValue) {\n        changeElementClass(element, getClassAttribute(element).replace(classValue, \"\"));\n    }\n\n    function initTabs() {\n        var container = document.getElementById(\"tabs\");\n\n        tabs.tabs = findTabs(container);\n        tabs.titles = findTitles(tabs.tabs);\n        tabs.headers = findHeaders(container);\n        tabs.select = select;\n        tabs.deselectAll = deselectAll;\n        tabs.select(0);\n\n        return true;\n    }\n\n    function getCheckBox() {\n        return document.getElementById(\"line-wrapping-toggle\");\n    }\n\n    function getLabelForCheckBox() {\n        return document.getElementById(\"label-for-line-wrapping-toggle\");\n    }\n\n    function findCodeBlocks() {\n        var spans = document.getElementById(\"tabs\").getElementsByTagName(\"span\");\n        var codeBlocks = [];\n        for (var i = 0; i < spans.length; ++i) {\n            if (spans[i].className.indexOf(\"code\") >= 0) {\n                codeBlocks.push(spans[i]);\n            }\n        }\n        return codeBlocks;\n    }\n\n    function forAllCodeBlocks(operation) {\n        var codeBlocks = findCodeBlocks();\n\n        for (var i = 0; i < codeBlocks.length; ++i) {\n            operation(codeBlocks[i], \"wrapped\");\n        }\n    }\n\n    function toggleLineWrapping() {\n        var checkBox = getCheckBox();\n\n        if (checkBox.checked) {\n            forAllCodeBlocks(addClass);\n        } else {\n            forAllCodeBlocks(removeClass);\n        }\n    }\n\n    function initControls() {\n        if (findCodeBlocks().length > 0) {\n            var checkBox = getCheckBox();\n            var label = getLabelForCheckBox();\n\n            checkBox.onclick = toggleLineWrapping;\n            checkBox.checked = false;\n\n            removeClass(label, \"hidden\");\n         }\n    }\n\n    function switchTab() {\n        var id = this.id.substr(1);\n\n        for (var i = 0; i < tabs.tabs.length; i++) {\n            if (tabs.tabs[i].id === id) {\n                tabs.select(i);\n                break;\n            }\n        }\n\n        return false;\n    }\n\n    function select(i) {\n        this.deselectAll();\n\n        changeElementClass(this.tabs[i], \"tab selected\");\n        changeElementClass(this.headers[i], \"selected\");\n\n        while (this.headers[i].firstChild) {\n            this.headers[i].removeChild(this.headers[i].firstChild);\n        }\n\n        var h2 = document.createElement(\"H2\");\n\n        h2.appendChild(document.createTextNode(this.titles[i]));\n        this.headers[i].appendChild(h2);\n    }\n\n    function deselectAll() {\n        for (var i = 0; i < this.tabs.length; i++) {\n            changeElementClass(this.tabs[i], \"tab deselected\");\n            changeElementClass(this.headers[i], \"deselected\");\n\n            while (this.headers[i].firstChild) {\n                this.headers[i].removeChild(this.headers[i].firstChild);\n            }\n\n            var a = document.createElement(\"A\");\n\n            a.setAttribute(\"id\", \"ltab\" + i);\n            a.setAttribute(\"href\", \"#tab\" + i);\n            a.onclick = switchTab;\n            a.appendChild(document.createTextNode(this.titles[i]));\n\n            this.headers[i].appendChild(a);\n        }\n    }\n\n    function findTabs(container) {\n        return findChildElements(container, \"DIV\", \"tab\");\n    }\n\n    function findHeaders(container) {\n        var owner = findChildElements(container, \"UL\", \"tabLinks\");\n        return findChildElements(owner[0], \"LI\", null);\n    }\n\n    function findTitles(tabs) {\n        var titles = [];\n\n        for (var i = 0; i < tabs.length; i++) {\n            var tab = tabs[i];\n            var header = findChildElements(tab, \"H2\", null)[0];\n\n            header.parentNode.removeChild(header);\n\n            if (header.innerText) {\n                titles.push(header.innerText);\n            } else {\n                titles.push(header.textContent);\n            }\n        }\n\n        return titles;\n    }\n\n    function findChildElements(container, name, targetClass) {\n        var elements = [];\n        var children = container.childNodes;\n\n        for (var i = 0; i < children.length; i++) {\n            var child = children.item(i);\n\n            if (child.nodeType === 1 && child.nodeName === name) {\n                if (targetClass && child.className.indexOf(targetClass) < 0) {\n                    continue;\n                }\n\n                elements.push(child);\n            }\n        }\n\n        return elements;\n    }\n\n    // Entry point.\n\n    window.onload = function() {\n        initTabs();\n        initControls();\n    };\n} (window, window.document));"
  },
  {
    "path": "reports/profile/profile-2020-03-31-14-39-05.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=edge\"/>\n<title>Profile report</title>\n<link href=\"css/base-style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n<link href=\"css/style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n<script src=\"js/report.js\" type=\"text/javascript\"></script>\n</head>\n<body>\n<div id=\"content\">\n<h1>Profile report</h1>\n<div id=\"header\">\n<p>Profiled build: help </p>\n<p>Started on: 2020/03/31 - 14:39:05</p>\n</div>\n<div id=\"tabs\">\n<ul class=\"tabLinks\">\n<li>\n<a href=\"#tab0\">Summary</a>\n</li>\n<li>\n<a href=\"#tab1\">Configuration</a>\n</li>\n<li>\n<a href=\"#tab2\">Dependency Resolution</a>\n</li>\n<li>\n<a href=\"#tab3\">Artifact Transforms</a>\n</li>\n<li>\n<a href=\"#tab4\">Task Execution</a>\n</li>\n</ul>\n<div class=\"tab\" id=\"tab0\">\n<h2>Summary</h2>\n<table>\n<thead>\n<tr>\n<th>Description</th>\n<th class=\"numeric\">Duration</th>\n</tr>\n</thead>\n<tr>\n<td>Total Build Time</td>\n<td class=\"numeric\">11.966s</td>\n</tr>\n<tr>\n<td>Startup</td>\n<td class=\"numeric\">0.701s</td>\n</tr>\n<tr>\n<td>Settings and BuildSrc</td>\n<td class=\"numeric\">0.002s</td>\n</tr>\n<tr>\n<td>Loading Projects</td>\n<td class=\"numeric\">0.010s</td>\n</tr>\n<tr>\n<td>Configuring Projects</td>\n<td class=\"numeric\">11.150s</td>\n</tr>\n<tr>\n<td>Artifact Transforms</td>\n<td class=\"numeric\">0s</td>\n</tr>\n<tr>\n<td>Task Execution</td>\n<td class=\"numeric\">0s</td>\n</tr>\n</table>\n</div>\n<div class=\"tab\" id=\"tab1\">\n<h2>Configuration</h2>\n<table>\n<thead>\n<tr>\n<th>Project</th>\n<th class=\"numeric\">Duration</th>\n</tr>\n</thead>\n<tr>\n<td>All projects</td>\n<td class=\"numeric\">11.150s</td>\n</tr>\n<tr>\n<td>:</td>\n<td class=\"numeric\">11.150s</td>\n</tr>\n</table>\n</div>\n<div class=\"tab\" id=\"tab2\">\n<h2>Dependency Resolution</h2>\n<table>\n<thead>\n<tr>\n<th>Dependencies</th>\n<th class=\"numeric\">Duration</th>\n</tr>\n</thead>\n<tr>\n<td>All dependencies</td>\n<td class=\"numeric\">4.725s</td>\n</tr>\n<tr>\n<td>:classpath</td>\n<td class=\"numeric\">2.866s</td>\n</tr>\n<tr>\n<td>detachedConfiguration1</td>\n<td class=\"numeric\">1.857s</td>\n</tr>\n<tr>\n<td>detachedConfiguration2</td>\n<td class=\"numeric\">0.002s</td>\n</tr>\n</table>\n</div>\n<div class=\"tab\" id=\"tab3\">\n<h2>Artifact Transforms</h2>\n<table>\n<thead>\n<tr>\n<th>Transform</th>\n<th class=\"numeric\">Duration</th>\n</tr>\n</thead>\n<tr>\n<td>All transforms</td>\n<td class=\"numeric\">0s</td>\n</tr>\n</table>\n</div>\n<div class=\"tab\" id=\"tab4\">\n<h2>Task Execution</h2>\n<table>\n<thead>\n<tr>\n<th>Task</th>\n<th class=\"numeric\">Duration</th>\n<th>Result</th>\n</tr>\n</thead>\n<tr>\n<td>:</td>\n<td class=\"numeric\">0s</td>\n<td>(total)</td>\n</tr>\n</table>\n</div>\n</div>\n<div id=\"footer\">\n<p>\n<div>\n<label class=\"hidden\" id=\"label-for-line-wrapping-toggle\" for=\"line-wrapping-toggle\">Wrap lines\n<input id=\"line-wrapping-toggle\" type=\"checkbox\" autocomplete=\"off\"/>\n</label>\n</div>Generated by \n<a href=\"http://www.gradle.org\">Gradle 5.6.3</a> at Mar 31, 2020 2:39:17 PM</p>\n</div>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':epoxy-adapter'\ninclude ':epoxy-sample'\ninclude ':epoxy-processor'\ninclude ':epoxy-annotations'\ninclude ':epoxy-processortest'\ninclude ':epoxy-processortest2'\ninclude ':epoxy-integrationtest'\ninclude ':epoxy-databinding'\ninclude ':epoxy-paging3'\ninclude ':kotlinsample'\ninclude ':epoxy-modelfactory'\ninclude ':epoxy-modelfactorytest'\ninclude ':epoxy-glide-preloader'\ninclude ':epoxy-preloadersample'\ninclude ':epoxy-viewbinder'\ninclude ':epoxy-compose'\ninclude ':epoxy-composesample'\ninclude ':epoxy-composeinterop-maverickssample'\ninclude ':epoxy-kspsample'\n"
  }
]