master f9fbb291a784 cached
76 files
113.6 KB
31.8k tokens
1 requests
Download .txt
Repository: wayfair-incubator/panel-layout
Branch: master
Commit: f9fbb291a784
Files: 76
Total size: 113.6 KB

Directory structure:
gitextract_i0r_bc1v/

├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .idea/
│   ├── .name
│   ├── codeStyles
│   ├── gradle.xml
│   ├── jarRepositories.xml
│   ├── misc.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MAINTAINERS.md
├── README.md
├── RELEASING.md
├── SECURITY.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── wayfair/
│       │               └── panellayout/
│       │                   └── ExampleInstrumentedTest.kt
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── wayfair/
│           │           └── panellayout/
│           │               ├── MainActivity.kt
│           │               └── MaterialCardViewExt.kt
│           └── res/
│               ├── drawable/
│               │   ├── ic_ballpoint_pen.xml
│               │   ├── ic_baseline_visibility_off.xml
│               │   ├── ic_baseline_visibility_on.xml
│               │   ├── ic_circle.xml
│               │   ├── ic_circle_outline.xml
│               │   ├── ic_color_fill.xml
│               │   ├── ic_eraser.xml
│               │   ├── ic_fountain_pen.xml
│               │   ├── ic_grease_pencil.xml
│               │   ├── ic_launcher_background.xml
│               │   ├── ic_pencil.xml
│               │   ├── ic_resize.xml
│               │   ├── ic_select.xml
│               │   ├── ic_show_hide_button.xml
│               │   ├── ic_square.xml
│               │   ├── ic_square_outline.xml
│               │   ├── ic_text.xml
│               │   ├── ic_triangle.xml
│               │   └── ic_triangle_outline.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── colors.xml
│               │   ├── shapes.xml
│               │   └── tools.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── strings.xml
│                   └── styles.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── panellayout/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── wayfair/
│           │           └── panellayout/
│           │               ├── PanelLayout.kt
│           │               ├── PanelLayoutCommands.kt
│           │               ├── PanelPosition.kt
│           │               └── PanelState.kt
│           └── res/
│               ├── layout/
│               │   ├── panel_view_default_snap_bottom.xml
│               │   ├── panel_view_default_snap_left.xml
│               │   ├── panel_view_default_snap_right.xml
│               │   └── panel_view_default_snap_top.xml
│               └── values/
│                   ├── panel_attrs.xml
│                   ├── panel_colors.xml
│                   ├── panel_dimens.xml
│                   └── panel_integers.xml
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    branches: [ master ]
  pull_request:
    paths-ignore:
      - 'docs/**'
      - '*.md'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - uses: gradle/wrapper-validation-action@v1

      - name: Build
        run: ./gradlew build -s


================================================
FILE: .github/workflows/release.yml
================================================
name: Publish a release

on:
  push:
    tags:
      - '*'

jobs:
  plugin-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout the repo
        uses: actions/checkout@v2
      - name: Publish
        run: ./gradlew publish
        env:
          BINTRAY_API_KEY: ${{ secrets.BINTRAY_API_KEY }}
          BINTRAY_USER: ${{ secrets.BINTRAY_USER }}


================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx


================================================
FILE: .idea/.name
================================================
Panel Layout

================================================
FILE: .idea/codeStyles
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectCodeStyleConfiguration">
    <code_scheme name="Project" version="173">
      <Objective-C-extensions>
        <file>
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
        </file>
        <class>
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
          <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
        </class>
        <extensions>
          <pair source="cpp" header="h" fileNamingConvention="NONE" />
          <pair source="c" header="h" fileNamingConvention="NONE" />
        </extensions>
      </Objective-C-extensions>
    </code_scheme>
  </component>
</project>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="testRunner" value="PLATFORM" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="gradleJvm" value="1.8" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
            <option value="$PROJECT_DIR$/panellayout" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/jarRepositories.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RemoteRepositoriesConfiguration">
    <remote-repository>
      <option name="id" value="central" />
      <option name="name" value="Maven Central repository" />
      <option name="url" value="https://repo1.maven.org/maven2" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="jboss.community" />
      <option name="name" value="JBoss Community repository" />
      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="BintrayJCenter" />
      <option name="name" value="BintrayJCenter" />
      <option name="url" value="https://jcenter.bintray.com/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="Google" />
      <option name="name" value="Google" />
      <option name="url" value="https://dl.google.com/dl/android/maven2/" />
    </remote-repository>
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CMakeSettings">
    <configurations>
      <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
    </configurations>
  </component>
  <component name="MarkdownProjectSettings" wasCopied="true">
    <PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true" openRemoteLinks="true" replaceUnicodeEmoji="false" lastLayoutSetsDefault="false">
      <PanelProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
      </PanelProvider>
    </PreviewSettings>
    <ParserSettings gitHubSyntaxChange="false" emojiShortcuts="1" emojiImages="0">
      <PegdownExtensions>
        <option name="ABBREVIATIONS" value="false" />
        <option name="ANCHORLINKS" value="true" />
        <option name="ASIDE" value="false" />
        <option name="ATXHEADERSPACE" value="true" />
        <option name="AUTOLINKS" value="true" />
        <option name="DEFINITIONS" value="false" />
        <option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
        <option name="FENCED_CODE_BLOCKS" value="true" />
        <option name="FOOTNOTES" value="false" />
        <option name="HARDWRAPS" value="false" />
        <option name="HTML_DEEP_PARSER" value="false" />
        <option name="INSERTED" value="false" />
        <option name="QUOTES" value="false" />
        <option name="RELAXEDHRULES" value="true" />
        <option name="SMARTS" value="false" />
        <option name="STRIKETHROUGH" value="true" />
        <option name="SUBSCRIPT" value="false" />
        <option name="SUPERSCRIPT" value="false" />
        <option name="SUPPRESS_HTML_BLOCKS" value="false" />
        <option name="SUPPRESS_INLINE_HTML" value="false" />
        <option name="TABLES" value="true" />
        <option name="TASKLISTITEMS" value="true" />
        <option name="TOC" value="false" />
        <option name="WIKILINKS" value="false" />
      </PegdownExtensions>
      <ParserOptions>
        <option name="ADMONITION_EXT" value="false" />
        <option name="ATTRIBUTES_EXT" value="false" />
        <option name="COMMONMARK_LISTS" value="true" />
        <option name="DUMMY" value="false" />
        <option name="EMOJI_SHORTCUTS" value="true" />
        <option name="ENUMERATED_REFERENCES_EXT" value="false" />
        <option name="FLEXMARK_FRONT_MATTER" value="false" />
        <option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
        <option name="GFM_TABLE_RENDERING" value="true" />
        <option name="GITBOOK_URL_ENCODING" value="false" />
        <option name="GITHUB_LISTS" value="false" />
        <option name="GITHUB_WIKI_LINKS" value="false" />
        <option name="GITLAB_EXT" value="false" />
        <option name="GITLAB_MATH_EXT" value="false" />
        <option name="GITLAB_MERMAID_EXT" value="false" />
        <option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" />
        <option name="HEADER_ID_NO_DUPED_DASHES" value="false" />
        <option name="JEKYLL_FRONT_MATTER" value="false" />
        <option name="MACROS_EXT" value="false" />
        <option name="NO_TEXT_ATTRIBUTES" value="false" />
        <option name="PARSE_HTML_ANCHOR_ID" value="false" />
        <option name="PLANTUML_FENCED_CODE" value="false" />
        <option name="PUML_FENCED_CODE" value="false" />
        <option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
      </ParserOptions>
    </ParserSettings>
    <HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" plantUmlConversion="0" mathConversion="0">
      <GeneratorProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
      </GeneratorProvider>
      <headerTop />
      <headerBottom />
      <bodyTop />
      <bodyBottom />
    </HtmlSettings>
    <CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
      <StylesheetProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
      </StylesheetProvider>
      <ScriptProviders />
      <cssText />
      <cssUriHistory />
    </CssSettings>
    <HtmlExportSettings updateOnSave="false" parentDir="" targetDir="" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
    <LinkMapSettings>
      <textMaps />
    </LinkMapSettings>
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: CHANGELOG.md
================================================
### v1.0.0-alpha02
- Fixes a bug that prevents resizing of the panel.

### v1.0.0-alpha01
- The very first release!


================================================
FILE: CONTRIBUTING.md
================================================
## Contributing to Panel Layout
First off, thank you for your interest in contributing to Panel Layout!

### Issue first
Found a bug 🐛, have an idea 💡, or want to improve something 🔧?

Please open an issue first describing the problem, your idea or possible improvements. Getting early feedback on your idea will save a ton of time before writing code in advance and realizing the idea is not feasible or not aligned with the goals of the project.

### Pull Requests
Please try to cover added / modified functions with tests as much as possible and make tests a part of your PR.

Writing a good description with screenshots / screen captures when necessary will help your PR get accepted / merged quickly.




================================================
FILE: LICENSE.md
================================================
BSD 2-Clause License

Copyright (c) 2020 Wayfair GmbH

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: MAINTAINERS.md
================================================
mkojadinovic [at] wayfair.com


================================================
FILE: README.md
================================================
*ARCHIVED* -- Wayfair's technology team is now focused on other endeavors. Please consider this project archived / available as-is until further notice.

## Panel Layout

![CI](https://github.com/GradleUp/auto-manifest/workflows/CI/badge.svg)

Panel Layout is a UI library for Android that allows you to display a floating and resizable panel that can also snap to the edges.

Panel Layout makes use of [ConstraintLayout](https://developer.android.com/training/constraint-layout) to lay out panel with rest of the content.

This library is inspired by a good iOS UI framework: [PanelKit](https://github.com/louisdh/panelkit)

![](https://user-images.githubusercontent.com/4990386/83229577-e6564f00-a190-11ea-8998-97322e3d818d.gif)

### Importing Panel Layout

[ ![Bintray](https://img.shields.io/bintray/v/wayfair/PanelLayout/PanelLayout) ](https://bintray.com/wayfair/PanelLayout/PanelLayout/_latestVersion)


```kotlin
dependencies {
    implementation("com.wayfair.panellayout:panellayout:<latest-version>")
}
```

**Note:** Panel Layout is currently in alpha and the public API it offers is __subject to heavy changes__.

### Panel Layout API
Define if the Panel Layout is visible
```kotlin
var panelVisible: Boolean
```

The command that put Panel Layout in one of the predefine Panel Positions.
Possible panel positions are: `LEFT_EDGE`, `RIGHT_EDGE`, `TOP_EDGE`, `BOTTOM_EDGE`, `NO_EDGE`.
```kotlin
fun snapPanelTo(panelPosition: PanelPosition)
```

The command that put the Panel Layout in absolute position with coordinates `x` and `y`.
```kotlin
fun popPanelTo(x: Int, y: Int)
```

Define a listener to define actions on different kinds of events.
```kotlin
var panelLayoutCallbacks: PanelLayout.Callbacks?

interface Callbacks {
    fun beforeSnap(position: PanelPosition)
    fun afterSnap(position: PanelPosition)
    fun beforePop(popToX: Int, popToY: Int)
    fun afterPop(popToX: Int, popToY: Int)
    fun afterClose()
}
```

### Panel Layout attributes

`panel_content` - Resource id of view where is placed the Panel Layout

`panel_view` - Resource id of view inside the Panel Layout
 
`panel_move_handle` - Resource id of view used for moving the Panel Layout inside of content view

`panel_resize_enabled` - Flag that defines if the Panel Layout is resizable

`panel_snap_to_edges` - Define edges where the Panel Layout could be snapped. Possible values: `all`, `none`, `left`, `top`, `right` and `bottom`

`panel_start_height` - Start height

`panel_start_width` - Start width

### How to Use Panel Layout

Add Panel Layout in your layout:
```xml
<com.wayfair.panellayout.PanelLayout
        android:id="@+id/panelLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:panel_content="@id/content"
        app:panel_move_handle="@id/moveHandle"
        app:panel_resize_enabled="true"
        app:panel_resize_handle="@id/resizeHandle"
        app:panel_snap_to_edges="all"
        app:panel_start_height="300dp"
        app:panel_start_width="300dp"
        app:panel_view="@id/panel">

        <FrameLayout
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#f3e5f5">
        </FrameLayout>

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/panel"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:cardBackgroundColor="@color/white">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <View
                    android:id="@+id/moveHandle"
                    android:layout_width="match_parent"
                    android:layout_height="48dp"
                    android:background="#e1bee7" />

                <ImageView
                    android:id="@+id/resizeHandle"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:layout_gravity="bottom|end"
                    android:padding="4dp"
                    android:src="@drawable/ic_resize"
                    app:tint="@color/divider" />
            </FrameLayout>
        </com.google.android.material.card.MaterialCardView>
    </com.wayfair.panellayout.PanelLayout>
``` 

Controls and listeners in the code:
```kotlin
panelLayout.panelVisible = !panelLayout.panelVisible
```
```kotlin
panelLayout.popPanelTo(100, 100)
```
```kotlin
panelLayout.snapPanelTo(PanelPosition.RIGHT_EDGE)
```
```kotlin
panelLayout.panelLayoutCallbacks = object : PanelLayout.Callbacks {
    override fun beforeSnap(position: PanelPosition) {
        TODO("Not yet implemented")
    }

    override fun afterSnap(position: PanelPosition) {
        TODO("Not yet implemented")
    }

    override fun beforePop(popToX: Int, popToY: Int) {
        TODO("Not yet implemented")
    }

    override fun afterPop(popToX: Int, popToY: Int) {
        TODO("Not yet implemented")
    }

    override fun afterClose() {
        TODO("Not yet implemented")
    }
}
```

### LICENSE

Panel Layout is licensed under 2-clause BSD License

See [LICENSE.md](LICENSE.md) for details.

### CONTRIBUTION

Panel Layout is open to contribution. See [CONTRIBUTING.md](CONTRIBUTING.md) for details


================================================
FILE: RELEASING.md
================================================
Releasing
========

 1. Change the version in `gradle.properties` to a new version.
 1. Update the `CHANGELOG.md` for the impending release.
 1. `git commit -am "Prepare for release X.Y.Z."` (where X.Y.Z is the new version)
 1. `git tag -a X.Y.X -m "Version X.Y.Z"` (where X.Y.Z is the new version)
 1. `git push && git push --tags`
 1. Wait for CI to publish and verify the version in `README.md` 


================================================
FILE: SECURITY.md
================================================
If you have discovered a security vulnerability, please email opensource@wayfair.com


================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "com.wayfair.panellayout.sample"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildFeatures {
        buildConfig = false
        resValues = false
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0'

    implementation project(':panellayout')

    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}


================================================
FILE: app/src/androidTest/java/com/wayfair/panellayout/ExampleInstrumentedTest.kt
================================================
package com.wayfair.panellayout

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun useAppContext() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.wayfair.panellayout", appContext.packageName)
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wayfair.panellayout">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


================================================
FILE: app/src/main/java/com/wayfair/panellayout/MainActivity.kt
================================================
package com.wayfair.panellayout

import android.content.res.ColorStateList
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.children
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.colors.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        addShowHideClickListener()
        addPanelElevationAndRadiusAnimations()
        addColorSelectorClickListener()
    }

    private fun addShowHideClickListener() {
        showHideButton.setOnClickListener {
            panelLayout.panelVisible = !panelLayout.panelVisible
            showHideButton.isSelected = !showHideButton.isSelected
        }
    }

    private fun addColorSelectorClickListener() {
        colorSelector.children.forEach { child ->
            child.setOnClickListener {
                it.backgroundTintList?.defaultColor?.let { color ->
                    art.imageTintList = ColorStateList.valueOf(color)
                }
            }
        }
    }

    private fun addPanelElevationAndRadiusAnimations() {
        panelLayout.panelLayoutCallbacks = object : PanelLayout.Callbacks {
            override fun beforeSnap(position: PanelPosition) {
                panel.animateRadius(
                    from = resources.getDimension(R.dimen.panel_corner_radius),
                    to = resources.getDimension(R.dimen.zero)
                )

                panel.animateElevation(
                    from = resources.getDimension(R.dimen.panel_elevation),
                    to = resources.getDimension(R.dimen.zero)
                )
            }

            override fun afterSnap(position: PanelPosition) {}

            override fun beforePop(popToX: Int, popToY: Int) {
                panel.animateRadius(
                    from = resources.getDimension(R.dimen.zero),
                    to = resources.getDimension(R.dimen.panel_corner_radius)
                )

                panel.animateElevation(
                    from = resources.getDimension(R.dimen.zero),
                    to = resources.getDimension(R.dimen.panel_elevation)
                )
            }

            override fun afterPop(popToX: Int, popToY: Int) {}

            override fun afterClose() {}
        }
    }
}


================================================
FILE: app/src/main/java/com/wayfair/panellayout/MaterialCardViewExt.kt
================================================
package com.wayfair.panellayout

import android.animation.ValueAnimator
import com.google.android.material.card.MaterialCardView

fun MaterialCardView.animateRadius(from: Float, to: Float) =
    ValueAnimator.ofFloat(from, to).apply {
        addUpdateListener {
            radius = it.animatedValue as Float
        }
    }.start()


fun MaterialCardView.animateElevation(from: Float, to: Float) =
    ValueAnimator.ofFloat(from, to).apply {
        addUpdateListener {
            elevation = it.animatedValue as Float
        }
    }.start()


================================================
FILE: app/src/main/res/drawable/ic_ballpoint_pen.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M20.71,7.04C20.37,7.38 20.04,7.71 20.03,8.04C20,8.36 20.34,8.69 20.66,9C21.14,9.5 21.61,9.95 21.59,10.44C21.57,10.93 21.06,11.44 20.55,11.94L16.42,16.08L15,14.66L19.25,10.42L18.29,9.46L16.87,10.87L13.12,7.12L16.96,3.29C17.35,2.9 18,2.9 18.37,3.29L20.71,5.63C21.1,6 21.1,6.65 20.71,7.04M3,17.25L12.56,7.68L16.31,11.43L6.75,21H3V17.25Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_baseline_visibility_off.xml
================================================
<vector android:height="24dp"
    android:tint="#FFFFFF"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_baseline_visibility_on.xml
================================================
<vector android:height="24dp"
    android:tint="#FFFFFF"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_circle.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_circle_outline.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_color_fill.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M19,11.5C19,11.5 17,13.67 17,15A2,2 0 0,0 19,17A2,2 0 0,0 21,15C21,13.67 19,11.5 19,11.5M5.21,10L10,5.21L14.79,10M16.56,8.94L7.62,0L6.21,1.41L8.59,3.79L3.44,8.94C2.85,9.5 2.85,10.47 3.44,11.06L8.94,16.56C9.23,16.85 9.62,17 10,17C10.38,17 10.77,16.85 11.06,16.56L16.56,11.06C17.15,10.47 17.15,9.5 16.56,8.94Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_eraser.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M16.24,3.56L21.19,8.5C21.97,9.29 21.97,10.55 21.19,11.34L12,20.53C10.44,22.09 7.91,22.09 6.34,20.53L2.81,17C2.03,16.21 2.03,14.95 2.81,14.16L13.41,3.56C14.2,2.78 15.46,2.78 16.24,3.56M4.22,15.58L7.76,19.11C8.54,19.9 9.8,19.9 10.59,19.11L14.12,15.58L9.17,10.63L4.22,15.58Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_fountain_pen.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M6.95,14.93L11.19,9.27L19.68,2.2C20.07,1.81 20.72,1.81 21.09,2.2L21.8,2.91C22.19,3.28 22.19,3.93 21.8,4.32L14.73,12.81L9.07,17.05L6.95,14.93M8.36,17.76L6.24,15.64L3.41,17.05L2,21.29L4.12,19.17C4.32,19 4.63,19 4.83,19.17C5,19.37 5,19.68 4.83,19.88L2.71,22L6.95,20.59L8.36,17.76Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_grease_pencil.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M18.62,1.5C18.11,1.5 17.6,1.69 17.21,2.09L10.75,8.55L14.95,12.74L21.41,6.29C22.2,5.5 22.2,4.24 21.41,3.46L20.04,2.09C19.65,1.69 19.14,1.5 18.62,1.5M9.8,9.5L3.23,16.07L3.93,16.77C3.4,17.24 2.89,17.78 2.38,18.29C1.6,19.08 1.6,20.34 2.38,21.12C3.16,21.9 4.42,21.9 5.21,21.12C5.72,20.63 6.25,20.08 6.73,19.58L7.43,20.27L14,13.7" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="108dp"
    android:height="108dp"
    android:viewportWidth="108"
    android:viewportHeight="108">
    <path
        android:fillColor="#3DDC84"
        android:pathData="M0,0h108v108h-108z" />
    <path
        android:fillColor="#00000000"
        android:pathData="M9,0L9,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,0L19,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,0L29,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,0L39,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,0L49,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,0L59,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,0L69,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,0L79,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M89,0L89,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M99,0L99,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,9L108,9"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,19L108,19"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,29L108,29"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,39L108,39"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,49L108,49"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,59L108,59"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,69L108,69"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,79L108,79"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,89L108,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,99L108,99"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,29L89,29"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,39L89,39"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,49L89,49"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,59L89,59"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,69L89,69"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,79L89,79"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,19L29,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,19L39,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,19L49,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,19L59,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,19L69,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,19L79,89"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_pencil.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_resize.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M22,22H20V20H22V22M22,18H20V16H22V18M18,22H16V20H18V22M18,18H16V16H18V18M14,22H12V20H14V22M22,14H20V12H22V14Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_select.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M4,3H5V5H3V4A1,1 0 0,1 4,3M20,3A1,1 0 0,1 21,4V5H19V3H20M15,5V3H17V5H15M11,5V3H13V5H11M7,5V3H9V5H7M21,20A1,1 0 0,1 20,21H19V19H21V20M15,21V19H17V21H15M11,21V19H13V21H11M7,21V19H9V21H7M4,21A1,1 0 0,1 3,20V19H5V21H4M3,15H5V17H3V15M21,15V17H19V15H21M3,11H5V13H3V11M21,11V13H19V11H21M3,7H5V9H3V7M21,7V9H19V7H21Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_show_hide_button.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_baseline_visibility_on" android:state_selected="true" />
    <item android:drawable="@drawable/ic_baseline_visibility_off" />
</selector>


================================================
FILE: app/src/main/res/drawable/ic_square.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M3,3V21H21V3" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_square_outline.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M3,3H21V21H3V3M5,5V19H19V5H5Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_text.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M9.62,12L12,5.67L14.37,12M11,3L5.5,17H7.75L8.87,14H15.12L16.25,17H18.5L13,3H11Z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_triangle.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M1,21H23L12,2" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_triangle_outline.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M12,2L1,21H23M12,6L19.53,19H4.47" />
</vector>


================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportWidth="108"
    android:viewportHeight="108">
    <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">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="85.84757"
                android:endY="92.4963"
                android:startX="42.9492"
                android:startY="49.59793"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        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"
        android:strokeWidth="1"
        android:strokeColor="#00000000" />
</vector>


================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.wayfair.panellayout.PanelLayout
        android:id="@+id/panelLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:panel_content="@id/content"
        app:panel_move_handle="@id/moveHandle"
        app:panel_resize_enabled="true"
        app:panel_resize_handle="@id/resizeHandle"
        app:panel_snap_to_edges="all"
        app:panel_start_height="300dp"
        app:panel_start_width="300dp"
        app:panel_view="@id/panel">

        <FrameLayout
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#f3e5f5">

            <FrameLayout
                android:id="@+id/canvas"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="16dp"
                android:background="@color/white"
                android:elevation="2dp">

                <ImageView
                    android:id="@+id/art"
                    android:scaleType="centerCrop"
                    android:layout_gravity="center"
                    android:layout_width="96dp"
                    android:layout_height="96dp"
                    android:tint="@color/colorAccent"
                    android:src="@drawable/ic_triangle_outline" />
            </FrameLayout>

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/showHideButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_margin="32dp"
                android:src="@drawable/ic_show_hide_button"
                app:backgroundTint="@color/colorAccent"
                app:fabSize="normal"
                app:tint="@color/white" />
        </FrameLayout>

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/panel"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:cardBackgroundColor="@color/white">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ScrollView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="48dp">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:padding="16dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/tools"
                            android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
                            android:textColor="@color/charcoal" />

                        <View
                            android:layout_width="match_parent"
                            android:layout_height="1dp"
                            android:layout_marginVertical="16dp"
                            android:background="@color/divider" />

                        <include
                            layout="@layout/tools"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content" />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="24dp"
                            android:text="@string/shapes"
                            android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
                            android:textColor="@color/charcoal" />

                        <View
                            android:layout_width="match_parent"
                            android:layout_height="1dp"
                            android:layout_marginVertical="16dp"
                            android:background="@color/divider" />

                        <include
                            layout="@layout/shapes"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content" />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="24dp"
                            android:text="@string/colors"
                            android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
                            android:textColor="@color/charcoal" />

                        <View
                            android:layout_width="match_parent"
                            android:layout_height="1dp"
                            android:layout_marginVertical="16dp"
                            android:background="@color/divider" />

                        <include
                            layout="@layout/colors"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content" />
                    </LinearLayout>
                </ScrollView>

                <View
                    android:id="@+id/moveHandle"
                    android:layout_width="match_parent"
                    android:layout_height="48dp"
                    android:background="#e1bee7" />

                <ImageView
                    android:id="@+id/resizeHandle"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:layout_gravity="bottom|end"
                    android:padding="4dp"
                    android:src="@drawable/ic_resize"
                    app:tint="@color/divider" />
            </FrameLayout>
        </com.google.android.material.card.MaterialCardView>
    </com.wayfair.panellayout.PanelLayout>
</androidx.constraintlayout.widget.ConstraintLayout>


================================================
FILE: app/src/main/res/layout/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/colorSelector"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingConstraints">

    <androidx.constraintlayout.helper.widget.Flow
        android:id="@+id/flow"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:constraint_referenced_ids="color1, color2, color3, color4, color5, color6, color7, color8, color9, color10, color11, color12, color13, color14, color15, color16, color17, color18, color19, color20, color21, color22, color23"
        app:flow_horizontalGap="16dp"
        app:flow_verticalGap="16dp"
        app:flow_wrapMode="aligned"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/color1"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color1" />

    <View
        android:id="@+id/color2"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color2" />

    <View
        android:id="@+id/color3"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color3" />

    <View
        android:id="@+id/color4"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color4" />

    <View
        android:id="@+id/color5"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color5" />

    <View
        android:id="@+id/color6"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color6" />

    <View
        android:id="@+id/color7"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color7" />

    <View
        android:id="@+id/color8"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color8" />

    <View
        android:id="@+id/color9"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color9" />

    <View
        android:id="@+id/color10"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color10" />

    <View
        android:id="@+id/color11"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color11" />

    <View
        android:id="@+id/color12"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color12" />

    <View
        android:id="@+id/color13"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color13" />

    <View
        android:id="@+id/color14"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color14" />

    <View
        android:id="@+id/color15"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color15" />

    <View
        android:id="@+id/color16"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color16" />

    <View
        android:id="@+id/color17"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color17" />

    <View
        android:id="@+id/color18"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color18" />

    <View
        android:id="@+id/color19"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color19" />

    <View
        android:id="@+id/color20"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color20" />

    <View
        android:id="@+id/color21"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color21" />

    <View
        android:id="@+id/color22"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color22" />

    <View
        android:id="@+id/color23"
        android:layout_width="@dimen/color_width"
        android:layout_height="@dimen/color_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/color23" />
</androidx.constraintlayout.widget.ConstraintLayout>


================================================
FILE: app/src/main/res/layout/shapes.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingConstraints">

    <View
        android:id="@+id/shape1"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_circle"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/shape2"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_circle_outline"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/shape3"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_square"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/shape4"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_square_outline"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/shape5"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_triangle"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/shape6"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_triangle_outline"
        android:backgroundTint="@color/charcoal" />


    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:constraint_referenced_ids="shape1, shape2, shape3, shape4, shape5, shape6"
        app:flow_horizontalGap="16dp"
        app:flow_verticalGap="16dp"
        app:flow_wrapMode="aligned"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


================================================
FILE: app/src/main/res/layout/tools.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingConstraints">

    <View
        android:id="@+id/tool1"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_pencil"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool2"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_grease_pencil"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool3"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_fountain_pen"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool4"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_ballpoint_pen"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool5"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_eraser"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool6"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_select"
        android:backgroundTint="@color/charcoal" />

    <View
        android:id="@+id/tool7"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_color_fill"
        android:backgroundTint="@color/charcoal" />


    <View
        android:id="@+id/tool8"
        android:layout_width="@dimen/tool_width"
        android:layout_height="@dimen/tool_width"
        android:background="@drawable/ic_text"
        android:backgroundTint="@color/charcoal" />


    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:constraint_referenced_ids="tool1, tool2, tool3, tool4, tool5, tool6, tool7, tool8"
        app:flow_horizontalGap="16dp"
        app:flow_verticalGap="16dp"
        app:flow_wrapMode="aligned"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>


================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>


================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#9C27B0</color>
    <color name="colorPrimaryDark">#6a0080</color>
    <color name="colorAccent">#9C27B0</color>
    <color name="white">#FFFFFF</color>
    <color name="divider">#20000000</color>
    <color name="charcoal">#424242</color>

    <!-- Color picker values-->
    <color name="color1">#F44336</color>
    <color name="color2">#E91E63</color>
    <color name="color3">#9C27B0</color>
    <color name="color4">#673AB7</color>
    <color name="color5">#3F51B5</color>
    <color name="color6">#2196F3</color>
    <color name="color7">#03A9F4</color>
    <color name="color8">#00BCD4</color>
    <color name="color9">#009688</color>
    <color name="color10">#4CAF50</color>
    <color name="color11">#8BC34A</color>
    <color name="color12">#CDDC39</color>
    <color name="color13">#FFEB3B</color>
    <color name="color14">#FFC107</color>
    <color name="color15">#FF9800</color>
    <color name="color16">#FF5722</color>
    <color name="color17">#795548</color>
    <color name="color18">#9E9E9E</color>
    <color name="color19">#757575</color>
    <color name="color20">#616161</color>
    <color name="color21">#424242</color>
    <color name="color22">#212121</color>
    <color name="color23">#FFFFFF</color>
</resources>


================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="zero">0dp</dimen>
    <dimen name="panel_elevation">4dp</dimen>
    <dimen name="panel_corner_radius">4dp</dimen>
    <dimen name="tool_width">32dp</dimen>
    <dimen name="color_width">32dp</dimen>
</resources>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">Panel Layout</string>
    <string name="shapes">Shapes</string>
    <string name="tools">Tools</string>
    <string name="colors">Colors</string>
</resources>


================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue May 05 17:46:57 EET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip


================================================
FILE: gradle.properties
================================================
org.gradle.jvmargs=-Xmx2048m
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official

GROUP=com.wayfair.panellayout
VERSION_NAME=1.0.0-alpha02

POM_URL=https://github.com/wayfair-incubator/panel-layout/
POM_SCM_URL=https://github.com/wayfair-incubator/panel-layout.git
POM_SCM_CONNECTION=scm:git:git://github.com/wayfair-incubator/panel-layout.git
POM_LICENCE_NAME=BSD 2-Clause "Simplified" License
POM_LICENCE_URL=https://raw.githubusercontent.com/wayfair-incubator/panel-layout/master/LICENSE
POM_LICENCE_DIST=repo

# https://github.com/gradle/gradle/issues/11412
systemProp.org.gradle.internal.publish.checksums.insecure=true


================================================
FILE: gradlew
================================================
#!/usr/bin/env sh

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
    echo "$*"
}

die () {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
  NONSTOP* )
    nonstop=true
    ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Escape application args
save () {
    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
    echo " "
}
APP_ARGS=$(save "$@")

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
  cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: panellayout/.gitignore
================================================
/build


================================================
FILE: panellayout/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'org.gradle.maven-publish'

android {
    compileSdkVersion 28

    defaultConfig {
        minSdkVersion 21
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8
    }
    buildFeatures {
        buildConfig = false
        resValues = false
    }
}

androidExtensions {
    features = ['parcelize']
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation "androidx.transition:transition:1.3.1"
}

publishing {
    publications.create("default", MavenPublication) {
        afterEvaluate {
            from(components.findByName("release"))
        }

        def sourcesJarTask = tasks.create("sourcesJar", Jar) {
            archiveClassifier.set("sources")
            from(android.sourceSets["main"].java.srcDirs)
        }
        artifact(sourcesJarTask)

        groupId = findProperty("GROUP")
        version = findProperty("VERSION_NAME")
        artifactId = findProperty("POM_ARTIFACT_ID")

        pom {
            name = findProperty("POM_NAME")
            description = findProperty("POM_DESCRIPTION")
            packaging = findProperty("POM_PACKAGING")
            url = findProperty("POM_URL")

            scm {
                url = findProperty("POM_SCM_URL")
                connection = findProperty("POM_SCM_CONNECTION")
            }

            licenses {
                license {
                    name = findProperty("POM_LICENCE_NAME")
                    url = findProperty("POM_LICENCE_URL")
                }
            }
        }
    }

    repositories {
        maven {
            name = "bintray"
            url = uri("https://api.bintray.com/maven/wayfair/PanelLayout/PanelLayout/;publish=1;override=1")
            credentials {
                username = System.getenv("BINTRAY_USER")
                password = System.getenv("BINTRAY_API_KEY")
            }
        }
    }
}


================================================
FILE: panellayout/gradle.properties
================================================
POM_ARTIFACT_ID=panellayout
POM_NAME=Panel Layout
POM_DESCRIPTION=UI library for Android that allows you to display a floating and resizable panel that can also snap to the edges.
POM_PACKAGING=aar


================================================
FILE: panellayout/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.wayfair.panellayout" />


================================================
FILE: panellayout/src/main/java/com/wayfair/panellayout/PanelLayout.kt
================================================
/*  These imports produce a detekt false-positive:
    import androidx.core.graphics.component1
    import androidx.core.graphics.component2
    import androidx.core.graphics.component3
    import androidx.core.graphics.component4

    So UnusedImports are suppressed. */
@file:Suppress("UnusedImports", "CommentOverPrivateFunction")

package com.wayfair.panellayout

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.TypedArray
import android.graphics.Rect
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
import android.view.*
import android.view.MotionEvent.*
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.annotation.ColorRes
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.core.content.res.getResourceIdOrThrow
import androidx.core.graphics.component1
import androidx.core.graphics.component2
import androidx.core.graphics.component3
import androidx.core.graphics.component4
import androidx.core.graphics.drawable.toDrawable
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.transition.AutoTransition
import androidx.transition.ChangeBounds
import androidx.transition.Transition
import androidx.transition.TransitionManager
import com.wayfair.panellayout.PanelPosition.*
import com.wayfair.panellayout.PanelPosition.values
import com.wayfair.panellayout.PanelState.HorizontalEdge.LEFT
import com.wayfair.panellayout.PanelState.HorizontalEdge.RIGHT
import com.wayfair.panellayout.PanelState.Snap.ANIMATING
import com.wayfair.panellayout.PanelState.Snap.FLOATING
import com.wayfair.panellayout.PanelState.Snap.SNAPPED
import com.wayfair.panellayout.PanelState.VerticalEdge.BOTTOM
import com.wayfair.panellayout.PanelState.VerticalEdge.TOP
import kotlin.math.roundToInt
import kotlin.math.sqrt

@Suppress("LargeClass", "LongMethod") // It's hard to split view classes
@SuppressLint("ClickableViewAccessibility") // ClickableViewAccessibility: We do not want to handle clicks on move and resize handles
class PanelLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), PanelLayoutCommands {

    // Public field
    override var panelLayoutCallbacks: Callbacks? = null
    override var panelVisible: Boolean
        get() = panelState.isVisible
        set(value) {
            if (value) showPanel() else hidePanel()
        }

    // Attrs (initial values are not used)
    @IdRes
    private var panelResId = 0

    @IdRes
    private var contentResId = 0

    @IdRes
    private var moveHandleResId = 0

    @IdRes
    private var resizeHandleResId = 0

    private var resizeEnabled = false

    private var panelMinWidth = 0
    private var panelMaxWidth = 0

    private var panelMinHeight = 0
    private var panelMaxHeight = 0

    private var panelStartWidth = 0
    private var panelStartHeight = 0

    private var panelSnapWidth = 0f
    private var panelSnapHeight = 0f

    private var panelSnapWidthPercent = 0f
    private var panelSnapHeightPercent = 0f

    @LayoutRes
    private var snapLeftLayout = 0

    @LayoutRes
    private var snapTopLayout = 0

    @LayoutRes
    private var snapRightLayout = 0

    @LayoutRes
    private var snapBottomLayout = 0

    private var snapAnimationDuration = 0L
    private var snapOverlayAnimationDuration = 0L

    @ColorRes
    private var snapOverlayColor = 0

    private var snapToEdges = 0

    // View references
    private lateinit var content: View
    private lateinit var panelView: View
    private lateinit var moveHandle: View
    private var resizeHandle: View? = null

    private val leftOverlay = View(context)
    private val topOverlay = View(context)
    private val rightOverlay = View(context)
    private val bottomOverlay = View(context)

    private var isPanelStateRestored = false

    lateinit var panelState: PanelState

    val initialPanelState: PanelState
        get() = PanelState(
            snap = FLOATING,
            position = NO_EDGE,
            size = panelStartWidth to panelStartHeight
        )

    private val preferredSnapWidth: Float
        get() = when (panelSnapWidthPercent) {
            NOT_SET -> panelSnapWidth
            else -> width * panelSnapWidthPercent
        }

    private val preferredSnapHeight: Float
        get() = when (panelSnapHeightPercent) {
            NOT_SET -> panelSnapHeight
            else -> height * panelSnapHeightPercent
        }

    // Touch / motion related
    private val moveSnapListener = PanelMoveSnapListener()
    private val popListener = PanelPopListener()
    private val resizeListener = PanelResizeListener()

    private var lastDownEvent: MotionEvent? = null
    private var relativeTouchPositionX = 0f
    private var relativeTouchPositionY = 0f

    private var touchSubject: View? = null

    init {
        isMotionEventSplittingEnabled = false
        isSaveEnabled = true

        readAttrs(attrs)
        setUpOverlays()
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()

        if (!isPanelStateRestored) {
            panelState = initialPanelState
        }

        ensureChildren()
        setTouchListeners()
        restorePanelFromState()
    }

    private fun ensureChildren() {
        fun Int.toResourceName() = resources.getResourceName(this)

        require(::content.isInitialized) {
            "Could not find child (panel_content) with id: ${contentResId.toResourceName()}"
        }
        require(::panelView.isInitialized) {
            "Could not find child (panel_view) with id: ${panelResId.toResourceName()}"
        }
        require(::moveHandle.isInitialized) {
            "Could not find child (panel_move_handle) with id: ${moveHandleResId.toResourceName()}"
        }
        if (resizeEnabled) {
            require(resizeHandle != null) {
                "Could not find child (panel_resize_handle) with id: ${resizeHandleResId.toResourceName()}"
            }
        }
    }

    override fun addView(child: View, index: Int, params: ViewGroup.LayoutParams?) {
        super.addView(child, index, params)

        child.findViewById<View>(contentResId)?.let {
            content = it
        }
        child.findViewById<View>(panelResId)?.let {
            panelView = it
            moveHandle = it.findViewById(moveHandleResId)
        }
        if (resizeEnabled) {
            child.findViewById<View>(resizeHandleResId)?.let {
                resizeHandle = it
            }
        }
    }

    private fun restorePanelFromState() = post {
        if (!panelState.isVisible) {
            panelView.isVisible = false
        } else if (panelState.snap == FLOATING) {
            // Restore size
            val (withWidth, withHeight) = panelState.size

            // Restore position
            val toX = panelState.horizontalNearestEdgeDistance.toX(withWidth)
            val toY = panelState.verticalNearestEdgeDistance.toY(withHeight)

            applyFloatingPanelConstraints(toX, toY, withWidth, withHeight)
        } else {
            // Restore snap
            snapPanelTo(panelState.position)
        }
    }

    override fun onSaveInstanceState(): Parcelable? {
        val superState = super.onSaveInstanceState()

        return bundleOf(
            PARCELABLE_KEY_SUPER_STATE to superState,
            PARCELABLE_KEY_PANEL_STATE to panelState
        )
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        val bundle = state as Bundle
        panelState = bundle.getParcelable(PARCELABLE_KEY_PANEL_STATE)!!
        val superState: AbsSavedState? = bundle.getParcelable(PARCELABLE_KEY_SUPER_STATE)

        isPanelStateRestored = true

        super.onRestoreInstanceState(superState)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        if (panelState.snap == FLOATING) {
            coercePanelSize()
        }
    }

    private fun readAttrs(attrs: AttributeSet?) = attrs?.let {
        val a = context.obtainStyledAttributes(it, R.styleable.PanelLayout, 0, 0)
        try {
            readResizeEnabledAttr(a)
            readViewReferenceAttrs(a)
            readMinMaxSizeAttrs(a)
            readStartSizeAttrs(a)
            readSnapSizeAttrs(a)
            readSnapToEdgesAttr(a)
            readSnapAttrs(a)
            readOverlayAndAnimationAttrs(a)
        } finally {
            a.recycle()
        }
    }

    private fun readResizeEnabledAttr(a: TypedArray) {
        resizeEnabled = a.getBoolean(R.styleable.PanelLayout_panel_resize_enabled, true)
    }

    private fun readViewReferenceAttrs(a: TypedArray) {
        panelResId = a.getResourceIdOrThrow(R.styleable.PanelLayout_panel_view)
        contentResId = a.getResourceIdOrThrow(R.styleable.PanelLayout_panel_content)
        moveHandleResId = a.getResourceIdOrThrow(R.styleable.PanelLayout_panel_move_handle)
        resizeHandleResId = a.getResourceId(R.styleable.PanelLayout_panel_resize_handle, -1)
    }

    private fun readMinMaxSizeAttrs(a: TypedArray) {
        panelMinWidth = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_min_width,
            resources.getDimensionPixelSize(R.dimen.panel_default_min_width)
        )
        panelMaxWidth = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_max_width,
            resources.getDimensionPixelSize(R.dimen.panel_default_max_width)
        )
        panelMinHeight = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_min_height,
            resources.getDimensionPixelSize(R.dimen.panel_default_min_height)
        )
        panelMaxHeight = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_max_height,
            resources.getDimensionPixelSize(R.dimen.panel_default_max_height)
        )
    }

    private fun readStartSizeAttrs(a: TypedArray) {
        panelStartWidth = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_start_width,
            resources.getDimensionPixelSize(R.dimen.panel_default_start_width)
        )
        panelStartHeight = a.getDimensionPixelSize(
            R.styleable.PanelLayout_panel_start_height,
            resources.getDimensionPixelSize(R.dimen.panel_default_start_height)
        )
    }

    private fun readSnapSizeAttrs(a: TypedArray) {
        panelSnapWidthPercent = a.getFloat(R.styleable.PanelLayout_panel_snap_width_percent, NOT_SET)
        panelSnapHeightPercent = a.getFloat(R.styleable.PanelLayout_panel_snap_height_percent, NOT_SET)

        if (panelSnapWidthPercent == NOT_SET) {
            panelSnapWidth = a.getDimension(
                R.styleable.PanelLayout_panel_snap_width,
                resources.getDimension(R.dimen.panel_default_snap_width)
            )
        }

        if (panelSnapHeightPercent == NOT_SET) {
            panelSnapHeight = a.getDimension(
                R.styleable.PanelLayout_panel_snap_height,
                resources.getDimension(R.dimen.panel_default_snap_height)
            )
        }
    }

    private fun readSnapToEdgesAttr(a: TypedArray) {
        snapToEdges = a.getInt(
            R.styleable.PanelLayout_panel_snap_to_edges,
            R.integer.panel_default_snap_edges
        )
    }

    private fun readSnapAttrs(a: TypedArray) {
        snapLeftLayout = a.getResourceId(
            R.styleable.PanelLayout_panel_snap_left_layout,
            R.layout.panel_view_default_snap_left
        )
        snapTopLayout = a.getResourceId(
            R.styleable.PanelLayout_panel_snap_top_layout,
            R.layout.panel_view_default_snap_top
        )
        snapRightLayout = a.getResourceId(
            R.styleable.PanelLayout_panel_snap_right_layout,
            R.layout.panel_view_default_snap_right
        )
        snapBottomLayout = a.getResourceId(
            R.styleable.PanelLayout_panel_snap_bottom_layout,
            R.layout.panel_view_default_snap_bottom
        )
    }

    private fun readOverlayAndAnimationAttrs(a: TypedArray) {
        snapAnimationDuration = a.getInt(
            R.styleable.PanelLayout_panel_snap_animation_duration,
            resources.getInteger(R.integer.panel_default_snap_animation_duration)
        ).toLong()
        snapOverlayAnimationDuration = a.getInt(
            R.styleable.PanelLayout_panel_snap_overlay_animation_duration,
            resources.getInteger(R.integer.panel_default_snap_overlay_animation_duration)
        ).toLong()
        snapOverlayColor = a.getResourceId(
            R.styleable.PanelLayout_panel_snap_overlay_color,
            R.color.panel_default_snap_overlay_color
        )
    }

    private fun setUpOverlays() {
        for (overlay in arrayOf(leftOverlay, topOverlay, rightOverlay, bottomOverlay)) {
            overlay.background = ContextCompat.getColor(context, snapOverlayColor).toDrawable()
            overlay.alpha = 0f
            overlay.layoutParams = LayoutParams(1, 1) // create square 1px x 1px to scale later.
            overlay.elevation = 2f
            addView(overlay)
        }
    }

    private fun setTouchListeners() {
        setOnTouchListener { v: View, event: MotionEvent ->
            when (touchSubject) {
                moveHandle -> when (panelState.snap) {
                    FLOATING -> moveSnapListener.onTouch(v, event)
                    SNAPPED -> popListener.onTouch(v, event)
                    else -> false
                }
                resizeHandle -> when (panelState.snap) {
                    FLOATING -> resizeListener.onTouch(v, event)
                    else -> false
                }
                else -> false
            }
        }
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event.actionMasked) {
            ACTION_DOWN -> {
                relativeTouchPositionX = event.rawX - panelView.x
                relativeTouchPositionY = event.rawY - panelView.y

                lastDownEvent = obtain(event)

                if (moveHandle.containsInHitRect(event)) {
                    touchSubject = moveHandle
                } else if (resizeEnabled && resizeHandle != null && resizeHandle!!.containsInHitRect(event)) {
                    touchSubject = resizeHandle!!
                } else {
                    touchSubject = null
                }

                return false
            }
            ACTION_MOVE -> {
                return touchSubject != null && event.isSignificantlyDistantTo(lastDownEvent!!)
            }
            ACTION_UP -> {
                return touchSubject != null && event.isSignificantlyDistantTo(lastDownEvent!!)
            }
            ACTION_CANCEL -> {
                touchSubject = null
                return false
            }
            else -> return false
        }
    }

    /**
     * Imitates a panel resize with zero difference in size.
     * <p>
     * This will make sure the panel size is recalculated and limited by the new panelLayout size.
     * Whenever the keyboard is shown, we resize the panelView to fit into the limited space available.
     */
    private fun coercePanelSize() = post {
        val (updatedWidth, updatedHeight) = calculateNewSize(diffX = 0f, diffY = 0f)
        resizePanel(updatedWidth, updatedHeight)
    }

    private fun calculateNewSize(diffX: Float, diffY: Float): Pair<Int, Int> {
        var updatedWidth =
            (panelView.width + diffX).roundToInt().coerceIn(panelMinWidth, panelMaxWidth)
        var updatedHeight =
            (panelView.height + diffY).roundToInt().coerceIn(panelMinHeight, panelMaxHeight)

        // These negative adjustment values are to prevent resizing out of the panel layout
        val negativeAdjustmentX = (width - (panelView.x + updatedWidth)).coerceAtMost(0f).roundToInt()
        val negativeAdjustmentY = (height - (panelView.y + updatedHeight)).coerceAtMost(0f).roundToInt()

        updatedWidth += negativeAdjustmentX
        updatedHeight += negativeAdjustmentY

        return updatedWidth to updatedHeight
    }

    private fun resizePanel(updatedWidth: Int, updatedHeight: Int) {
        val params = panelView.layoutParams as LayoutParams
        params.width = updatedWidth
        params.height = updatedHeight
        panelView.layoutParams = params
    }

    private fun calculatePositionFor(x: Int, y: Int): PanelPosition {
        val (left, top, right, bottom) = panelView.moveBounds()

        if (x == left) return LEFT_EDGE
        if (x == right) return RIGHT_EDGE
        if (y == top) return TOP_EDGE
        if (y == bottom) return BOTTOM_EDGE
        return NO_EDGE
    }

    private fun showSnapOverlay(snapPosition: PanelPosition) {

        val overlay = snapPosition.overlay()
        val (touchPointX, touchPointY) = snapPosition.touchPoint()
        val (scaleX, scaleY) = snapPosition.overlayScale()

        overlay.translationX = touchPointX
        overlay.translationY = touchPointY
        overlay.pivotX = touchPointX / width
        overlay.pivotY = touchPointY / height

        overlay.clearAnimation()

        overlay.animate()
            .alpha(1f)
            .scaleX(scaleX)
            .scaleY(scaleY)
            .setDuration(snapOverlayAnimationDuration)
            .setInterpolator(AccelerateDecelerateInterpolator())
            .start()
    }

    private fun hideSnapOverlay(snapPosition: PanelPosition) {
        val overlay = snapPosition.overlay()

        overlay.clearAnimation()

        overlay.animate()
            .alpha(0f)
            .scaleX(0f)
            .scaleY(0f)
            .setDuration(snapOverlayAnimationDuration)
            .setInterpolator(AccelerateDecelerateInterpolator())
            .start()
    }

    private fun hidePanel() {
        if (panelState.snap == SNAPPED) {
            val transition = AutoTransition().apply {
                interpolator = AccelerateDecelerateInterpolator()
                duration = snapAnimationDuration

                addListener(object : Transition.TransitionListener {
                    override fun onTransitionEnd(transition: Transition) {
                        panelLayoutCallbacks?.afterClose()
                    }

                    override fun onTransitionStart(transition: Transition) {} // No-op
                    override fun onTransitionResume(transition: Transition) {} // No-op
                    override fun onTransitionPause(transition: Transition) {} // No-op
                    override fun onTransitionCancel(transition: Transition) {} // No-op
                })
            }

            TransitionManager.beginDelayedTransition(this, transition)
        }

        panelView.isVisible = false
        panelState.isVisible = false
    }

    private fun showPanel() {
        panelState.isVisible = true

        restorePanelFromState()
    }

    override fun popPanelTo(x: Int, y: Int) {
        panelState.snap = ANIMATING

        val (popWidth, popHeight) = panelState.sanitizedSize()

        val transition = ChangeBounds().apply {
            interpolator = AccelerateDecelerateInterpolator()
            duration = snapAnimationDuration

            addListener(object : Transition.TransitionListener {
                override fun onTransitionStart(transition: Transition) {
                    panelLayoutCallbacks?.beforePop(x, y)
                    resizeHandle?.isVisible = true
                }

                override fun onTransitionEnd(transition: Transition) {
                    panelLayoutCallbacks?.afterPop(x, y)
                }

                override fun onTransitionResume(transition: Transition) {} // No-op
                override fun onTransitionPause(transition: Transition) {} // No-op
                override fun onTransitionCancel(transition: Transition) {} // No-op
            })
        }

        TransitionManager.beginDelayedTransition(this, transition)

        applyFloatingPanelConstraints(x, y, popWidth, popHeight)

        panelState.position = NO_EDGE
        panelState.snap = FLOATING
    }

    private fun applyFloatingPanelConstraints(x: Int, y: Int, width: Int, height: Int) = ConstraintSet().apply {
        clone(this)
        clear(panelResId)
        clear(contentResId)

        connect(contentResId, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
        connect(contentResId, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
        connect(contentResId, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)
        connect(contentResId, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)

        setTranslationX(panelResId, x.toFloat())
        setTranslationY(panelResId, y.toFloat())

        constrainWidth(panelResId, width)
        constrainHeight(panelResId, height)

        applyTo(this@PanelLayout)
    }

    override fun snapPanelTo(panelPosition: PanelPosition) {
        if (panelState.snap == FLOATING) {
            switchToMarginPositioning()
        }

        panelState.snap = ANIMATING

        when (panelPosition) {
            LEFT_EDGE -> applyConstraintsWithAnimation(snapLeftLayout)
            RIGHT_EDGE -> applyConstraintsWithAnimation(snapRightLayout)
            TOP_EDGE -> applyConstraintsWithAnimation(snapTopLayout)
            BOTTOM_EDGE -> applyConstraintsWithAnimation(snapBottomLayout)
            NO_EDGE -> throw IllegalArgumentException("Cannot snap panel with position NO_EDGE")
        }
    }

    private fun switchToMarginPositioning() {
        val marginLeft = panelView.translationX.roundToInt()
        val marginTop = panelView.translationY.roundToInt()

        panelView.translationX = 0f
        panelView.translationY = 0f

        ConstraintSet().apply {
            clone(this)
            connect(panelResId, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, marginLeft)
            connect(panelResId, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, marginTop)
            applyTo(this@PanelLayout)
        }
    }

    private fun applyConstraintsWithAnimation(layoutResId: Int) = post {
        val constraintSet = ConstraintSet()
        constraintSet.load(context, layoutResId)

        val transition = AutoTransition().apply {
            interpolator = AccelerateDecelerateInterpolator()
            duration = snapAnimationDuration

            addListener(object : Transition.TransitionListener {
                override fun onTransitionStart(transition: Transition) {
                    panelLayoutCallbacks?.beforeSnap(panelState.position)
                    resizeHandle?.isVisible = false
                }

                override fun onTransitionEnd(transition: Transition) {
                    panelLayoutCallbacks?.afterSnap(panelState.position)
                }

                override fun onTransitionResume(transition: Transition) {} // No-op
                override fun onTransitionPause(transition: Transition) {} // No-op
                override fun onTransitionCancel(transition: Transition) {} // No-op
            })
        }

        TransitionManager.beginDelayedTransition(this, transition)

        constraintSet.applyTo(this)
        panelState.snap = SNAPPED
    }

    private fun PanelPosition.isSnapEnabled() = snapToEdges.hasFlag(this.snapFlag())

    private fun PanelPosition.snapFlag() = when (this) {
        LEFT_EDGE -> SNAP_TO_LEFT
        RIGHT_EDGE -> SNAP_TO_RIGHT
        TOP_EDGE -> SNAP_TO_TOP
        BOTTOM_EDGE -> SNAP_TO_BOTTOM
        NO_EDGE -> throw IllegalArgumentException("You cannot get a snapFlag for PanelState.Position.NO_EDGE")
    }

    private fun PanelPosition.overlay() = when (this) {
        LEFT_EDGE -> leftOverlay
        RIGHT_EDGE -> rightOverlay
        TOP_EDGE -> topOverlay
        BOTTOM_EDGE -> bottomOverlay
        NO_EDGE -> throw IllegalArgumentException("You cannot get an overlay for PanelState.Position.NO_EDGE")
    }

    private fun PanelPosition.overlayScale() = when (this) {
        LEFT_EDGE,
        RIGHT_EDGE -> preferredSnapWidth to height.toFloat() + 1
        TOP_EDGE,
        BOTTOM_EDGE -> width.toFloat() + 1 to preferredSnapHeight
        NO_EDGE -> throw IllegalArgumentException("You cannot get an overlayScale for PanelState.Position.NO_EDGE")
    }

    private fun PanelPosition.touchPoint() = when (this) {
        LEFT_EDGE -> 0f to panelView.centerY()
        RIGHT_EDGE -> width.toFloat() to panelView.centerY()
        TOP_EDGE -> panelView.centerX() to 0f
        BOTTOM_EDGE -> panelView.centerX() to height.toFloat()
        NO_EDGE -> throw IllegalArgumentException("You cannot get an touchPoint for PanelState.Position.NO_EDGE")
    }

    private fun View.centerX() = x + width / 2f

    private fun View.centerY() = y + height / 2f

    private fun PanelState.sanitizedSize(): Pair<Int, Int> {
        val (savedWidth, savedHeight) = size

        val w = when (savedWidth) {
            -1 -> panelStartWidth
            else -> savedWidth.coerceAtMost(width)
        }

        val h = when (savedHeight) {
            -1 -> panelStartHeight
            else -> savedHeight.coerceAtMost(height)
        }

        return w to h
    }

    private fun PanelState.HorizontalEdgeDistance.toX(panelWidth: Int) = when (this.edge) {
        LEFT -> distance
        RIGHT -> width - panelWidth - distance
    }

    private fun PanelState.VerticalEdgeDistance.toY(panelHeight: Int) = when (this.edge) {
        TOP -> distance
        BOTTOM -> height - panelHeight - distance
    }

    private fun View.calculateHorizontalNearestEdgeDistance(): PanelState.HorizontalEdgeDistance {
        val leftDistance = this.x.roundToInt()
        val rightDistance = this@PanelLayout.width - this.x.roundToInt() - this.width

        return if (leftDistance <= rightDistance) {
            PanelState.HorizontalEdgeDistance(LEFT, leftDistance)
        } else {
            PanelState.HorizontalEdgeDistance(RIGHT, rightDistance)
        }
    }

    private fun View.calculateVerticalNearestEdgeDistance(): PanelState.VerticalEdgeDistance {
        val topDistance = this.y.roundToInt()
        val bottomDistance = this@PanelLayout.height - this.y.roundToInt() - this.height

        return if (topDistance <= bottomDistance) {
            PanelState.VerticalEdgeDistance(TOP, topDistance)
        } else {
            PanelState.VerticalEdgeDistance(BOTTOM, bottomDistance)
        }
    }

    // Calculates move bounds given (width to height) pair in PanelLayout
    private fun Pair<Int, Int>.moveBounds(offset: Int = 0): Rect {
        val (childWidth, childHeight) = this

        val minX = 0 + offset
        val minY = 0 + offset
        val maxX = (width - childWidth - offset).coerceAtLeast(minX)
        val maxY = (height - childHeight - offset).coerceAtLeast(minY)

        return Rect(minX, minY, maxX, maxY)
    }

    private fun View.moveBounds(): Rect = (width to height).moveBounds()

    private fun MotionEvent.isSignificantlyDistantTo(other: MotionEvent): Boolean {
        val deltaX = other.rawX - this.rawX
        val deltaY = other.rawY - this.rawY

        return sqrt(deltaX * deltaX + deltaY * deltaY) > ViewConfiguration.get(context).scaledTouchSlop
    }

    private fun View.containsInHitRect(event: MotionEvent) = offsetHitRectToAscendant(this@PanelLayout)
        .contains(event.x.toInt(), event.y.toInt())

    private fun View.offsetHitRectToAscendant(ascendant: View): Rect {
        val hitRect = Rect()
        this.getHitRect(hitRect)

        var iterator = parent as View

        while (iterator != ascendant) {
            hitRect.offset(iterator.x.toInt(), iterator.y.toInt())
            iterator = iterator.parent as View
        }

        return hitRect
    }

    private inner class PanelMoveSnapListener : OnTouchListener {
        override fun onTouch(v: View, event: MotionEvent): Boolean {
            return when (event.action) {
                ACTION_DOWN -> true
                ACTION_MOVE -> handleActionMove(event)
                ACTION_UP -> handleActionUp()
                else -> false
            }
        }

        private fun handleActionMove(event: MotionEvent): Boolean {
            val (left, top, right, bottom) = panelView.moveBounds()

            val nextX = (event.rawX - relativeTouchPositionX).roundToInt().coerceIn(left, right)
            val nextY = (event.rawY - relativeTouchPositionY).roundToInt().coerceIn(top, bottom)

            val currentPosition = panelState.position
            val nextPosition = calculatePositionFor(nextX, nextY)
            panelState.position = nextPosition

            handleSnapOverlayAnimation(currentPosition, nextPosition)
            movePanelTo(nextX, nextY)

            return true
        }

        private fun handleActionUp(): Boolean {
            if (panelState.position != NO_EDGE && panelState.position.isSnapEnabled()) {
                hideSnapOverlay(panelState.position)
                snapPanelTo(panelState.position)
            }

            touchSubject = null
            return true
        }

        // Checking current and next positions shows or hides snap overlays with animation
        private fun handleSnapOverlayAnimation(
            currentPosition: PanelPosition,
            nextPosition: PanelPosition
        ) {
            for (position in values()) {
                if (position == NO_EDGE) continue
                if (position.isSnapEnabled().not()) continue

                if (currentPosition != position && nextPosition == position) {
                    showSnapOverlay(position)
                }

                if (currentPosition == position && nextPosition != position) {
                    hideSnapOverlay(position)
                }
            }
        }

        private fun movePanelTo(destinationX: Int, destinationY: Int) {
            panelView.animate()
                .translationX(destinationX.toFloat())
                .translationY(destinationY.toFloat())
                .setDuration(0)
                .withEndAction {
                    panelState.horizontalNearestEdgeDistance = panelView.calculateHorizontalNearestEdgeDistance()
                    panelState.verticalNearestEdgeDistance = panelView.calculateVerticalNearestEdgeDistance()
                }
                .start()
        }
    }

    private inner class PanelPopListener : OnTouchListener {
        override fun onTouch(v: View, event: MotionEvent): Boolean {
            return when (event.action) {
                ACTION_DOWN -> true
                ACTION_MOVE -> handleActionMove(event)
                ACTION_UP -> handleActionUp()
                else -> false
            }
        }

        private fun handleActionMove(event: MotionEvent): Boolean {
            relativeTouchPositionX = event.rawX - panelView.x
            relativeTouchPositionY = event.rawY - panelView.y

            val (popWidth, popHeight) = panelState.sanitizedSize()

            val nextRelativeTouchPositionX = relativeTouchPositionX / panelView.width * popWidth
            val nextRelativeTouchPositionY = relativeTouchPositionY / panelView.height * popHeight

            val (left, top, right, bottom) = (popWidth to popHeight).moveBounds(offset = PANEL_POP_OFFSET)

            val popToX = (event.rawX - nextRelativeTouchPositionX).roundToInt().coerceIn(left, right)
            val popToY = (event.rawY - nextRelativeTouchPositionY).roundToInt().coerceIn(top, bottom)

            popPanelTo(popToX, popToY)

            relativeTouchPositionX = event.rawX - popToX
            relativeTouchPositionY = event.rawY - popToY

            return true
        }

        private fun handleActionUp(): Boolean {
            touchSubject = null
            return true
        }
    }

    private inner class PanelResizeListener : OnTouchListener {
        private var previousX = NOT_SET
        private var previousY = NOT_SET

        override fun onTouch(v: View, event: MotionEvent): Boolean {
            return when (event.action) {
                ACTION_DOWN -> true
                ACTION_MOVE -> handleActionMove(event)
                ACTION_UP -> handleActionUp()
                else -> false
            }
        }

        private fun handleActionMove(event: MotionEvent): Boolean {
            if (previousX == NOT_SET || previousY == NOT_SET) {
                previousX = lastDownEvent!!.rawX
                previousY = lastDownEvent!!.rawY
            }

            val diffX = event.rawX - previousX
            val diffY = event.rawY - previousY

            val (updatedWidth, updatedHeight) = calculateNewSize(diffX, diffY)

            resizePanel(updatedWidth, updatedHeight)

            panelState.size = updatedWidth to updatedHeight

            previousX = event.rawX
            previousY = event.rawY

            return true
        }

        private fun handleActionUp(): Boolean {
            previousX = NOT_SET
            previousY = NOT_SET
            touchSubject = null
            return true
        }
    }

    interface Callbacks {
        fun beforeSnap(position: PanelPosition)
        fun afterSnap(position: PanelPosition)
        fun beforePop(popToX: Int, popToY: Int)
        fun afterPop(popToX: Int, popToY: Int)
        fun afterClose()
    }

    companion object {
        private const val NOT_SET = -1f
        private const val PANEL_POP_OFFSET = 4 // distance from edges when panelState is popped. in pixels
        private const val PARCELABLE_KEY_SUPER_STATE = "superState"
        private const val PARCELABLE_KEY_PANEL_STATE = "panelState"

        // Possible flags for snapToEdges
        private const val SNAP_TO_LEFT = 1
        private const val SNAP_TO_TOP = 2
        private const val SNAP_TO_RIGHT = 4
        private const val SNAP_TO_BOTTOM = 8

        private fun Int.hasFlag(flag: Int) = (this and flag) == flag
    }
}


================================================
FILE: panellayout/src/main/java/com/wayfair/panellayout/PanelLayoutCommands.kt
================================================
package com.wayfair.panellayout

internal interface PanelLayoutCommands {
    var panelLayoutCallbacks: PanelLayout.Callbacks?
    var panelVisible: Boolean

    fun snapPanelTo(panelPosition: PanelPosition)
    fun popPanelTo(x: Int, y: Int)
}


================================================
FILE: panellayout/src/main/java/com/wayfair/panellayout/PanelPosition.kt
================================================
package com.wayfair.panellayout

enum class PanelPosition {
    LEFT_EDGE, RIGHT_EDGE, TOP_EDGE, BOTTOM_EDGE, NO_EDGE
}


================================================
FILE: panellayout/src/main/java/com/wayfair/panellayout/PanelState.kt
================================================
package com.wayfair.panellayout

import android.os.Parcelable
import com.wayfair.panellayout.PanelState.HorizontalEdge.LEFT
import com.wayfair.panellayout.PanelState.VerticalEdge.TOP
import kotlinx.android.parcel.Parcelize

@Parcelize
data class PanelState(
    var isVisible: Boolean = true,
    var snap: Snap = Snap.FLOATING,
    var size: Pair<Int, Int> = -1 to -1,
    var position: PanelPosition = PanelPosition.NO_EDGE,
    var horizontalNearestEdgeDistance: HorizontalEdgeDistance = HorizontalEdgeDistance(edge = LEFT, distance = 0),
    var verticalNearestEdgeDistance: VerticalEdgeDistance = VerticalEdgeDistance(edge = TOP, distance = 0)
) : Parcelable {

    @Parcelize
    data class HorizontalEdgeDistance(val edge: HorizontalEdge, val distance: Int) : Parcelable

    @Parcelize
    data class VerticalEdgeDistance(val edge: VerticalEdge, val distance: Int) : Parcelable

    enum class HorizontalEdge {
        LEFT, RIGHT
    }

    enum class VerticalEdge {
        TOP, BOTTOM
    }

    enum class Snap {
        FLOATING, ANIMATING, SNAPPED
    }
}


================================================
FILE: panellayout/src/main/res/layout/panel_view_default_snap_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/panelLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="WrongConstraintLayoutUsage">

    <View
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/panel"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:background="#ABC" />

    <View
        android:id="@+id/panel"
        android:layout_width="match_parent"
        android:layout_height="@dimen/panel_default_snap_height"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

================================================
FILE: panellayout/src/main/res/layout/panel_view_default_snap_left.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/panelLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="WrongConstraintLayoutUsage">

    <View
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/panel"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:background="#ABC" />

    <View
        android:id="@+id/panel"
        android:layout_width="@dimen/panel_default_snap_width"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>


================================================
FILE: panellayout/src/main/res/layout/panel_view_default_snap_right.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/panelLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="WrongConstraintLayoutUsage">

    <View
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/panel"
        app:layout_constraintTop_toTopOf="parent"
        tools:background="#ABC" />

    <View
        android:id="@+id/panel"
        android:layout_width="@dimen/panel_default_snap_width"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

================================================
FILE: panellayout/src/main/res/layout/panel_view_default_snap_top.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/panelLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="WrongConstraintLayoutUsage">

    <View
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/panel"
        tools:background="#ABC" />

    <View
        android:id="@+id/panel"
        android:layout_width="match_parent"
        android:layout_height="@dimen/panel_default_snap_height"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

================================================
FILE: panellayout/src/main/res/values/panel_attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="PanelLayout">

        <attr name="panel_view" format="reference" />
        <attr name="panel_content" format="reference" />
        <attr name="panel_move_handle" format="reference" />
        <attr name="panel_resize_handle" format="reference" />

        <attr name="panel_resize_enabled" format="boolean" />

        <attr name="panel_min_width" format="dimension" />
        <attr name="panel_max_width" format="dimension" />
        <attr name="panel_min_height" format="dimension" />
        <attr name="panel_max_height" format="dimension" />
        <attr name="panel_start_width" format="dimension" />
        <attr name="panel_start_height" format="dimension" />
        <attr name="panel_snap_width" format="dimension" />
        <attr name="panel_snap_height" format="dimension" />

        <attr name="panel_snap_width_percent" format="float" />
        <attr name="panel_snap_height_percent" format="float" />

        <attr name="panel_snap_animation_duration" format="integer" />
        <attr name="panel_snap_overlay_animation_duration" format="integer" />

        <attr name="panel_snap_overlay_color" format="color" />

        <attr name="panel_snap_to_edges">
            <flag name="none" value="0" />
            <flag name="left" value="1" />
            <flag name="top" value="2" />
            <flag name="right" value="4" />
            <flag name="bottom" value="8" />
            <flag name="all" value="15" />
        </attr>

        <attr name="panel_snap_top_layout" format="reference" />
        <attr name="panel_snap_right_layout" format="reference" />
        <attr name="panel_snap_bottom_layout" format="reference" />
        <attr name="panel_snap_left_layout" format="reference" />

    </declare-styleable>
</resources>

================================================
FILE: panellayout/src/main/res/values/panel_colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="panel_default_snap_overlay_color">#802196F3</color>
</resources>

================================================
FILE: panellayout/src/main/res/values/panel_dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="panel_default_min_width">100dp</dimen>
    <dimen name="panel_default_max_width">600dp</dimen>
    <dimen name="panel_default_min_height">100dp</dimen>
    <dimen name="panel_default_max_height">600dp</dimen>
    <dimen name="panel_default_start_width">320dp</dimen>
    <dimen name="panel_default_start_height">480dp</dimen>
    <dimen name="panel_default_snap_width">300dp</dimen>
    <dimen name="panel_default_snap_height">300dp</dimen>
</resources>

================================================
FILE: panellayout/src/main/res/values/panel_integers.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="panel_default_snap_edges">15</integer> <!-- snap to all -->
    <integer name="panel_default_snap_animation_duration">300</integer>
    <integer name="panel_default_snap_overlay_animation_duration">300</integer>
</resources>

================================================
FILE: settings.gradle
================================================
include ':app', ':panellayout'
rootProject.name = "Panel Layout"
Download .txt
gitextract_i0r_bc1v/

├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .idea/
│   ├── .name
│   ├── codeStyles
│   ├── gradle.xml
│   ├── jarRepositories.xml
│   ├── misc.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MAINTAINERS.md
├── README.md
├── RELEASING.md
├── SECURITY.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── wayfair/
│       │               └── panellayout/
│       │                   └── ExampleInstrumentedTest.kt
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── wayfair/
│           │           └── panellayout/
│           │               ├── MainActivity.kt
│           │               └── MaterialCardViewExt.kt
│           └── res/
│               ├── drawable/
│               │   ├── ic_ballpoint_pen.xml
│               │   ├── ic_baseline_visibility_off.xml
│               │   ├── ic_baseline_visibility_on.xml
│               │   ├── ic_circle.xml
│               │   ├── ic_circle_outline.xml
│               │   ├── ic_color_fill.xml
│               │   ├── ic_eraser.xml
│               │   ├── ic_fountain_pen.xml
│               │   ├── ic_grease_pencil.xml
│               │   ├── ic_launcher_background.xml
│               │   ├── ic_pencil.xml
│               │   ├── ic_resize.xml
│               │   ├── ic_select.xml
│               │   ├── ic_show_hide_button.xml
│               │   ├── ic_square.xml
│               │   ├── ic_square_outline.xml
│               │   ├── ic_text.xml
│               │   ├── ic_triangle.xml
│               │   └── ic_triangle_outline.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── colors.xml
│               │   ├── shapes.xml
│               │   └── tools.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── strings.xml
│                   └── styles.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── panellayout/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── wayfair/
│           │           └── panellayout/
│           │               ├── PanelLayout.kt
│           │               ├── PanelLayoutCommands.kt
│           │               ├── PanelPosition.kt
│           │               └── PanelState.kt
│           └── res/
│               ├── layout/
│               │   ├── panel_view_default_snap_bottom.xml
│               │   ├── panel_view_default_snap_left.xml
│               │   ├── panel_view_default_snap_right.xml
│               │   └── panel_view_default_snap_top.xml
│               └── values/
│                   ├── panel_attrs.xml
│                   ├── panel_colors.xml
│                   ├── panel_dimens.xml
│                   └── panel_integers.xml
└── settings.gradle
Condensed preview — 76 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (127K chars).
[
  {
    "path": ".github/workflows/ci.yml",
    "chars": 306,
    "preview": "name: CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    paths-ignore:\n      - 'docs/**'\n      - '*.md'\n\njobs:"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 364,
    "preview": "name: Publish a release\n\non:\n  push:\n    tags:\n      - '*'\n\njobs:\n  plugin-deploy:\n    runs-on: ubuntu-latest\n\n    steps"
  },
  {
    "path": ".gitignore",
    "chars": 208,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor."
  },
  {
    "path": ".idea/.name",
    "chars": 12,
    "preview": "Panel Layout"
  },
  {
    "path": ".idea/codeStyles",
    "chars": 1905,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectCodeStyleConfiguration\">\n    <cod"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 853,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersio"
  },
  {
    "path": ".idea/jarRepositories.xml",
    "chars": 1052,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RemoteRepositoriesConfiguration\">\n    <r"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 5707,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CMakeSettings\">\n    <configurations>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 116,
    "preview": "### v1.0.0-alpha02\n- Fixes a bug that prevents resizing of the panel.\n\n### v1.0.0-alpha01\n- The very first release!\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 708,
    "preview": "## Contributing to Panel Layout\nFirst off, thank you for your interest in contributing to Panel Layout!\n\n### Issue first"
  },
  {
    "path": "LICENSE.md",
    "chars": 1300,
    "preview": "BSD 2-Clause License\n\nCopyright (c) 2020 Wayfair GmbH\n\nRedistribution and use in source and binary forms, with or withou"
  },
  {
    "path": "MAINTAINERS.md",
    "chars": 30,
    "preview": "mkojadinovic [at] wayfair.com\n"
  },
  {
    "path": "README.md",
    "chars": 5368,
    "preview": "*ARCHIVED* -- Wayfair's technology team is now focused on other endeavors. Please consider this project archived / avail"
  },
  {
    "path": "RELEASING.md",
    "chars": 399,
    "preview": "Releasing\n========\n\n 1. Change the version in `gradle.properties` to a new version.\n 1. Update the `CHANGELOG.md` for th"
  },
  {
    "path": "SECURITY.md",
    "chars": 85,
    "preview": "If you have discovered a security vulnerability, please email opensource@wayfair.com\n"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 1108,
    "preview": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-android-extensions'\n\nandroi"
  },
  {
    "path": "app/src/androidTest/java/com/wayfair/panellayout/ExampleInstrumentedTest.kt",
    "chars": 674,
    "preview": "package com.wayfair.panellayout\n\nimport androidx.test.platform.app.InstrumentationRegistry\nimport androidx.test.ext.juni"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 718,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/com/wayfair/panellayout/MainActivity.kt",
    "chars": 2433,
    "preview": "package com.wayfair.panellayout\n\nimport android.content.res.ColorStateList\nimport android.os.Bundle\nimport androidx.appc"
  },
  {
    "path": "app/src/main/java/com/wayfair/panellayout/MaterialCardViewExt.kt",
    "chars": 546,
    "preview": "package com.wayfair.panellayout\n\nimport android.animation.ValueAnimator\nimport com.google.android.material.card.Material"
  },
  {
    "path": "app/src/main/res/drawable/ic_ballpoint_pen.xml",
    "chars": 599,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_visibility_off.xml",
    "chars": 901,
    "preview": "<vector android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\"\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_visibility_on.xml",
    "chars": 542,
    "preview": "<vector android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\"\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_circle.xml",
    "chars": 342,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_circle_outline.xml",
    "chars": 410,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_color_fill.xml",
    "chars": 573,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_eraser.xml",
    "chars": 537,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_fountain_pen.xml",
    "chars": 543,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_grease_pencil.xml",
    "chars": 589,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/drawable/ic_pencil.xml",
    "chars": 413,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_resize.xml",
    "chars": 375,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_select.xml",
    "chars": 573,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_show_hide_button.xml",
    "chars": 288,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable/ic_square.xml",
    "chars": 278,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_square_outline.xml",
    "chars": 295,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_text.xml",
    "chars": 345,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_triangle.xml",
    "chars": 279,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_triangle_outline.xml",
    "chars": 298,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:height=\"24dp\"\n    android:width=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1703,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 6822,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/layout/colors.xml",
    "chars": 6777,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/layout/shapes.xml",
    "chars": 2414,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/layout/tools.xml",
    "chars": 2897,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 273,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 273,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 1325,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#9C27B0</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "chars": 280,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"zero\">0dp</dimen>\n    <dimen name=\"panel_elevation\">"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 199,
    "preview": "<resources>\n    <string name=\"app_name\">Panel Layout</string>\n    <string name=\"shapes\">Shapes</string>\n    <string name"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 391,
    "preview": "<resources>\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.DarkA"
  },
  {
    "path": "build.gradle",
    "chars": 509,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    ex"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Tue May 05 17:46:57 EET 2020\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 653,
    "preview": "org.gradle.jvmargs=-Xmx2048m\nandroid.useAndroidX=true\nandroid.enableJetifier=true\nkotlin.code.style=official\n\nGROUP=com."
  },
  {
    "path": "gradlew",
    "chars": 5296,
    "preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up"
  },
  {
    "path": "gradlew.bat",
    "chars": 2176,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "panellayout/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "panellayout/build.gradle",
    "chars": 2263,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-android-extensions'\napply plugi"
  },
  {
    "path": "panellayout/gradle.properties",
    "chars": 198,
    "preview": "POM_ARTIFACT_ID=panellayout\nPOM_NAME=Panel Layout\nPOM_DESCRIPTION=UI library for Android that allows you to display a fl"
  },
  {
    "path": "panellayout/src/main/AndroidManifest.xml",
    "chars": 86,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest package=\"com.wayfair.panellayout\" />\n"
  },
  {
    "path": "panellayout/src/main/java/com/wayfair/panellayout/PanelLayout.kt",
    "chars": 34194,
    "preview": "/*  These imports produce a detekt false-positive:\n    import androidx.core.graphics.component1\n    import androidx.core"
  },
  {
    "path": "panellayout/src/main/java/com/wayfair/panellayout/PanelLayoutCommands.kt",
    "chars": 245,
    "preview": "package com.wayfair.panellayout\n\ninternal interface PanelLayoutCommands {\n    var panelLayoutCallbacks: PanelLayout.Call"
  },
  {
    "path": "panellayout/src/main/java/com/wayfair/panellayout/PanelPosition.kt",
    "chars": 120,
    "preview": "package com.wayfair.panellayout\n\nenum class PanelPosition {\n    LEFT_EDGE, RIGHT_EDGE, TOP_EDGE, BOTTOM_EDGE, NO_EDGE\n}\n"
  },
  {
    "path": "panellayout/src/main/java/com/wayfair/panellayout/PanelState.kt",
    "chars": 1070,
    "preview": "package com.wayfair.panellayout\n\nimport android.os.Parcelable\nimport com.wayfair.panellayout.PanelState.HorizontalEdge.L"
  },
  {
    "path": "panellayout/src/main/res/layout/panel_view_default_snap_bottom.xml",
    "chars": 1150,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "panellayout/src/main/res/layout/panel_view_default_snap_left.xml",
    "chars": 1150,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "panellayout/src/main/res/layout/panel_view_default_snap_right.xml",
    "chars": 1149,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "panellayout/src/main/res/layout/panel_view_default_snap_top.xml",
    "chars": 1150,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "panellayout/src/main/res/values/panel_attrs.xml",
    "chars": 1847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <declare-styleable name=\"PanelLayout\">\n\n        <attr name=\"pane"
  },
  {
    "path": "panellayout/src/main/res/values/panel_colors.xml",
    "chars": 132,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"panel_default_snap_overlay_color\">#802196F3</color>\n"
  },
  {
    "path": "panellayout/src/main/res/values/panel_dimens.xml",
    "chars": 521,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"panel_default_min_width\">100dp</dimen>\n    <dimen na"
  },
  {
    "path": "panellayout/src/main/res/values/panel_integers.xml",
    "chars": 294,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"panel_default_snap_edges\">15</integer> <!-- snap t"
  },
  {
    "path": "settings.gradle",
    "chars": 65,
    "preview": "include ':app', ':panellayout'\nrootProject.name = \"Panel Layout\"\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the wayfair-incubator/panel-layout GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 76 files (113.6 KB), approximately 31.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!