[
  {
    "path": ".gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\nbuild/\n\n# Android related\n**/android/**/gradle-wrapper.jar\n**/android/.gradle\n**/android/captures/\n**/android/gradlew\n**/android/gradlew.bat\n**/android/local.properties\n**/android/**/GeneratedPluginRegistrant.java\n\n# iOS/XCode related\n**/ios/**/*.mode1v3\n**/ios/**/*.mode2v3\n**/ios/**/*.moved-aside\n**/ios/**/*.pbxuser\n**/ios/**/*.perspectivev3\n**/ios/**/*sync/\n**/ios/**/.sconsign.dblite\n**/ios/**/.tags*\n**/ios/**/.vagrant/\n**/ios/**/DerivedData/\n**/ios/**/Icon?\n**/ios/**/Pods/\n**/ios/**/.symlinks/\n**/ios/**/profile\n**/ios/**/xcuserdata\n**/ios/.generated/\n**/ios/Flutter/App.framework\n**/ios/Flutter/Flutter.framework\n**/ios/Flutter/Flutter.podspec\n**/ios/Flutter/Generated.xcconfig\n**/ios/Flutter/app.flx\n**/ios/Flutter/app.zip\n**/ios/Flutter/flutter_assets/\n**/ios/Flutter/flutter_export_environment.sh\n**/ios/ServiceDefinitions.json\n**/ios/Runner/GeneratedPluginRegistrant.*\n\n# Exceptions to above rules.\n!**/ios/**/default.mode1v3\n!**/ios/**/default.mode2v3\n!**/ios/**/default.pbxuser\n!**/ios/**/default.perspectivev3\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n"
  },
  {
    "path": ".metadata",
    "content": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrades etc.\n#\n# This file should be version controlled and should not be manually edited.\n\nversion:\n  revision: b041144f833e05cf463b8887fa12efdec9493488\n  channel: stable\n\nproject_type: package\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "\n# Changelog\n\nAll notable changes to this project will be documented in this file.\n\n## [4.1.3] - 2022-11-27\n### Changed\n- make initialValue non-nullable\n- add didUpdateWidget that sets the selected items if initialValue changed\n- add isDismissable parameter\n- fixed 'items still selected after cancel'\n\n## [4.1.2] - 2022-03-14\n### Changed\n- Merged [PR #87](https://github.com/CHB61/multi_select_flutter/pull/87). Thanks @benyaminbeyzaie\n\n## [4.1.1] - 2022-03-14\n### Changed\n- Created a bug in 4.0.0 by removing the 'collection' dependency. It's only used to call firstWhereOrNull in _buildInheritedChipDisplay in both MultiSelectDialogField and MultiSelectBottomSheetField. This function is meant to automatically build the chips, but it may be changed or removed in the future as I don't think it is really necessary, and has caused some issues. For now, the package still depends on collection.\n\n## [4.1.0] - 2022-03-14\n### Changed\n- BREAKING: re-named the 'width' and 'height' fields to dialogWidth and dialogHeight.\n- Allow to adjust the width of the dialog.\n\n### Added\n- param 'separateSelectedItems' which can be used with LIST type only.\n\n## [4.0.0] - 2021-03-20\n### Changed\n- Added null safety. Thanks to @ihancock for taking the initiative to apply this.\n\n## [3.1.8] - 2021-02-15\n### Fixed\n- [Slow with big list](https://github.com/CHB61/multi_select_flutter/issues/18). Using a ListView.builder solves this but haven't found a way to use ListView.builder when the listType is set to MultiSelectListType.CHIP. Currently when this is set, the widget renders a Wrap inside of a SingleChildScrollView. For now, if you have a big list, do not use `MultiSelectListType.CHIP`.\n## [3.1.7] - 2021-02-14\n### Changed\n- title param type from Text to Widget\n### Fixed\n- Missing generic type `<V>` on MultiSelectChipDisplay declarations\n\t- MultiSelectDialogField.dart line 33 in MultiSelectDialogField\n\t- MultiSelectDialogField.dart line 181 in _MultiSelectDialogFieldView\n\t- MultiSelectBottomSheetField.dart line 69 in MultiSelectBottomSheetField\n\t- MultiSelectBottomSheetField.dart line 209 _MultiSelectBottomSheetFieldView\n\nThis would cause a type error if you were to specify the type of a MultiSelectChipDisplay that's part of a MultiSelectDialogField or MultiSelectBottomSheetField.\n\n```dart\nMultiSelectBottomSheetField(\n    onConfirm: (values) {\n        _selectedAnimals = values;\n    },\n    items: _items,\n    chipDisplay: MultiSelectChipDisplay<Animal>( // supplying the runtime type here will cause error\n        onTap: (item) {\n            _selectedAnimals.remove(item);\n            return _selectedAnimals;\n        },\n    ),\n)\n```\nThe type being supplied plus returning a List<Animal> would mean that the onTap function is now `List<Animal> Function(Animal)`\nHowever, since the declaration of the chipDisplay was missing the type (ex. MultiSelectChipDisplay chipDisplay;), it is expecting onTap to be \n`dynamic Function(dynamic)`.\n## [3.1.6] - 2020-12-05\n### Changed\n- Autofocus search textfield when search icon is tapped.\n\n## [3.1.5] - 2020-12-01\n### Fixed\n- Readme tables\n## [3.1.4] - 2020-11-30\n### Added\n- A constructor MultiSelectChipDisplay.none() which disables the default chipDisplay that is part of MultiSelectDialogField and \n  MultiSelectBottomSheetField.\n### Fixed\n- When using a MultiSelectDialogField with pre-selected values, can't remove from the chipDisplay until after first confirm.\n\t- The onConfirm function provides a reference to the list of selected values that MultiSelectDialogField uses.\n\t- If you have pre-selected values set, you can now simply return the list of updated values in the onTap of the \n\t  MultiSelectChipDisplay.\n## [3.1.3] - 2020-10-09\n### Added\n- param `chipWidth` for MultiSelectChipDisplay and MultiSelectChipField. When this is set, overflowing text will show ellipses.\n  \n\n## [3.1.2] - 2020-10-09\n### Added\n- param `scroll`, `scrollBar`, `height` for MultiSelectChipDisplay.\n\n## [3.1.1] - 2020-10-08\n### Added\n- param `showHeader` for MultiSelectChipField allowing it to be completely removed if so desired.\n\n## [3.1.0] - 2020-10-04\n### Fixed\n- `type Color is not a subtype of type bool` when selecting item in MultiSelectBottomSheet\n\t- These errors appear in cases that use conditional expressions like this: `widget.selectedColor ?? widget.var != null ? widget.var.func() : widget.otherVar`.\n- Show selected chips in MultiSelectChipDisplay when `initialValue` is set\n\t- Previously if you set the initialValue on a MultiSelectBottomSheetField, it would show the selected items in the bottomsheet\n\t  but not in the chipDisplay.\n\n### Added\n- param `checkColor` for dialog and bottomsheet widgets.\n\n### Changed\n- BREAKING: Replace `chipColor` with `unselectedColor` for dialog and bottomsheet widgets. Apply the color to unselected checkbox border or the \n  unselected chip body depending which `listType` is used.\n- BREAKING: Replace deprecated `autovalidate` with `autovalidateMode` on FormField widgets\n\n## [3.0.1] - 2020-09-28\n### Fixed\n- `type List<dynamic> is not a subtype of type bool` when using chipDisplay param on MultiSelectBottomSheet.\n\n## [3.0.0] - 2020-09-27\n### Added\n- MultiSelectChipField\n\t- Similar to MultiSelectChipDisplay except that it is the primary\n\t  interface to select items\n\t- supports scroll or wrap, autoscroll, formfield features, searchable, custom items\n\n### Changed\n- MultiSelectDialogField and MultiSelectBottomSheetField now come with a default `chipDisplay`.\n\t- User no longer needs `chipDisplay` param to have a MultiSelectChipDisplay, a MultiSelectDialogField with only `items` specified is enough.\n\t- User can override or remove it. To remove it, override with MultiSelectChipDisplay(items: [])\n\t- User no longer needs to specify `items` on MultiSelectChipDisplay when using it as a chipDisplay param\n- Combine Field/FormField widgets\n\t- Instead of having 2 widgets e.g. MultiSelectDialogField and MultiSelectDialogFormField,\n\t  move the features of MultiSelectDialogFormField into MultiSelectDialogField.\n- Made MultiSelectChipDisplay stateless\n- Renamed searchPlaceholder to searchHint\n- Removed opacity param from MultiSelectChipDisplay.\n\n## [2.3.0] - 2020-09-14\n### Fixed\n- An error was being produced when using the `icon` param in MultiSelectChipDisplay with no `colorator` applied.\n- When no `title` is provided in MultiSelectDialogField, default title of Text(\"Select\") should be provided, not a String of \"Select\"\n\n### Changed\n- BREAKING: Removed `chipOpacity` from MultiSelectDialog and MultiSelectBottomSheet widgets.\n\t- can simply set the opacity along with the color.\n\n### Added\n- Param `selectedItemsTextStyle` that applies to dialog / bottomsheet, list and chip.\n\n\n## [2.2.0] - 2020-08-31\n### Added\nA number of parameters that allow more customizations.\n- `backgroundColor`\n- `chipColor`\n- `chipOpacity`\n- `searchIcon`, `closeSearchIcon`\n- `itemsTextStyle`, `searchTextStyle`, `searchHintStyle`\n- `icon` and `shape` for MultiSelectChipDisplay\n\n## [2.1.1] - 2020-08-27\n### Changed\n- When colorator is applied to Field or FormField, apply the same colorator to the chipDisplay if there is one.\n\tPreviously, when using a MultiSelectDialogField with a chipDisplay and you wanted the same effect both within\n\tthe dialog and on the chipDisplay, you would have to define the colorator for both widgets. This is repetitive\n\tand not ideal. Now, the MultiSelectChipDisplay inherits the colorator from the parent field, and can still \n\toverride that with the use of its own colorator.\n\n## [2.1.0] - 2020-08-24\n### Added\n- `colorator` param for all widgets. Set the color of individual items based on their value.\n\t- works like FormField's validator\n\t- takes a function in which you compare the value\n\t- return a color based on the value\n\t- return null if no conditions satisfied\n\t- applies to selected chips and checkboxes\n- `opacity` param for MultiSelectChipDisplay\n\n### Changed\n- MultiSelectChipDisplay's `chipColor` param now automatically sets the opacity to 0.33 and sets the text to the same color but with full opacity.\n\t- previously you would have to set the chipColor to `Colors.blue.withOpacity(0.33)`\n\t  and textStyle to `TextStyle(Colors.blue)` to achieve this simple look.\n\t- you can still override this if you want different colored text by using the `textStyle` param\n\t- and you can override the default 0.33 opacity of the chip body with the new `opacity` param\n- set the color of the FormField widgets bottom border to `selectedColor` if there is one\n- set the color of confirm/cancel buttons to `selectedColor` if there is one\n\n\n## [2.0.3] - 2020-08-22\n### Added\n- parameter `searchPlaceholder` to replace the default \"Search\" text.\n\n### Fixed\n- `selectedColor` wasn't being passed to MultiSelectDialog when using MultiSelectDialogField or MultiSelectDialogFormField\n\n## [2.0.2] - 2020-08-17\n### Added\n- dartdoc comments\n\n## [2.0.1] - 2020-08-17\n### Added\n- `selectedColor` param which controls the color of the selected checkbox / chips within a dialog / bottomsheet\n- `height` param to MultiSelectDialog widgets.\n\n### Changed\n- Set the default color of the confirmText and cancelText to primary for BottomSheet widgets.\n\n### Fixed\n- onSelectionChanged wasn't being called for all widgets.\n\n## [2.0.0] - 2020-08-16\n### Added\n- `MultiSelectBottomSheet`, `MultiSelectBottomSheetField`, `MultiSelectBottomSheetFormField`\n- `barrierColor` param to MultiSelectDialog\n\n### Changed\n- The addition of the MultiSelectBottomSheet widgets prompted a bit of a re-write in order to de-couple widgets. Didn't want the generic MultiSelectField to be responsible for both types (dialog, bottomsheet). The new structure makes more sense and is easier to work with.\n- MultiSelectField replaced with MultiSelectDialogField / MultiSelectBottomSheetField.\n- MultiSelectListDialog and MultiSelectChipDialog have been replaced with MultiSelectDialog.\n- dialogType replaced with listType, now accepts MultiSelectListType instead of MultiSelectDialogType.\n- Improved the look of validator text, matches the look of TextFormField validator style much more closely.\n- buttonText, confirmText, cancelText all now accept a Text widget instead of a string, allowing the removal of the textStyle param.\n\n## [1.0.6] - 2020-08-14\n\n### Fixed\n\n- Implement scrolling in MultiSelectChipDialog.\n\t- When the source list was large enough, the chip dialog would just overflow but it is now scrollable.\n\n### Changed\n\n-  `title` is no longer required for List / Chip dialogs, default to \"Select\".\n-  `initialSelectedItems` is now required for List / Chip dialogs.\n-  `items` is now required for MultiSelectChipDisplay.\n- Removed iconSize - can set icon size as param of Icon.\n- Removed `state` as a parameter of MultiSelectField and created a constructor `MultiSelectField.withState()` that gets called by MultiSelectFormField.\n\t-  `state` never needs to be set by the user, and would do nothing if set explicitly, so it shouldn't be a named param on the default constructor.\n- Updated docs\n\n## [1.0.5] - 2020-07-10\n\n### Fixed\n\n- A bug was introduced in version 1.0.4 that caused the MultiSelectFormField to not highlight any of the selected values in the dialog.\n\n### Added\n\n- Boolean parameter 'searchable'. Useful for larger lists, the searchable parameter enables a search icon in the dialog which shows a search bar that lets you query the list.\n- String parameters for 'confirmText' and 'cancelText'. This is important for users who want text other than 'OK' and 'CANCEL', especially for other languages and alphabets.\n\n## [1.0.4] - 2020-07-06\n\n### Changed\n\n- Allow user to set initial selected values for MultiSelectField and MultiSelectFormField by adding param 'initialValue' to MultiSelectField, and enabled the same functionality for MultiSelectFormField by passing its existing 'initialValue' param to the MultiSelectField's new 'initialValue' param.\n\t- MultiSelectFormField creates a MultiSelectField which never had an 'initialValue' param that could be set by the user. Even if 'initialValue' was set on the MultiSelectFormField, it never got passed to the MultiSelectField that it creates. Now it does.\n\t- Previously when using a MultiSelectField or FormField, the values in the MultiSelectListDialog / MultiSelectChipDialog were only being stored internally when a user confirms the values. Now the initial values can be set before any user interaction has occurred.\n\t- Another use case is when a MultiSelectField is being re-inserted into the widget tree (such as one inside of a PersistentBottomSheet), and if the developer wants the previously selected values to remain after the bottomsheet re-opens, they can use this parameter to achieve that.\n- Updated example app\n\n## [1.0.3] - 2020-06-21\n\n### Changed\n\n- Updated pubspec.yaml project description and added homepage link\n\n## [1.0.2] - 2020-06-20\n\n### Added\n\n- Example project\n\n- analysis_options.yaml\n\n## [1.0.1] - 2020-06-20\n\n### Changed\n\n- Added readme\n\n## [1.0.0] - 2020-06-20\n\n### Added\n\n- Creation of MultiSelect package\n\n- Widgets include MultiSelectListDialog, MultiSelectChipDialog, MultiSelectChipDisplay, MultiSelectField, MultiSelectFormField."
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2020, Chris Botha\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the \nfollowing conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following \ndisclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following \ndisclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, \nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "\n# Multi Select Flutter\n\n[![Pub Version](https://img.shields.io/pub/v/multi_select_flutter.svg)](https://pub.dev/packages/multi_select_flutter)\n\nMulti Select Flutter is a package for creating multi-select widgets in a variety of ways.\n\n| <img src=\"https://i.imgur.com/12ba2NO.gif\" width=\"250\"/><br /><sub><b>Dialog</b></sub> | <img src=\"https://i.imgur.com/NqldWcV.gif\" width=\"250\"/><br /><sub><b>BottomSheet</b></sub> | <img src=\"https://i.imgur.com/m7FzBIW.gif\" width=\"250\"/><br /><sub><b>ChoiceChip</b></sub> |\n| :---: | :---: | :---: |\n\n## Features\n- Supports FormField features like validator.\n- Neutral default design.\n- Dialog, BottomSheet, or ChoiceChip style widgets.\n- Make your multi select `searchable` for larger lists.\n\n## Usage\n\n### MultiSelectDialogField / MultiSelectBottomSheetField\n<img src=\"https://i.imgur.com/JoTYWce.png\" /><img src=\"https://i.imgur.com/Co8fhrD.png\" />\n\nThese widgets provide an InkWell button which open the dialog or bottom sheet and are equipped with FormField features. You can customize it using the provided parameters.\n\nTo store the selected values, you can use the `onConfirm` parameter. You could also use `onSelectionChanged` for this.\n\nBy default these widgets render a MultiSelectChipDisplay below the field. This can be overridden with the `chipDisplay` parameter or removed completely by using `chipDisplay: MultiSelectChipDisplay.none()`.\n\n```dart\nMultiSelectDialogField(\n  items: _animals.map((e) => MultiSelectItem(e, e.name)).toList(),\n  listType: MultiSelectListType.CHIP,\n  onConfirm: (values) {\n    _selectedAnimals = values;\n  },\n),\n```\n\n### MultiSelectDialog / MultiSelectBottomSheet\n<img src=\"https://i.imgur.com/XeuzNtQ.png\" height=\"250\" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=\"https://i.imgur.com/AwVOr54.png\" height=\"200\" />\n\nIf you prefer to create your own button for opening the dialog or bottom sheet, you may do so and then make a call to a function like this:\n\n`MultiSelectDialog` can be used in the builder of `showDialog()`.\n```dart\nvoid _showMultiSelect(BuildContext context) async {\n  await showDialog(\n    context: context,\n    builder: (ctx) {\n      return  MultiSelectDialog(\n        items: _items,\n        initialValue: _selectedAnimals,\n        onConfirm: (values) {...},\n      );\n    },\n  );\n}\n```\n\n`MultiSelectBottomSheet` can be used in the builder of `showModalBottomSheet()`.\n```dart\nvoid _showMultiSelect(BuildContext context) async {\n  await showModalBottomSheet(\n    isScrollControlled: true, // required for min/max child size\n    context: context,\n    builder: (ctx) {\n      return  MultiSelectBottomSheet(\n        items: _items,\n        initialValue: _selectedAnimals,\n        onConfirm: (values) {...},\n        maxChildSize: 0.8,\n      );\n    },\n  );\n}\n```\n\n### MultiSelectChipDisplay\n<img src=\"https://i.imgur.com/hMbuSxk.png\" width=\"300\" />\n\nTo display the selected items, this widget can be used alongside your own button or it can be specified as a `chipDisplay` parameter of widgets like `MultiSelectDialogField`.\n\nYou can also remove items from the source list in the onTap function.\n\n```dart\nMultiSelectChipDisplay(\n  items: _selectedAnimals.map((e) => MultiSelectItem(e, e)).toList(),\n  onTap: (value) {\n    setState(() {\n      _selectedAnimals.remove(value);\n    });\n  },\n),\n```\nA MultiSelectChipDisplay that is part of a MultiSelectDialogField still renders outside the BoxDecoration of the MultiSelectDialogField as seen here:\n\n<img  src=\"https://imgur.com/RuluMpS.png\"  alt=\"chipDisplay\"/>\n\nIf you want to encapsulate the MultiSelectChipDisplay, wrap the MultiSelectDialogField in a Container and apply the decoration to that instead:\n\n```dart\nContainer(\n  decoration: BoxDecoration(...),\n  child: MultiSelectDialogField(\n    items: _items,\n    chipDisplay: MultiSelectChipDisplay(...),\n  ),\n),\n```\n<img  src=\"https://imgur.com/EcCyly4.png\"  alt=\"chipDisplay\"/>\n\n### MultiSelectChipField\n<img src=\"https://i.imgur.com/KDmtpmV.png\" alt=\"chipField\"/> \n\nThis widget is similar to MultiSelectChipDisplay, except these chips are the primary interface for selecting items.\n```dart\nMultiSelectChipField<Animal>(\n  items: _items,\n  icon: Icon(Icons.check),\n  onTap: (values) {\n    _selectedAnimals = values;\n  },\n),\n```\n#### Using `itemBuilder` to create custom items:\n```dart\nMultiSelectChipField<Animal>(\n  items: _items,\n  key: _multiSelectKey,\n  validator: (values) {...}\n  itemBuilder: (item, state) {\n    // return your custom widget here\n    return InkWell(\n      onTap: () {\n        _selectedAnimals.contains(item.value)\n\t\t\t      ? _selectedAnimals.remove(item.value)\n\t\t\t      : _selectedAnimals.add(item.value);\n\t      state.didChange(_selectedAnimals);\n\t      _multiSelectKey.currentState.validate();\n\t    },\n\t    child: Text(item.value.name),\n    );\n  },\n),\n```\nThe `itemBuilder` param takes a function that will create a widget for each of the provided `items`. \n\nIn order to use validator and other FormField features with custom widgets, you must call `state.didChange(_updatedList)` any time the list of selected items is updated.\n\n#### Using `scrollControl` to auto scroll:\n```dart\nMultiSelectChipField(\n  items: _items,\n  scrollControl: (controller) {\n    _startAnimation(controller);\n  },\n)\n\n// waits 5 seconds, scrolls to end slow, then back fast\nvoid _startAnimation(ScrollController controller) {\n  // when using more than one animation, use async/await\n  Future.delayed(const Duration(milliseconds: 5000), () async {\n    await controller.animateTo(\n      controller.position.maxScrollExtent,\n      duration: Duration(milliseconds: 8000), \n      curve: Curves.linear);\n      \n    await controller.animateTo(\n      controller.position.minScrollExtent,\n      duration: Duration(milliseconds: 1250),\n      curve: Curves.fastLinearToSlowEaseIn);\n  });\n}\n```\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change."
  },
  {
    "path": "analysis_options.yaml",
    "content": "analyzer:\n  exclude: [build/**]\n  strong-mode:\n    implicit-casts: true\n\nlinter:\n  rules:\n    - camel_case_types"
  },
  {
    "path": "example/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Symbolication related\napp.*.symbols\n\n# Obfuscation related\napp.*.map.json\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n"
  },
  {
    "path": "example/.metadata",
    "content": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrades etc.\n#\n# This file should be version controlled and should not be manually edited.\n\nversion:\n  revision: b041144f833e05cf463b8887fa12efdec9493488\n  channel: stable\n\nproject_type: app\n"
  },
  {
    "path": "example/README.md",
    "content": "# example\n\nExample for multi_select_flutter package.\n\nCheck out some different ways to implement multi_select_flutter.\n"
  },
  {
    "path": "example/android/.gitignore",
    "content": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n"
  },
  {
    "path": "example/android/app/build.gradle",
    "content": "def localProperties = new Properties()\ndef localPropertiesFile = rootProject.file('local.properties')\nif (localPropertiesFile.exists()) {\n    localPropertiesFile.withReader('UTF-8') { reader ->\n        localProperties.load(reader)\n    }\n}\n\ndef flutterRoot = localProperties.getProperty('flutter.sdk')\nif (flutterRoot == null) {\n    throw new GradleException(\"Flutter SDK not found. Define location with flutter.sdk in the local.properties file.\")\n}\n\ndef flutterVersionCode = localProperties.getProperty('flutter.versionCode')\nif (flutterVersionCode == null) {\n    flutterVersionCode = '1'\n}\n\ndef flutterVersionName = localProperties.getProperty('flutter.versionName')\nif (flutterVersionName == null) {\n    flutterVersionName = '1.0'\n}\n\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply from: \"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle\"\n\nandroid {\n    compileSdkVersion 28\n\n    sourceSets {\n        main.java.srcDirs += 'src/main/kotlin'\n    }\n\n    lintOptions {\n        disable 'InvalidPackage'\n    }\n\n    defaultConfig {\n        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).\n        applicationId \"com.example.example\"\n        minSdkVersion 16\n        targetSdkVersion 28\n        versionCode flutterVersionCode.toInteger()\n        versionName flutterVersionName\n    }\n\n    buildTypes {\n        release {\n            // TODO: Add your own signing config for the release build.\n            // Signing with the debug keys for now, so `flutter run --release` works.\n            signingConfig signingConfigs.debug\n        }\n    }\n}\n\nflutter {\n    source '../..'\n}\n\ndependencies {\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n}\n"
  },
  {
    "path": "example/android/app/src/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.example.example\">\n    <!-- Flutter needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.example.example\">\n    <!-- io.flutter.app.FlutterApplication is an android.app.Application that\n         calls FlutterMain.startInitialization(this); in its onCreate method.\n         In most cases you can leave this as-is, but you if you want to provide\n         additional functionality it is fine to subclass or reimplement\n         FlutterApplication and put your custom class here. -->\n    <application\n        android:name=\"${applicationName}\"\n        android:label=\"example\"\n        android:icon=\"@mipmap/ic_launcher\">\n        <activity\n            android:name=\".MainActivity\"\n            android:launchMode=\"singleTop\"\n            android:theme=\"@style/LaunchTheme\"\n            android:configChanges=\"orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode\"\n            android:hardwareAccelerated=\"true\"\n            android:windowSoftInputMode=\"adjustResize\">\n            <!-- Specifies an Android theme to apply to this Activity as soon as\n                 the Android process has started. This theme is visible to the user\n                 while the Flutter UI initializes. After that, this theme continues\n                 to determine the Window background behind the Flutter UI. -->\n            <meta-data\n              android:name=\"io.flutter.embedding.android.NormalTheme\"\n              android:resource=\"@style/NormalTheme\"\n              />\n            <!-- Displays an Android View that continues showing the launch screen\n                 Drawable until Flutter paints its first frame, then this splash\n                 screen fades out. A splash screen is useful to avoid any visual\n                 gap between the end of Android's launch screen and the painting of\n                 Flutter's first frame. -->\n            <meta-data\n              android:name=\"io.flutter.embedding.android.SplashScreenDrawable\"\n              android:resource=\"@drawable/launch_background\"\n              />\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\"/>\n                <category android:name=\"android.intent.category.LAUNCHER\"/>\n            </intent-filter>\n        </activity>\n        <!-- Don't delete the meta-data below.\n             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->\n        <meta-data\n            android:name=\"flutterEmbedding\"\n            android:value=\"2\" />\n    </application>\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/kotlin/com/example/example/MainActivity.kt",
    "content": "package com.example.example\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivity() {\n}\n"
  },
  {
    "path": "example/android/app/src/main/res/drawable/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@android:color/white\" />\n\n    <!-- You can insert your own image assets here -->\n    <!-- <item>\n        <bitmap\n            android:gravity=\"center\"\n            android:src=\"@mipmap/launch_image\" />\n    </item> -->\n</layer-list>\n"
  },
  {
    "path": "example/android/app/src/main/res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- Theme applied to the Android Window while the process is starting -->\n    <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <!-- Show a splash screen on the activity. Automatically removed when\n             Flutter draws its first frame -->\n        <item name=\"android:windowBackground\">@drawable/launch_background</item>\n    </style>\n    <!-- Theme applied to the Android Window as soon as the process has started.\n         This theme determines the color of the Android Window while your\n         Flutter UI initializes, as well as behind your Flutter UI while its\n         running.\n         \n         This Theme is only used starting with V2 of Flutter's Android embedding. -->\n    <style name=\"NormalTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <item name=\"android:windowBackground\">@android:color/white</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "example/android/app/src/profile/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.example.example\">\n    <!-- Flutter needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "example/android/build.gradle",
    "content": "buildscript {\n    ext.kotlin_version = '1.3.50'\n    repositories {\n        google()\n        jcenter()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\nrootProject.buildDir = '../build'\nsubprojects {\n    project.buildDir = \"${rootProject.buildDir}/${project.name}\"\n}\nsubprojects {\n    project.evaluationDependsOn(':app')\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "example/android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Fri Jun 23 08:50:38 CEST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n"
  },
  {
    "path": "example/android/gradle.properties",
    "content": "org.gradle.jvmargs=-Xmx1536M\nandroid.enableR8=true\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n"
  },
  {
    "path": "example/android/settings.gradle",
    "content": "// Copyright 2014 The Flutter Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\ninclude ':app'\n\ndef localPropertiesFile = new File(rootProject.projectDir, \"local.properties\")\ndef properties = new Properties()\n\nassert localPropertiesFile.exists()\nlocalPropertiesFile.withReader(\"UTF-8\") { reader -> properties.load(reader) }\n\ndef flutterSdkPath = properties.getProperty(\"flutter.sdk\")\nassert flutterSdkPath != null, \"flutter.sdk not set in local.properties\"\napply from: \"$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle\"\n"
  },
  {
    "path": "example/ios/.gitignore",
    "content": "*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/DerivedData/\nIcon?\n**/Pods/\n**/.symlinks/\nprofile\nxcuserdata\n**/.generated/\nFlutter/App.framework\nFlutter/Flutter.framework\nFlutter/Flutter.podspec\nFlutter/Generated.xcconfig\nFlutter/app.flx\nFlutter/app.zip\nFlutter/flutter_assets/\nFlutter/flutter_export_environment.sh\nServiceDefinitions.json\nRunner/GeneratedPluginRegistrant.*\n\n# Exceptions to above rules.\n!default.mode1v3\n!default.mode2v3\n!default.pbxuser\n!default.perspectivev3\n"
  },
  {
    "path": "example/ios/Flutter/AppFrameworkInfo.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>$(DEVELOPMENT_LANGUAGE)</string>\n  <key>CFBundleExecutable</key>\n  <string>App</string>\n  <key>CFBundleIdentifier</key>\n  <string>io.flutter.flutter.app</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>App</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>1.0</string>\n  <key>MinimumOSVersion</key>\n  <string>8.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Flutter/Debug.xcconfig",
    "content": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Flutter/Release.xcconfig",
    "content": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Runner/AppDelegate.swift",
    "content": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n  override func application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n  ) -> Bool {\n    GeneratedPluginRegistrant.register(with: self)\n    return super.application(application, didFinishLaunchingWithOptions: launchOptions)\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"83.5x83.5\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-83.5x83.5@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"1024x1024\",\n      \"idiom\" : \"ios-marketing\",\n      \"filename\" : \"Icon-App-1024x1024@1x.png\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage@3x.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
    "content": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in this directory.\n\nYou can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images."
  },
  {
    "path": "example/ios/Runner/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"12121\" systemVersion=\"16G29\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12089\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Ydg-fD-yQy\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xbc-2k-c8Z\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" image=\"LaunchImage\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YRO-k0-Ey4\">\n                            </imageView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerX\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerX\" id=\"1a2-6s-vTC\"/>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerY\" id=\"4X2-HB-R7a\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"LaunchImage\" width=\"168\" height=\"185\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "example/ios/Runner/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"10117\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"10085\"/>\n    </dependencies>\n    <scenes>\n        <!--Flutter View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"FlutterViewController\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"y3c-jy-aDJ\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"wfy-db-euE\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "example/ios/Runner/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>example</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>$(FLUTTER_BUILD_NAME)</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(FLUTTER_BUILD_NUMBER)</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner/Runner-Bridging-Header.h",
    "content": "#import \"GeneratedPluginRegistrant.h\"\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };\n\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };\n\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };\n\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };\n\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };\n\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t9705A1C41CF9048500538489 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = \"<group>\"; };\n\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = \"<group>\"; };\n\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = \"<group>\"; };\n\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Runner-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = \"<group>\"; };\n\t\t97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t97C146EB1CF9000F007C117D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t9740EEB11CF90186004384FC /* Flutter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,\n\t\t\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */,\n\t\t\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */,\n\t\t\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */,\n\t\t\t);\n\t\t\tname = Flutter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146E51CF9000F007C117D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9740EEB11CF90186004384FC /* Flutter */,\n\t\t\t\t97C146F01CF9000F007C117D /* Runner */,\n\t\t\t\t97C146EF1CF9000F007C117D /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146EF1CF9000F007C117D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146EE1CF9000F007C117D /* Runner.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146F01CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FA1CF9000F007C117D /* Main.storyboard */,\n\t\t\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */,\n\t\t\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,\n\t\t\t\t97C147021CF9000F007C117D /* Info.plist */,\n\t\t\t\t97C146F11CF9000F007C117D /* Supporting Files */,\n\t\t\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,\n\t\t\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,\n\t\t\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */,\n\t\t\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,\n\t\t\t);\n\t\t\tpath = Runner;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146F11CF9000F007C117D /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t97C146ED1CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t9740EEB61CF901F6004384FC /* Run Script */,\n\t\t\t\t97C146EA1CF9000F007C117D /* Sources */,\n\t\t\t\t97C146EB1CF9000F007C117D /* Frameworks */,\n\t\t\t\t97C146EC1CF9000F007C117D /* Resources */,\n\t\t\t\t9705A1C41CF9048500538489 /* Embed Frameworks */,\n\t\t\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Runner;\n\t\t\tproductName = Runner;\n\t\t\tproductReference = 97C146EE1CF9000F007C117D /* Runner.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t97C146E61CF9000F007C117D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = \"\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t97C146ED1CF9000F007C117D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 97C146E51CF9000F007C117D;\n\t\t\tproductRefGroup = 97C146EF1CF9000F007C117D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t97C146ED1CF9000F007C117D /* Runner */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t97C146EC1CF9000F007C117D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,\n\t\t\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,\n\t\t\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Thin Binary\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" embed_and_thin\";\n\t\t};\n\t\t9740EEB61CF901F6004384FC /* Run Script */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" build\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t97C146EA1CF9000F007C117D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,\n\t\t\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t97C146FA1CF9000F007C117D /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FB1CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C147001CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t249021D3217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t249021D4217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t97C147031CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147041CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\";\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t97C147061CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147071CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/Flutter\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147031CF9000F007C117D /* Debug */,\n\t\t\t\t97C147041CF9000F007C117D /* Release */,\n\t\t\t\t249021D3217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147061CF9000F007C117D /* Debug */,\n\t\t\t\t97C147071CF9000F007C117D /* Release */,\n\t\t\t\t249021D4217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 97C146E61CF9000F007C117D /* Project object */;\n}\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1020\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n               BuildableName = \"Runner.app\"\n               BlueprintName = \"Runner\"\n               ReferencedContainer = \"container:Runner.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Profile\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:multi_select_flutter/multi_select_flutter.dart';\n\nvoid main() {\n  runApp(MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'Flutter Multi Select',\n      theme: ThemeData(\n        primarySwatch: Colors.purple,\n        visualDensity: VisualDensity.adaptivePlatformDensity,\n      ),\n      home: MyHomePage(title: 'Flutter Multi Select'),\n    );\n  }\n}\n\nclass Animal {\n  final int id;\n  final String name;\n\n  Animal({\n    this.id,\n    this.name,\n  });\n}\n\nclass MyHomePage extends StatefulWidget {\n  MyHomePage({Key key, this.title}) : super(key: key);\n  final String title;\n  @override\n  _MyHomePageState createState() => _MyHomePageState();\n}\n\nclass _MyHomePageState extends State<MyHomePage> {\n  static List<Animal> _animals = [\n    Animal(id: 1, name: \"Lion\"),\n    Animal(id: 2, name: \"Flamingo\"),\n    Animal(id: 3, name: \"Hippo\"),\n    Animal(id: 4, name: \"Horse\"),\n    Animal(id: 5, name: \"Tiger\"),\n    Animal(id: 6, name: \"Penguin\"),\n    Animal(id: 7, name: \"Spider\"),\n    Animal(id: 8, name: \"Snake\"),\n    Animal(id: 9, name: \"Bear\"),\n    Animal(id: 10, name: \"Beaver\"),\n    Animal(id: 11, name: \"Cat\"),\n    Animal(id: 12, name: \"Fish\"),\n    Animal(id: 13, name: \"Rabbit\"),\n    Animal(id: 14, name: \"Mouse\"),\n    Animal(id: 15, name: \"Dog\"),\n    Animal(id: 16, name: \"Zebra\"),\n    Animal(id: 17, name: \"Cow\"),\n    Animal(id: 18, name: \"Frog\"),\n    Animal(id: 19, name: \"Blue Jay\"),\n    Animal(id: 20, name: \"Moose\"),\n    Animal(id: 21, name: \"Gecko\"),\n    Animal(id: 22, name: \"Kangaroo\"),\n    Animal(id: 23, name: \"Shark\"),\n    Animal(id: 24, name: \"Crocodile\"),\n    Animal(id: 25, name: \"Owl\"),\n    Animal(id: 26, name: \"Dragonfly\"),\n    Animal(id: 27, name: \"Dolphin\"),\n  ];\n  final _items = _animals\n      .map((animal) => MultiSelectItem<Animal>(animal, animal.name))\n      .toList();\n  //List<Animal> _selectedAnimals = [];\n  List<Animal> _selectedAnimals2 = [];\n  List<Animal> _selectedAnimals3 = [];\n  //List<Animal> _selectedAnimals4 = [];\n  List<Animal> _selectedAnimals5 = [];\n  final _multiSelectKey = GlobalKey<FormFieldState>();\n\n  @override\n  void initState() {\n    _selectedAnimals5 = _animals;\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(widget.title),\n      ),\n      body: SingleChildScrollView(\n        child: Container(\n          alignment: Alignment.center,\n          padding: EdgeInsets.all(20),\n          child: Column(\n            children: <Widget>[\n              SizedBox(height: 40),\n              //################################################################################################\n              // Rounded blue MultiSelectDialogField\n              //################################################################################################\n              MultiSelectDialogField(\n                items: _items,\n                title: Text(\"Animals\"),\n                selectedColor: Colors.blue,\n                decoration: BoxDecoration(\n                  color: Colors.blue.withOpacity(0.1),\n                  borderRadius: BorderRadius.all(Radius.circular(40)),\n                  border: Border.all(\n                    color: Colors.blue,\n                    width: 2,\n                  ),\n                ),\n                buttonIcon: Icon(\n                  Icons.pets,\n                  color: Colors.blue,\n                ),\n                buttonText: Text(\n                  \"Favorite Animals\",\n                  style: TextStyle(\n                    color: Colors.blue[800],\n                    fontSize: 16,\n                  ),\n                ),\n                onConfirm: (results) {\n                  //_selectedAnimals = results;\n                },\n              ),\n              SizedBox(height: 50),\n              //################################################################################################\n              // This MultiSelectBottomSheetField has no decoration, but is instead wrapped in a Container that has\n              // decoration applied. This allows the ChipDisplay to render inside the same Container.\n              //################################################################################################\n              Container(\n                decoration: BoxDecoration(\n                  color: Theme.of(context).primaryColor.withOpacity(.4),\n                  border: Border.all(\n                    color: Theme.of(context).primaryColor,\n                    width: 2,\n                  ),\n                ),\n                child: Column(\n                  children: <Widget>[\n                    MultiSelectBottomSheetField(\n                      initialChildSize: 0.4,\n                      listType: MultiSelectListType.CHIP,\n                      searchable: true,\n                      buttonText: Text(\"Favorite Animals\"),\n                      title: Text(\"Animals\"),\n                      items: _items,\n                      onConfirm: (values) {\n                        _selectedAnimals2 = values;\n                      },\n                      chipDisplay: MultiSelectChipDisplay(\n                        onTap: (value) {\n                          setState(() {\n                            _selectedAnimals2.remove(value);\n                          });\n                        },\n                      ),\n                    ),\n                    _selectedAnimals2 == null || _selectedAnimals2.isEmpty\n                        ? Container(\n                            padding: EdgeInsets.all(10),\n                            alignment: Alignment.centerLeft,\n                            child: Text(\n                              \"None selected\",\n                              style: TextStyle(color: Colors.black54),\n                            ))\n                        : Container(),\n                  ],\n                ),\n              ),\n              SizedBox(height: 40),\n              //################################################################################################\n              // MultiSelectBottomSheetField with validators\n              //################################################################################################\n              MultiSelectBottomSheetField<Animal>(\n                key: _multiSelectKey,\n                initialChildSize: 0.7,\n                maxChildSize: 0.95,\n                title: Text(\"Animals\"),\n                buttonText: Text(\"Favorite Animals\"),\n                items: _items,\n                searchable: true,\n                validator: (values) {\n                  if (values == null || values.isEmpty) {\n                    return \"Required\";\n                  }\n                  List<String> names = values.map((e) => e.name).toList();\n                  if (names.contains(\"Frog\")) {\n                    return \"Frogs are weird!\";\n                  }\n                  return null;\n                },\n                onConfirm: (values) {\n                  setState(() {\n                    _selectedAnimals3 = values;\n                  });\n                  _multiSelectKey.currentState.validate();\n                },\n                chipDisplay: MultiSelectChipDisplay(\n                  onTap: (item) {\n                    setState(() {\n                      _selectedAnimals3.remove(item);\n                    });\n                    _multiSelectKey.currentState.validate();\n                  },\n                ),\n              ),\n              SizedBox(height: 40),\n              //################################################################################################\n              // MultiSelectChipField\n              //################################################################################################\n              MultiSelectChipField(\n                items: _items,\n                initialValue: [_animals[4], _animals[7], _animals[9]],\n                title: Text(\"Animals\"),\n                headerColor: Colors.blue.withOpacity(0.5),\n                decoration: BoxDecoration(\n                  border: Border.all(color: Colors.blue[700], width: 1.8),\n                ),\n                selectedChipColor: Colors.blue.withOpacity(0.5),\n                selectedTextStyle: TextStyle(color: Colors.blue[800]),\n                onTap: (values) {\n                  //_selectedAnimals4 = values;\n                },\n              ),\n              SizedBox(height: 40),\n              //################################################################################################\n              // MultiSelectDialogField with initial values\n              //################################################################################################\n              MultiSelectDialogField(\n                onConfirm: (val) {\n                  _selectedAnimals5 = val;\n                },\n                dialogWidth: MediaQuery.of(context).size.width * 0.7,\n                items: _items,\n                initialValue:\n                    _selectedAnimals5, // setting the value of this in initState() to pre-select values.\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "example/pubspec.yaml",
    "content": "name: example\ndescription: A new Flutter project.\n\n# The following line prevents the package from being accidentally published to\n# pub.dev using `pub publish`. This is preferred for private packages.\npublish_to: \"none\" # Remove this line if you wish to publish to pub.dev\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.7.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n  multi_select_flutter:\n    path: ../\n\n  # The following adds the Cupertino Icons font to your application.\n  # Use with the CupertinoIcons class for iOS style icons.\n  cupertino_icons: ^0.1.3\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n# For information on the generic Dart part of this file, see the\n# following page: https://dart.dev/tools/pub/pubspec\n\n# The following section is specific to Flutter.\nflutter:\n  # The following line ensures that the Material Icons font is\n  # included with your application, so that you can use the icons in\n  # the material Icons class.\n  uses-material-design: true\n\n  # To add assets to your application, add an assets section, like this:\n  # assets:\n  #   - images/a_dot_burr.jpeg\n  #   - images/a_dot_ham.jpeg\n\n  # An image asset can refer to one or more resolution-specific \"variants\", see\n  # https://flutter.dev/assets-and-images/#resolution-aware.\n\n  # For details regarding adding assets from package dependencies, see\n  # https://flutter.dev/assets-and-images/#from-packages\n\n  # To add custom fonts to your application, add a fonts section here,\n  # in this \"flutter\" section. Each entry in this list should have a\n  # \"family\" key with the font family name, and a \"fonts\" key with a\n  # list giving the asset and other descriptors for the font. For\n  # example:\n  # fonts:\n  #   - family: Schyler\n  #     fonts:\n  #       - asset: fonts/Schyler-Regular.ttf\n  #       - asset: fonts/Schyler-Italic.ttf\n  #         style: italic\n  #   - family: Trajan Pro\n  #     fonts:\n  #       - asset: fonts/TrajanPro.ttf\n  #       - asset: fonts/TrajanPro_Bold.ttf\n  #         weight: 700\n  #\n  # For details regarding fonts from package dependencies,\n  # see https://flutter.dev/custom-fonts/#from-packages\n"
  },
  {
    "path": "example/test/widget_test.dart",
    "content": "// This is a basic Flutter widget test.\n//\n// To perform an interaction with a widget in your test, use the WidgetTester\n// utility that Flutter provides. For example, you can send tap and scroll\n// gestures. You can also use WidgetTester to find child widgets in the widget\n// tree, read text, and verify that the values of widget properties are correct.\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:example/main.dart';\n\nvoid main() {\n  testWidgets('Counter increments smoke test', (WidgetTester tester) async {\n    // Build our app and trigger a frame.\n    await tester.pumpWidget(MyApp());\n\n    // Verify that our counter starts at 0.\n    expect(find.text('0'), findsOneWidget);\n    expect(find.text('1'), findsNothing);\n\n    // Tap the '+' icon and trigger a frame.\n    await tester.tap(find.byIcon(Icons.add));\n    await tester.pump();\n\n    // Verify that our counter has incremented.\n    expect(find.text('0'), findsNothing);\n    expect(find.text('1'), findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "example/web/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <!--\n    If you are serving your web app in a path other than the root, change the\n    href value below to reflect the base path you are serving from.\n\n    The path provided below has to start and end with a slash \"/\" in order for\n    it to work correctly.\n\n    For more details:\n    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\n\n    This is a placeholder for base href that will be replaced by the value of\n    the `--base-href` argument provided to `flutter build`.\n  -->\n  <base href=\"$FLUTTER_BASE_HREF\">\n\n  <meta charset=\"UTF-8\">\n  <meta content=\"IE=Edge\" http-equiv=\"X-UA-Compatible\">\n  <meta name=\"description\" content=\"A new Flutter project.\">\n\n  <!-- iOS meta tags & icons -->\n  <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n  <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n  <meta name=\"apple-mobile-web-app-title\" content=\"example\">\n  <link rel=\"apple-touch-icon\" href=\"icons/Icon-192.png\">\n\n  <!-- Favicon -->\n  <link rel=\"icon\" type=\"image/png\" href=\"favicon.png\"/>\n\n  <title>example</title>\n  <link rel=\"manifest\" href=\"manifest.json\">\n</head>\n<body>\n  <!-- This script installs service_worker.js to provide PWA functionality to\n       application. For more information, see:\n       https://developers.google.com/web/fundamentals/primers/service-workers -->\n  <script>\n    var serviceWorkerVersion = null;\n    var scriptLoaded = false;\n    function loadMainDartJs() {\n      if (scriptLoaded) {\n        return;\n      }\n      scriptLoaded = true;\n      var scriptTag = document.createElement('script');\n      scriptTag.src = 'main.dart.js';\n      scriptTag.type = 'application/javascript';\n      document.body.append(scriptTag);\n    }\n\n    if ('serviceWorker' in navigator) {\n      // Service workers are supported. Use them.\n      window.addEventListener('load', function () {\n        // Wait for registration to finish before dropping the <script> tag.\n        // Otherwise, the browser will load the script multiple times,\n        // potentially different versions.\n        var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;\n        navigator.serviceWorker.register(serviceWorkerUrl)\n          .then((reg) => {\n            function waitForActivation(serviceWorker) {\n              serviceWorker.addEventListener('statechange', () => {\n                if (serviceWorker.state == 'activated') {\n                  console.log('Installed new service worker.');\n                  loadMainDartJs();\n                }\n              });\n            }\n            if (!reg.active && (reg.installing || reg.waiting)) {\n              // No active web worker and we have installed or are installing\n              // one for the first time. Simply wait for it to activate.\n              waitForActivation(reg.installing || reg.waiting);\n            } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {\n              // When the app updates the serviceWorkerVersion changes, so we\n              // need to ask the service worker to update.\n              console.log('New service worker available.');\n              reg.update();\n              waitForActivation(reg.installing);\n            } else {\n              // Existing service worker is still good.\n              console.log('Loading app from service worker.');\n              loadMainDartJs();\n            }\n          });\n\n        // If service worker doesn't succeed in a reasonable amount of time,\n        // fallback to plaint <script> tag.\n        setTimeout(() => {\n          if (!scriptLoaded) {\n            console.warn(\n              'Failed to load app from service worker. Falling back to plain <script> tag.',\n            );\n            loadMainDartJs();\n          }\n        }, 4000);\n      });\n    } else {\n      // Service workers not supported. Just drop the <script> tag.\n      loadMainDartJs();\n    }\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "example/web/manifest.json",
    "content": "{\n    \"name\": \"example\",\n    \"short_name\": \"example\",\n    \"start_url\": \".\",\n    \"display\": \"standalone\",\n    \"background_color\": \"#0175C2\",\n    \"theme_color\": \"#0175C2\",\n    \"description\": \"A new Flutter project.\",\n    \"orientation\": \"portrait-primary\",\n    \"prefer_related_applications\": false,\n    \"icons\": [\n        {\n            \"src\": \"icons/Icon-192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"icons/Icon-512.png\",\n            \"sizes\": \"512x512\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"icons/Icon-maskable-192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\",\n            \"purpose\": \"maskable\"\n        },\n        {\n            \"src\": \"icons/Icon-maskable-512.png\",\n            \"sizes\": \"512x512\",\n            \"type\": \"image/png\",\n            \"purpose\": \"maskable\"\n        }\n    ]\n}\n"
  },
  {
    "path": "lib/bottom_sheet/multi_select_bottom_sheet.dart",
    "content": "import 'package:flutter/material.dart';\nimport '../util/multi_select_item.dart';\nimport '../util/multi_select_actions.dart';\nimport '../util/multi_select_list_type.dart';\n\n/// A bottom sheet widget containing either a classic checkbox style list, or a chip style list.\nclass MultiSelectBottomSheet<T> extends StatefulWidget\n    with MultiSelectActions<T> {\n  /// List of items to select from.\n  final List<MultiSelectItem<T>> items;\n\n  /// The list of selected values before interaction.\n  final List<T> initialValue;\n\n  /// The text at the top of the BottomSheet.\n  final Widget? title;\n\n  /// Fires when the an item is selected / unselected.\n  final void Function(List<T>)? onSelectionChanged;\n\n  /// Fires when confirm is tapped.\n  final void Function(List<T>)? onConfirm;\n\n  /// Toggles search functionality.\n  final bool searchable;\n\n  /// Text on the confirm button.\n  final Text? confirmText;\n\n  /// Text on the cancel button.\n  final Text? cancelText;\n\n  /// An enum that determines which type of list to render.\n  final MultiSelectListType? listType;\n\n  /// Sets the color of the checkbox or chip when it's selected.\n  final Color? selectedColor;\n\n  /// Set the initial height of the BottomSheet.\n  final double? initialChildSize;\n\n  /// Set the minimum height threshold of the BottomSheet before it closes.\n  final double? minChildSize;\n\n  /// Set the maximum height of the BottomSheet.\n  final double? maxChildSize;\n\n  /// Set the placeholder text of the search field.\n  final String? searchHint;\n\n  /// A function that sets the color of selected items based on their value.\n  /// It will either set the chip color, or the checkbox color depending on the list type.\n  final Color? Function(T)? colorator;\n\n  /// Color of the chip body or checkbox border while not selected.\n  final Color? unselectedColor;\n\n  /// Icon button that shows the search field.\n  final Icon? searchIcon;\n\n  /// Icon button that hides the search field\n  final Icon? closeSearchIcon;\n\n  /// Style the text on the chips or list tiles.\n  final TextStyle? itemsTextStyle;\n\n  /// Style the text on the selected chips or list tiles.\n  final TextStyle? selectedItemsTextStyle;\n\n  /// Style the search text.\n  final TextStyle? searchTextStyle;\n\n  /// Style the search hint.\n  final TextStyle? searchHintStyle;\n\n  /// Moves the selected items to the top of the list.\n  final bool separateSelectedItems;\n\n  /// Set the color of the check in the checkbox\n  final Color? checkColor;\n\n  MultiSelectBottomSheet({\n    required this.items,\n    required this.initialValue,\n    this.title,\n    this.onSelectionChanged,\n    this.onConfirm,\n    this.listType,\n    this.cancelText,\n    this.confirmText,\n    this.searchable = false,\n    this.selectedColor,\n    this.initialChildSize,\n    this.minChildSize,\n    this.maxChildSize,\n    this.colorator,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchTextStyle,\n    this.searchHint,\n    this.searchHintStyle,\n    this.selectedItemsTextStyle,\n    this.separateSelectedItems = false,\n    this.checkColor,\n  });\n\n  @override\n  _MultiSelectBottomSheetState<T> createState() =>\n      _MultiSelectBottomSheetState<T>(items);\n}\n\nclass _MultiSelectBottomSheetState<T> extends State<MultiSelectBottomSheet<T>> {\n  List<T> _selectedValues = [];\n  bool _showSearch = false;\n  List<MultiSelectItem<T>> _items;\n\n  _MultiSelectBottomSheetState(this._items);\n\n  @override\n  void initState() {\n    super.initState();\n    _selectedValues.addAll(widget.initialValue);\n\n    for (int i = 0; i < _items.length; i++) {\n      _items[i].selected = false;\n      if (_selectedValues.contains(_items[i].value)) {\n        _items[i].selected = true;\n      }\n    }\n\n    if (widget.separateSelectedItems) {\n      _items = widget.separateSelected(_items);\n    }\n  }\n\n  /// Returns a CheckboxListTile\n  Widget _buildListItem(MultiSelectItem<T> item) {\n    return Theme(\n      data: ThemeData(\n        unselectedWidgetColor: widget.unselectedColor ?? Colors.black54,\n      ),\n      child: CheckboxListTile(\n        checkColor: widget.checkColor,\n        value: item.selected,\n        activeColor: widget.colorator != null\n            ? widget.colorator!(item.value) ?? widget.selectedColor\n            : widget.selectedColor,\n        title: Text(\n          item.label,\n          style: item.selected\n              ? widget.selectedItemsTextStyle\n              : widget.itemsTextStyle,\n        ),\n        controlAffinity: ListTileControlAffinity.leading,\n        onChanged: (checked) {\n          setState(() {\n            _selectedValues = widget.onItemCheckedChange(\n                _selectedValues, item.value, checked!);\n\n            if (checked) {\n              item.selected = true;\n            } else {\n              item.selected = false;\n            }\n            if (widget.separateSelectedItems) {\n              _items = widget.separateSelected(_items);\n            }\n          });\n          if (widget.onSelectionChanged != null) {\n            widget.onSelectionChanged!(_selectedValues);\n          }\n        },\n      ),\n    );\n  }\n\n  /// Returns a ChoiceChip\n  Widget _buildChipItem(MultiSelectItem<T> item) {\n    return Container(\n      padding: const EdgeInsets.all(2.0),\n      child: ChoiceChip(\n        backgroundColor: widget.unselectedColor,\n        selectedColor:\n            widget.colorator != null && widget.colorator!(item.value) != null\n                ? widget.colorator!(item.value)\n                : widget.selectedColor != null\n                    ? widget.selectedColor\n                    : Theme.of(context).primaryColor.withOpacity(0.35),\n        label: Text(\n          item.label,\n          style: _selectedValues.contains(item.value)\n              ? TextStyle(\n                  color: widget.selectedItemsTextStyle?.color ??\n                      widget.colorator?.call(item.value) ??\n                      widget.selectedColor?.withOpacity(1) ??\n                      Theme.of(context).primaryColor,\n                  fontSize: widget.selectedItemsTextStyle != null\n                      ? widget.selectedItemsTextStyle!.fontSize\n                      : null,\n                )\n              : widget.itemsTextStyle,\n        ),\n        selected: item.selected,\n        onSelected: (checked) {\n          if (checked) {\n            item.selected = true;\n          } else {\n            item.selected = false;\n          }\n          setState(() {\n            _selectedValues = widget.onItemCheckedChange(\n                _selectedValues, item.value, checked);\n          });\n          if (widget.onSelectionChanged != null) {\n            widget.onSelectionChanged!(_selectedValues);\n          }\n        },\n      ),\n    );\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      padding:\n          EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),\n      child: DraggableScrollableSheet(\n        initialChildSize: widget.initialChildSize ?? 0.3,\n        minChildSize: widget.minChildSize ?? 0.3,\n        maxChildSize: widget.maxChildSize ?? 0.6,\n        expand: false,\n        builder: (BuildContext context, ScrollController scrollController) {\n          return Column(\n            children: [\n              Padding(\n                padding: const EdgeInsets.all(10),\n                child: Row(\n                  mainAxisAlignment: MainAxisAlignment.spaceBetween,\n                  children: [\n                    _showSearch\n                        ? Expanded(\n                            child: Container(\n                              padding: const EdgeInsets.only(left: 10),\n                              child: TextField(\n                                autofocus: true,\n                                style: widget.searchTextStyle,\n                                decoration: InputDecoration(\n                                  hintStyle: widget.searchHintStyle,\n                                  hintText: widget.searchHint ?? \"Search\",\n                                  focusedBorder: UnderlineInputBorder(\n                                    borderSide: BorderSide(\n                                        color: widget.selectedColor ??\n                                            Theme.of(context).primaryColor),\n                                  ),\n                                ),\n                                onChanged: (val) {\n                                  List<MultiSelectItem<T>> filteredList = [];\n                                  filteredList = widget.updateSearchQuery(\n                                      val, widget.items);\n                                  setState(() {\n                                    if (widget.separateSelectedItems) {\n                                      _items =\n                                          widget.separateSelected(filteredList);\n                                    } else {\n                                      _items = filteredList;\n                                    }\n                                  });\n                                },\n                              ),\n                            ),\n                          )\n                        : widget.title ??\n                            Text(\n                              \"Select\",\n                              style: TextStyle(fontSize: 18),\n                            ),\n                    widget.searchable\n                        ? IconButton(\n                            icon: _showSearch\n                                ? widget.closeSearchIcon ?? Icon(Icons.close)\n                                : widget.searchIcon ?? Icon(Icons.search),\n                            onPressed: () {\n                              setState(() {\n                                _showSearch = !_showSearch;\n                                if (!_showSearch) {\n                                  if (widget.separateSelectedItems) {\n                                    _items =\n                                        widget.separateSelected(widget.items);\n                                  } else {\n                                    _items = widget.items;\n                                  }\n                                }\n                              });\n                            },\n                          )\n                        : Padding(\n                            padding: EdgeInsets.all(15),\n                          ),\n                  ],\n                ),\n              ),\n              Expanded(\n                child: widget.listType == null ||\n                        widget.listType == MultiSelectListType.LIST\n                    ? ListView.builder(\n                        controller: scrollController,\n                        itemCount: _items.length,\n                        itemBuilder: (context, index) {\n                          return _buildListItem(_items[index]);\n                        },\n                      )\n                    : SingleChildScrollView(\n                        controller: scrollController,\n                        child: Container(\n                          padding: EdgeInsets.all(10),\n                          child: Wrap(\n                            children: _items.map(_buildChipItem).toList(),\n                          ),\n                        ),\n                      ),\n              ),\n              Container(\n                padding: EdgeInsets.all(2),\n                child: Row(\n                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n                  children: [\n                    Expanded(\n                      child: TextButton(\n                        onPressed: () {\n                          widget.onCancelTap(context, widget.initialValue);\n                        },\n                        child: widget.cancelText ??\n                            Text(\n                              \"CANCEL\",\n                              style: TextStyle(\n                                color: (widget.selectedColor != null &&\n                                        widget.selectedColor !=\n                                            Colors.transparent)\n                                    ? widget.selectedColor!.withOpacity(1)\n                                    : Theme.of(context).primaryColor,\n                              ),\n                            ),\n                      ),\n                    ),\n                    SizedBox(width: 10),\n                    Expanded(\n                      child: TextButton(\n                        onPressed: () {\n                          widget.onConfirmTap(\n                              context, _selectedValues, widget.onConfirm);\n                        },\n                        child: widget.confirmText ??\n                            Text(\n                              \"OK\",\n                              style: TextStyle(\n                                color: (widget.selectedColor != null &&\n                                        widget.selectedColor !=\n                                            Colors.transparent)\n                                    ? widget.selectedColor!.withOpacity(1)\n                                    : Theme.of(context).primaryColor,\n                              ),\n                            ),\n                      ),\n                    ),\n                  ],\n                ),\n              ),\n            ],\n          );\n        },\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/bottom_sheet/multi_select_bottom_sheet_field.dart",
    "content": "import 'package:collection/collection.dart' show IterableExtension;\nimport 'package:flutter/material.dart';\nimport '../util/multi_select_list_type.dart';\nimport '../chip_display/multi_select_chip_display.dart';\nimport '../util/multi_select_item.dart';\nimport 'multi_select_bottom_sheet.dart';\n\n/// A customizable InkWell widget that opens the MultiSelectBottomSheet\n// ignore: must_be_immutable\nclass MultiSelectBottomSheetField<V> extends FormField<List<V>> {\n  /// Style the Container that makes up the field.\n  final BoxDecoration? decoration;\n\n  /// Set text that is displayed on the button.\n  final Text? buttonText;\n\n  /// Specify the button icon.\n  final Icon? buttonIcon;\n\n  /// List of items to select from.\n  final List<MultiSelectItem<V>> items;\n\n  /// The list of selected values before interaction.\n  final List<V> initialValue;\n\n  /// The text at the top of the dialog.\n  final Widget? title;\n\n  /// Fires when the an item is selected / unselected.\n  final void Function(List<V>)? onSelectionChanged;\n\n  /// Fires when confirm is tapped.\n  final void Function(List<V>) onConfirm;\n\n  /// Toggles search functionality.\n  final bool searchable;\n\n  /// Text on the confirm button.\n  final Text? confirmText;\n\n  /// Text on the cancel button.\n  final Text? cancelText;\n\n  /// An enum that determines which type of list to render.\n  final MultiSelectListType? listType;\n\n  /// Sets the color of the checkbox or chip body when selected.\n  final Color? selectedColor;\n\n  /// Set the hint text of the search field.\n  final String? searchHint;\n\n  /// Set the initial height of the BottomSheet.\n  final double? initialChildSize;\n\n  /// Set the minimum height threshold of the BottomSheet before it closes.\n  final double? minChildSize;\n\n  /// Set the maximum height of the BottomSheet.\n  final double? maxChildSize;\n\n  /// Apply a ShapeBorder to alter the edges of the BottomSheet.\n  final ShapeBorder? shape;\n\n  /// Set the color of the space outside the BottomSheet.\n  final Color? barrierColor;\n\n  /// Overrides the default MultiSelectChipDisplay attached to this field.\n  /// If you want to remove it, use MultiSelectChipDisplay.none().\n  final MultiSelectChipDisplay<V>? chipDisplay;\n\n  /// A function that sets the color of selected items based on their value.\n  /// It will either set the chip color, or the checkbox color depending on the list type.\n  final Color Function(V)? colorator;\n\n  /// Set the background color of the bottom sheet.\n  final Color? backgroundColor;\n\n  /// Color of the chip body or checkbox border while not selected.\n  final Color? unselectedColor;\n\n  /// Replaces the deafult search icon when searchable is true.\n  final Icon? searchIcon;\n\n  /// Replaces the default close search icon when searchable is true.\n  final Icon? closeSearchIcon;\n\n  /// The TextStyle of the items within the BottomSheet.\n  final TextStyle? itemsTextStyle;\n\n  /// Style the text on the selected chips or list tiles.\n  final TextStyle? selectedItemsTextStyle;\n\n  /// Moves the selected items to the top of the list.\n  final bool separateSelectedItems;\n\n  /// Style the text that is typed into the search field.\n  final TextStyle? searchTextStyle;\n\n  /// Style the search hint.\n  final TextStyle? searchHintStyle;\n\n  /// Set the color of the check in the checkbox\n  final Color? checkColor;\n\n  /// Whether the user can dismiss the widget by tapping outside\n  final bool isDismissible;\n\n  final AutovalidateMode autovalidateMode;\n  final FormFieldValidator<List<V>>? validator;\n  final FormFieldSetter<List<V>>? onSaved;\n  final GlobalKey<FormFieldState>? key;\n  FormFieldState<List<V>>? state;\n\n  MultiSelectBottomSheetField({\n    required this.items,\n    required this.onConfirm,\n    this.title,\n    this.buttonText,\n    this.buttonIcon,\n    this.listType,\n    this.decoration,\n    this.onSelectionChanged,\n    this.chipDisplay,\n    this.initialValue = const [],\n    this.searchable = false,\n    this.confirmText,\n    this.cancelText,\n    this.selectedColor,\n    this.initialChildSize,\n    this.minChildSize,\n    this.maxChildSize,\n    this.shape,\n    this.barrierColor,\n    this.searchHint,\n    this.colorator,\n    this.backgroundColor,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchTextStyle,\n    this.searchHintStyle,\n    this.selectedItemsTextStyle,\n    this.separateSelectedItems = false,\n    this.checkColor,\n    this.isDismissible = true,\n    this.key,\n    this.onSaved,\n    this.validator,\n    this.autovalidateMode = AutovalidateMode.disabled,\n  }) : super(\n            key: key,\n            onSaved: onSaved,\n            validator: validator,\n            autovalidateMode: autovalidateMode,\n            initialValue: initialValue,\n            builder: (FormFieldState<List<V>> state) {\n              _MultiSelectBottomSheetFieldView view =\n                  _MultiSelectBottomSheetFieldView<V>(\n                items: items,\n                decoration: decoration,\n                unselectedColor: unselectedColor,\n                colorator: colorator,\n                itemsTextStyle: itemsTextStyle,\n                selectedItemsTextStyle: selectedItemsTextStyle,\n                backgroundColor: backgroundColor,\n                title: title,\n                initialValue: initialValue,\n                barrierColor: barrierColor,\n                buttonIcon: buttonIcon,\n                buttonText: buttonText,\n                cancelText: cancelText,\n                chipDisplay: chipDisplay,\n                closeSearchIcon: closeSearchIcon,\n                confirmText: confirmText,\n                initialChildSize: initialChildSize,\n                listType: listType,\n                maxChildSize: maxChildSize,\n                minChildSize: minChildSize,\n                onConfirm: onConfirm,\n                onSelectionChanged: onSelectionChanged,\n                searchHintStyle: searchHintStyle,\n                searchIcon: searchIcon,\n                searchHint: searchHint,\n                searchTextStyle: searchTextStyle,\n                searchable: searchable,\n                selectedColor: selectedColor,\n                separateSelectedItems: separateSelectedItems,\n                shape: shape,\n                checkColor: checkColor,\n                isDismissible: isDismissible,\n              );\n              return _MultiSelectBottomSheetFieldView<V?>._withState(\n                  view as _MultiSelectBottomSheetFieldView<V?>, state);\n            });\n}\n\n// ignore: must_be_immutable\nclass _MultiSelectBottomSheetFieldView<V> extends StatefulWidget {\n  final BoxDecoration? decoration;\n  final Text? buttonText;\n  final Icon? buttonIcon;\n  final List<MultiSelectItem<V>> items;\n  final List<V> initialValue;\n  final Widget? title;\n  final void Function(List<V>)? onSelectionChanged;\n  final void Function(List<V>)? onConfirm;\n  final bool searchable;\n  final Text? confirmText;\n  final Text? cancelText;\n  final MultiSelectListType? listType;\n  final Color? selectedColor;\n  final String? searchHint;\n  final double? initialChildSize;\n  final double? minChildSize;\n  final double? maxChildSize;\n  final ShapeBorder? shape;\n  final Color? barrierColor;\n  final MultiSelectChipDisplay<V>? chipDisplay;\n  final Color Function(V)? colorator;\n  final Color? backgroundColor;\n  final Color? unselectedColor;\n  final Icon? searchIcon;\n  final Icon? closeSearchIcon;\n  final TextStyle? itemsTextStyle;\n  final TextStyle? selectedItemsTextStyle;\n  final TextStyle? searchTextStyle;\n  final TextStyle? searchHintStyle;\n  final bool separateSelectedItems;\n  final Color? checkColor;\n  final bool isDismissible;\n  FormFieldState<List<V>>? state;\n\n  _MultiSelectBottomSheetFieldView({\n    required this.items,\n    this.title,\n    this.buttonText,\n    this.buttonIcon,\n    this.listType,\n    this.decoration,\n    this.onSelectionChanged,\n    this.onConfirm,\n    this.chipDisplay,\n    required this.initialValue,\n    required this.searchable,\n    this.confirmText,\n    this.cancelText,\n    this.selectedColor,\n    this.initialChildSize,\n    this.minChildSize,\n    this.maxChildSize,\n    this.shape,\n    this.barrierColor,\n    this.searchHint,\n    this.colorator,\n    this.backgroundColor,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchTextStyle,\n    this.searchHintStyle,\n    this.selectedItemsTextStyle,\n    required this.separateSelectedItems,\n    this.checkColor,\n    required this.isDismissible,\n  });\n\n  /// This constructor allows a FormFieldState to be passed in. Called by MultiSelectBottomSheetField.\n  _MultiSelectBottomSheetFieldView._withState(\n      _MultiSelectBottomSheetFieldView<V> field, FormFieldState<List<V>> state)\n      : items = field.items,\n        title = field.title,\n        buttonText = field.buttonText,\n        buttonIcon = field.buttonIcon,\n        listType = field.listType,\n        decoration = field.decoration,\n        onSelectionChanged = field.onSelectionChanged,\n        onConfirm = field.onConfirm,\n        chipDisplay = field.chipDisplay,\n        initialValue = field.initialValue,\n        searchable = field.searchable,\n        confirmText = field.confirmText,\n        cancelText = field.cancelText,\n        selectedColor = field.selectedColor,\n        initialChildSize = field.initialChildSize,\n        minChildSize = field.minChildSize,\n        maxChildSize = field.maxChildSize,\n        shape = field.shape,\n        barrierColor = field.barrierColor,\n        searchHint = field.searchHint,\n        colorator = field.colorator,\n        backgroundColor = field.backgroundColor,\n        unselectedColor = field.unselectedColor,\n        searchIcon = field.searchIcon,\n        closeSearchIcon = field.closeSearchIcon,\n        itemsTextStyle = field.itemsTextStyle,\n        searchHintStyle = field.searchHintStyle,\n        searchTextStyle = field.searchTextStyle,\n        selectedItemsTextStyle = field.selectedItemsTextStyle,\n        separateSelectedItems = field.separateSelectedItems,\n        checkColor = field.checkColor,\n        isDismissible = field.isDismissible,\n        state = state;\n\n  @override\n  __MultiSelectBottomSheetFieldViewState createState() =>\n      __MultiSelectBottomSheetFieldViewState<V>();\n}\n\nclass __MultiSelectBottomSheetFieldViewState<V>\n    extends State<_MultiSelectBottomSheetFieldView<V>> {\n  List<V> _selectedItems = [];\n\n  @override\n  void initState() {\n    super.initState();\n    _selectedItems.addAll(widget.initialValue);\n  }\n\n  @override\n  void didUpdateWidget(_MultiSelectBottomSheetFieldView<V> oldWidget) {\n    super.didUpdateWidget(oldWidget);\n\n    if (oldWidget.initialValue != widget.initialValue) {\n      _selectedItems = [];\n      _selectedItems.addAll(widget.initialValue);\n\n      WidgetsBinding.instance.addPostFrameCallback((_) {\n        widget.state!.didChange(_selectedItems);\n      });\n    }\n  }\n\n  Widget _buildInheritedChipDisplay() {\n    List<MultiSelectItem<V>?> chipDisplayItems = [];\n    chipDisplayItems = _selectedItems\n        .map((e) =>\n            widget.items.firstWhereOrNull((element) => e == element.value))\n        .toList();\n    chipDisplayItems.removeWhere((element) => element == null);\n    if (widget.chipDisplay != null) {\n      // if user has specified a chipDisplay, use its params\n      if (widget.chipDisplay!.disabled!) {\n        return Container();\n      } else {\n        return MultiSelectChipDisplay<V>(\n          items: chipDisplayItems,\n          colorator: widget.chipDisplay!.colorator ?? widget.colorator,\n          onTap: (item) {\n            List<V>? newValues;\n            if (widget.chipDisplay!.onTap != null) {\n              dynamic result = widget.chipDisplay!.onTap!(item);\n              if (result is List<V>) newValues = result;\n            }\n            if (newValues != null) {\n              _selectedItems = newValues;\n              if (widget.state != null) {\n                widget.state!.didChange(_selectedItems);\n              }\n            }\n          },\n          decoration: widget.chipDisplay!.decoration,\n          chipColor: widget.chipDisplay!.chipColor ??\n              ((widget.selectedColor != null &&\n                      widget.selectedColor != Colors.transparent)\n                  ? widget.selectedColor!.withOpacity(0.35)\n                  : null),\n          alignment: widget.chipDisplay!.alignment,\n          textStyle: widget.chipDisplay!.textStyle,\n          icon: widget.chipDisplay!.icon,\n          shape: widget.chipDisplay!.shape,\n          scroll: widget.chipDisplay!.scroll,\n          scrollBar: widget.chipDisplay!.scrollBar,\n          height: widget.chipDisplay!.height,\n          chipWidth: widget.chipDisplay!.chipWidth,\n        );\n      }\n    } else {\n      // user didn't specify a chipDisplay, build the default\n      return MultiSelectChipDisplay<V>(\n        items: chipDisplayItems,\n        colorator: widget.colorator,\n        chipColor: (widget.selectedColor != null &&\n                widget.selectedColor != Colors.transparent)\n            ? widget.selectedColor!.withOpacity(0.35)\n            : null,\n      );\n    }\n  }\n\n  _showBottomSheet(BuildContext ctx) async {\n    List<V>? myVar = await showModalBottomSheet<List<V>>(\n        isDismissible: widget.isDismissible,\n        backgroundColor: widget.backgroundColor,\n        barrierColor: widget.barrierColor,\n        shape: widget.shape ??\n            RoundedRectangleBorder(\n              borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)),\n            ),\n        isScrollControlled: true,\n        context: context,\n        builder: (context) {\n          return MultiSelectBottomSheet<V>(\n            checkColor: widget.checkColor,\n            selectedItemsTextStyle: widget.selectedItemsTextStyle,\n            searchTextStyle: widget.searchTextStyle,\n            searchHintStyle: widget.searchHintStyle,\n            itemsTextStyle: widget.itemsTextStyle,\n            searchIcon: widget.searchIcon,\n            closeSearchIcon: widget.closeSearchIcon,\n            unselectedColor: widget.unselectedColor,\n            colorator: widget.colorator,\n            searchHint: widget.searchHint,\n            selectedColor: widget.selectedColor,\n            listType: widget.listType,\n            items: widget.items,\n            cancelText: widget.cancelText,\n            confirmText: widget.confirmText,\n            separateSelectedItems: widget.separateSelectedItems,\n            initialValue: _selectedItems,\n            onConfirm: (selected) {\n              if (widget.state != null) {\n                widget.state!.didChange(selected);\n              }\n              _selectedItems = selected;\n              if (widget.onConfirm != null) widget.onConfirm!(selected);\n            },\n            onSelectionChanged: widget.onSelectionChanged,\n            searchable: widget.searchable,\n            title: widget.title,\n            initialChildSize: widget.initialChildSize,\n            minChildSize: widget.minChildSize,\n            maxChildSize: widget.maxChildSize,\n          );\n        });\n    print(myVar.toString());\n    _selectedItems = myVar!;\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      mainAxisAlignment: MainAxisAlignment.start,\n      children: <Widget>[\n        InkWell(\n          onTap: () {\n            _showBottomSheet(context);\n          },\n          child: Container(\n            decoration: widget.state != null\n                ? widget.decoration ??\n                    BoxDecoration(\n                      border: Border(\n                        bottom: BorderSide(\n                          color: widget.state != null && widget.state!.hasError\n                              ? Colors.red.shade800.withOpacity(0.6)\n                              : _selectedItems.isNotEmpty\n                                  ? (widget.selectedColor != null &&\n                                          widget.selectedColor !=\n                                              Colors.transparent)\n                                      ? widget.selectedColor!\n                                      : Theme.of(context).primaryColor\n                                  : Colors.black45,\n                          width: _selectedItems.isNotEmpty\n                              ? (widget.state != null && widget.state!.hasError)\n                                  ? 1.4\n                                  : 1.8\n                              : 1.2,\n                        ),\n                      ),\n                    )\n                : widget.decoration,\n            padding: EdgeInsets.all(10),\n            child: Row(\n              mainAxisAlignment: MainAxisAlignment.spaceBetween,\n              children: <Widget>[\n                widget.buttonText ?? Text(\"Select\"),\n                widget.buttonIcon ?? Icon(Icons.arrow_downward),\n              ],\n            ),\n          ),\n        ),\n        _buildInheritedChipDisplay(),\n        widget.state != null && widget.state!.hasError\n            ? SizedBox(height: 5)\n            : Container(),\n        widget.state != null && widget.state!.hasError\n            ? Row(\n                children: <Widget>[\n                  Padding(\n                    padding: const EdgeInsets.only(left: 4),\n                    child: Text(\n                      widget.state!.errorText!,\n                      style: TextStyle(\n                        color: Colors.red[800],\n                        fontSize: 12.5,\n                      ),\n                    ),\n                  ),\n                ],\n              )\n            : Container(),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/chip_display/multi_select_chip_display.dart",
    "content": "import 'package:flutter/material.dart';\nimport '../util/horizontal_scrollbar.dart';\nimport '../util/multi_select_item.dart';\n\n/// A widget meant to display selected values as chips.\n// ignore: must_be_immutable\nclass MultiSelectChipDisplay<V> extends StatelessWidget {\n  /// The source list of selected items.\n  final List<MultiSelectItem<V>?>? items;\n\n  /// Fires when a chip is tapped.\n  final Function(V)? onTap;\n\n  /// Set the chip color.\n  final Color? chipColor;\n\n  /// Change the alignment of the chips.\n  final Alignment? alignment;\n\n  /// Style the Container that makes up the chip display.\n  final BoxDecoration? decoration;\n\n  /// Style the text on the chips.\n  final TextStyle? textStyle;\n\n  /// A function that sets the color of selected items based on their value.\n  final Color? Function(V)? colorator;\n\n  /// An icon to display prior to the chip's label.\n  final Icon? icon;\n\n  /// Set a ShapeBorder. Typically a RoundedRectangularBorder.\n  final ShapeBorder? shape;\n\n  /// Enables horizontal scrolling.\n  final bool scroll;\n\n  /// Enables the scrollbar when scroll is `true`.\n  final HorizontalScrollBar? scrollBar;\n\n  final ScrollController _scrollController = ScrollController();\n\n  /// Set a fixed height.\n  final double? height;\n\n  /// Set the width of the chips.\n  final double? chipWidth;\n\n  bool? disabled;\n\n  MultiSelectChipDisplay({\n    this.items,\n    this.onTap,\n    this.chipColor,\n    this.alignment,\n    this.decoration,\n    this.textStyle,\n    this.colorator,\n    this.icon,\n    this.shape,\n    this.scroll = false,\n    this.scrollBar,\n    this.height,\n    this.chipWidth,\n  }) {\n    this.disabled = false;\n  }\n\n  MultiSelectChipDisplay.none({\n    this.items = const [],\n    this.disabled = true,\n    this.onTap,\n    this.chipColor,\n    this.alignment,\n    this.decoration,\n    this.textStyle,\n    this.colorator,\n    this.icon,\n    this.shape,\n    this.scroll = false,\n    this.scrollBar,\n    this.height,\n    this.chipWidth,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    if (items == null || items!.isEmpty) return Container();\n    return Container(\n      decoration: decoration,\n      alignment: alignment ?? Alignment.centerLeft,\n      padding: EdgeInsets.symmetric(horizontal: scroll ? 0 : 10),\n      child: scroll\n          ? Container(\n              width: MediaQuery.of(context).size.width,\n              height: height ?? MediaQuery.of(context).size.height * 0.08,\n              child: scrollBar != null\n                  ? Scrollbar(\n                      thumbVisibility: scrollBar!.isAlwaysShown,\n                      controller: _scrollController,\n                      child: ListView.builder(\n                        controller: _scrollController,\n                        scrollDirection: Axis.horizontal,\n                        itemCount: items!.length,\n                        itemBuilder: (ctx, index) {\n                          return _buildItem(items![index]!, context);\n                        },\n                      ),\n                    )\n                  : ListView.builder(\n                      controller: _scrollController,\n                      scrollDirection: Axis.horizontal,\n                      itemCount: items!.length,\n                      itemBuilder: (ctx, index) {\n                        return _buildItem(items![index]!, context);\n                      },\n                    ),\n            )\n          : Wrap(\n              children: items != null\n                  ? items!.map((item) => _buildItem(item!, context)).toList()\n                  : <Widget>[\n                      Container(),\n                    ],\n            ),\n    );\n  }\n\n  Widget _buildItem(MultiSelectItem<V> item, BuildContext context) {\n    return Container(\n      padding: const EdgeInsets.all(2.0),\n      child: ChoiceChip(\n        shape: shape as OutlinedBorder?,\n        avatar: icon != null\n            ? Icon(\n                icon!.icon,\n                color: colorator != null && colorator!(item.value) != null\n                    ? colorator!(item.value)!.withOpacity(1)\n                    : icon!.color ?? Theme.of(context).primaryColor,\n              )\n            : null,\n        label: Container(\n          width: chipWidth,\n          child: Text(\n            item.label,\n            overflow: TextOverflow.ellipsis,\n            style: TextStyle(\n              color: colorator != null && colorator!(item.value) != null\n                  ? textStyle != null\n                      ? textStyle!.color ?? colorator!(item.value)\n                      : colorator!(item.value)\n                  : textStyle != null && textStyle!.color != null\n                      ? textStyle!.color\n                      : chipColor != null\n                          ? chipColor!.withOpacity(1)\n                          : null,\n              fontSize: textStyle != null ? textStyle!.fontSize : null,\n            ),\n          ),\n        ),\n        selected: items!.contains(item),\n        selectedColor: colorator != null && colorator!(item.value) != null\n            ? colorator!(item.value)\n            : chipColor != null\n                ? chipColor\n                : Theme.of(context).primaryColor.withOpacity(0.33),\n        onSelected: (_) {\n          if (onTap != null) onTap!(item.value);\n        },\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/chip_field/multi_select_chip_field.dart",
    "content": "import 'package:flutter/material.dart';\nimport '../multi_select_flutter.dart';\n\nclass MultiSelectChipField<V> extends FormField<List<V>> {\n  /// Style the Container that makes up the field.\n  final BoxDecoration? decoration;\n\n  /// List of items to select from.\n  final List<MultiSelectItem<V>> items;\n\n  /// Color of the chip while not selected.\n  final Color? chipColor;\n\n  /// Sets the color of the chip while selected.\n  final Color? selectedChipColor;\n\n  /// Style the text of the chips.\n  final TextStyle? textStyle;\n\n  /// Style the text of the selected chips.\n  final TextStyle? selectedTextStyle;\n\n  /// The icon displayed in front of text on selected chips.\n  final Icon? icon;\n\n  /// Replaces the deafult search icon when searchable is true.\n  final Icon? searchIcon;\n\n  /// Replaces the default close search icon when searchable is true.\n  final Icon? closeSearchIcon;\n\n  /// Set a ShapeBorder. Typically a RoundedRectangularBorder.\n  final ShapeBorder? chipShape;\n\n  /// Defines the header text.\n  final Text? title;\n\n  /// Enables horizontal scrolling. Default is true.\n  final bool scroll;\n\n  /// A function that sets the color of selected items based on their value.\n  final Color Function(V)? colorator;\n\n  /// Fires when a chip is tapped. A good time to store the selected values.\n  final Function(List<V>)? onTap;\n\n  /// Enables search functionality.\n  final bool? searchable;\n\n  /// Set the search hint.\n  final String? searchHint;\n\n  /// Set the TextStyle of the search hint.\n  final TextStyle? searchHintStyle;\n\n  /// Set the TextStyle of the text that gets typed into the search bar.\n  final TextStyle? searchTextStyle;\n\n  /// Set the header color.\n  final Color? headerColor;\n\n  /// Build a custom widget that gets created dynamically for each item.\n  final Widget Function(MultiSelectItem<V>, FormFieldState<List<V>>)?\n      itemBuilder;\n\n  /// Set the height of the selectable area.\n  final double? height;\n\n  /// Make use of the ScrollController to automatically scroll through the list.\n  final Function(ScrollController)? scrollControl;\n\n  /// Define a HorizontalScrollBar.\n  final HorizontalScrollBar? scrollBar;\n\n  /// Determines whether to show the header.\n  final bool showHeader;\n\n  /// Set the width of the chip.\n  final double? chipWidth;\n\n  final List<V> initialValue;\n  final AutovalidateMode autovalidateMode;\n  final FormFieldValidator<List<V>>? validator;\n  final FormFieldSetter<List<V>>? onSaved;\n  final GlobalKey<FormFieldState>? key;\n\n  MultiSelectChipField({\n    required this.items,\n    this.decoration,\n    this.chipColor,\n    this.selectedChipColor,\n    this.colorator,\n    this.textStyle,\n    this.selectedTextStyle,\n    this.icon,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.chipShape,\n    this.onTap,\n    this.title,\n    this.scroll = true,\n    this.searchable,\n    this.searchHint,\n    this.searchHintStyle,\n    this.searchTextStyle,\n    this.headerColor,\n    this.key,\n    this.onSaved,\n    this.validator,\n    this.autovalidateMode = AutovalidateMode.disabled,\n    this.initialValue = const [],\n    this.itemBuilder,\n    this.height,\n    this.scrollControl,\n    this.scrollBar,\n    this.showHeader = true,\n    this.chipWidth,\n  }) : super(\n            key: key,\n            onSaved: onSaved,\n            validator: validator,\n            autovalidateMode: autovalidateMode,\n            initialValue: initialValue,\n            builder: (FormFieldState<List<V>> state) {\n              _MultiSelectChipFieldView view = _MultiSelectChipFieldView<V>(\n                items: items,\n                decoration: decoration,\n                chipColor: chipColor,\n                selectedChipColor: selectedChipColor,\n                colorator: colorator,\n                textStyle: textStyle,\n                selectedTextStyle: selectedTextStyle,\n                icon: icon,\n                searchIcon: searchIcon,\n                closeSearchIcon: closeSearchIcon,\n                chipShape: chipShape,\n                onTap: onTap,\n                title: title,\n                scroll: scroll,\n                initialValue: initialValue,\n                searchable: searchable,\n                searchHint: searchHint,\n                searchHintStyle: searchHintStyle,\n                searchTextStyle: searchTextStyle,\n                headerColor: headerColor,\n                itemBuilder: itemBuilder,\n                height: height,\n                scrollControl: scrollControl,\n                scrollBar: scrollBar,\n                showHeader: showHeader,\n                chipWidth: chipWidth,\n              );\n              return _MultiSelectChipFieldView<V?>.withState(\n                  view as _MultiSelectChipFieldView<V?>, state);\n            });\n}\n\n// ignore: must_be_immutable\nclass _MultiSelectChipFieldView<V> extends StatefulWidget\n    with MultiSelectActions {\n  final BoxDecoration? decoration;\n  final List<MultiSelectItem<V>> items;\n  final List<MultiSelectItem<V>>? selectedItems;\n  final Color? chipColor;\n  final Color? selectedChipColor;\n  final TextStyle? textStyle;\n  final TextStyle? selectedTextStyle;\n  final Icon? icon;\n  final Icon? searchIcon;\n  final Icon? closeSearchIcon;\n  final ShapeBorder? chipShape;\n  final Text? title;\n  final bool scroll;\n  final bool? searchable;\n  final String? searchHint;\n  final TextStyle? searchHintStyle;\n  final TextStyle? searchTextStyle;\n  final List<V> initialValue;\n  final Color? Function(V)? colorator;\n  final Function(List<V>)? onTap;\n  final Color? headerColor;\n  final Widget Function(MultiSelectItem<V>, FormFieldState<List<V>>)?\n      itemBuilder;\n  final double? height;\n  FormFieldState<List<V>>? state;\n  final Function(ScrollController)? scrollControl;\n  final HorizontalScrollBar? scrollBar;\n  final bool showHeader;\n  final double? chipWidth;\n\n  _MultiSelectChipFieldView({\n    required this.items,\n    this.selectedItems,\n    this.decoration,\n    this.chipColor,\n    this.selectedChipColor,\n    this.colorator,\n    this.textStyle,\n    this.selectedTextStyle,\n    this.icon,\n    this.chipShape,\n    this.onTap,\n    this.title,\n    this.scroll = true,\n    this.initialValue = const [],\n    this.searchable,\n    this.searchHint,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.searchHintStyle,\n    this.searchTextStyle,\n    this.headerColor,\n    this.itemBuilder,\n    this.height,\n    this.scrollControl,\n    this.scrollBar,\n    this.showHeader = true,\n    this.chipWidth,\n  });\n\n  /// This constructor allows a FormFieldState to be passed in. Called by MultiSelectChipField.\n  _MultiSelectChipFieldView.withState(\n      _MultiSelectChipFieldView<V> field, FormFieldState<List<V>> state)\n      : items = field.items,\n        title = field.title,\n        decoration = field.decoration,\n        initialValue = field.initialValue,\n        selectedChipColor = field.selectedChipColor,\n        chipShape = field.chipShape,\n        colorator = field.colorator,\n        chipColor = field.chipColor,\n        icon = field.icon,\n        closeSearchIcon = field.closeSearchIcon,\n        selectedItems = field.selectedItems,\n        textStyle = field.textStyle,\n        scroll = field.scroll,\n        selectedTextStyle = field.selectedTextStyle,\n        onTap = field.onTap,\n        searchable = field.searchable,\n        searchHint = field.searchHint,\n        searchIcon = field.searchIcon,\n        searchTextStyle = field.searchTextStyle,\n        searchHintStyle = field.searchHintStyle,\n        headerColor = field.headerColor,\n        itemBuilder = field.itemBuilder,\n        height = field.height,\n        scrollControl = field.scrollControl,\n        scrollBar = field.scrollBar,\n        showHeader = field.showHeader,\n        chipWidth = field.chipWidth,\n        state = state;\n\n  @override\n  __MultiSelectChipFieldViewState createState() =>\n      __MultiSelectChipFieldViewState<V>(items);\n}\n\nclass __MultiSelectChipFieldViewState<V>\n    extends State<_MultiSelectChipFieldView<V?>> {\n  List<V?> _selectedValues = [];\n  bool _showSearch = false;\n  List<MultiSelectItem> _items;\n  ScrollController _scrollController = ScrollController();\n\n  __MultiSelectChipFieldViewState(this._items);\n\n  void initState() {\n    super.initState();\n    _selectedValues.addAll(widget.initialValue);\n\n    if (widget.scrollControl != null && widget.scroll)\n      WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToPosition());\n  }\n\n  @override\n  void didUpdateWidget(_MultiSelectChipFieldView<V> oldWidget) {\n    super.didUpdateWidget(oldWidget);\n\n    if (oldWidget.initialValue != widget.initialValue) {\n      _selectedValues = [];\n      _selectedValues.addAll(widget.initialValue);\n\n      WidgetsBinding.instance.addPostFrameCallback((_) {\n        widget.state!.didChange(_selectedValues);\n      });\n    }\n    if (oldWidget.items != widget.items) {\n      _items = [...widget.items];\n    }\n  }\n\n  _scrollToPosition() {\n    widget.scrollControl!(_scrollController);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: [\n        Container(\n          decoration: widget.decoration ??\n              BoxDecoration(\n                border:\n                    Border.all(width: 1, color: Theme.of(context).primaryColor),\n              ),\n          child: Column(\n            children: [\n              widget.showHeader\n                  ? Container(\n                      color:\n                          widget.headerColor ?? Theme.of(context).primaryColor,\n                      child: Row(\n                        mainAxisAlignment: MainAxisAlignment.spaceBetween,\n                        children: [\n                          _showSearch\n                              ? Expanded(\n                                  child: Container(\n                                    padding: EdgeInsets.only(left: 10),\n                                    child: TextField(\n                                      style: widget.searchTextStyle,\n                                      decoration: InputDecoration(\n                                        hintStyle: widget.searchHintStyle,\n                                        hintText: widget.searchHint ?? \"Search\",\n                                        focusedBorder: UnderlineInputBorder(\n                                          borderSide: BorderSide(\n                                            color: widget.selectedChipColor ??\n                                                Theme.of(context).primaryColor,\n                                          ),\n                                        ),\n                                      ),\n                                      onChanged: (val) {\n                                        setState(() {\n                                          _items = widget.updateSearchQuery(\n                                              val, widget.items);\n                                        });\n                                      },\n                                    ),\n                                  ),\n                                )\n                              : Padding(\n                                  padding: const EdgeInsets.only(left: 8.0),\n                                  child: widget.title != null\n                                      ? Text(\n                                          widget.title!.data!,\n                                          style: TextStyle(\n                                              color: widget.title!.style != null\n                                                  ? widget.title!.style!.color\n                                                  : null,\n                                              fontSize:\n                                                  widget.title!.style != null\n                                                      ? widget.title!.style!\n                                                              .fontSize ??\n                                                          18\n                                                      : 18),\n                                        )\n                                      : Text(\n                                          \"Select\",\n                                          style: TextStyle(fontSize: 18),\n                                        ),\n                                ),\n                          widget.searchable != null && widget.searchable!\n                              ? IconButton(\n                                  icon: _showSearch\n                                      ? widget.closeSearchIcon ??\n                                          Icon(\n                                            Icons.close,\n                                            size: 22,\n                                          )\n                                      : widget.searchIcon ??\n                                          Icon(\n                                            Icons.search,\n                                            size: 22,\n                                          ),\n                                  onPressed: () {\n                                    setState(() {\n                                      _showSearch = !_showSearch;\n                                      if (!_showSearch) _items = widget.items;\n                                    });\n                                  },\n                                )\n                              : Padding(\n                                  padding: EdgeInsets.all(18),\n                                ),\n                        ],\n                      ),\n                    )\n                  : Container(),\n              widget.scroll\n                  ? Container(\n                      padding: widget.itemBuilder == null\n                          ? EdgeInsets.symmetric(horizontal: 5)\n                          : null,\n                      width: MediaQuery.of(context).size.width,\n                      height: widget.height ??\n                          MediaQuery.of(context).size.height * 0.08,\n                      child: widget.scrollBar != null\n                          ? Scrollbar(\n                              thumbVisibility: widget.scrollBar!.isAlwaysShown,\n                              controller: _scrollController,\n                              child: ListView.builder(\n                                controller: _scrollController,\n                                scrollDirection: Axis.horizontal,\n                                itemCount: _items.length,\n                                itemBuilder: (ctx, index) {\n                                  return widget.itemBuilder != null\n                                      ? widget.itemBuilder!(\n                                          _items[index] as MultiSelectItem<V>,\n                                          widget.state!)\n                                      : _buildItem(\n                                          _items[index] as MultiSelectItem<V?>);\n                                },\n                              ),\n                            )\n                          : ListView.builder(\n                              controller: _scrollController,\n                              scrollDirection: Axis.horizontal,\n                              itemCount: _items.length,\n                              itemBuilder: (ctx, index) {\n                                return widget.itemBuilder != null\n                                    ? widget.itemBuilder!(\n                                        _items[index] as MultiSelectItem<V>,\n                                        widget.state!)\n                                    : _buildItem(\n                                        _items[index] as MultiSelectItem<V?>);\n                              },\n                            ),\n                    )\n                  : Container(\n                      height: widget.height,\n                      alignment: Alignment.centerLeft,\n                      padding: EdgeInsets.symmetric(horizontal: 10),\n                      child: Wrap(\n                        children: widget.itemBuilder != null\n                            ? _items\n                                .map((item) => widget.itemBuilder!(\n                                    item as MultiSelectItem<V>, widget.state!))\n                                .toList()\n                            : _items\n                                .map((item) =>\n                                    _buildItem(item as MultiSelectItem<V?>))\n                                .toList(),\n                      ),\n                    ),\n            ],\n          ),\n        ),\n        widget.state != null && widget.state!.hasError\n            ? Row(\n                children: <Widget>[\n                  Padding(\n                    padding: const EdgeInsets.fromLTRB(4, 4, 0, 0),\n                    child: Text(\n                      widget.state!.errorText!,\n                      style: TextStyle(\n                        color: Colors.red[800],\n                        fontSize: 12.5,\n                      ),\n                    ),\n                  ),\n                ],\n              )\n            : Container(),\n      ],\n    );\n  }\n\n  Widget _buildItem(MultiSelectItem<V?> item) {\n    return Container(\n      margin: EdgeInsets.all(0),\n      padding: const EdgeInsets.all(2.0),\n      child: ChoiceChip(\n        shape: widget.chipShape as OutlinedBorder? ??\n            RoundedRectangleBorder(\n              side: BorderSide(\n                  color: widget.colorator != null &&\n                          widget.colorator!(item.value) != null &&\n                          _selectedValues.contains(item.value)\n                      ? widget.colorator!(item.value)!\n                      : widget.selectedChipColor ??\n                          Theme.of(context).primaryColor),\n              borderRadius: BorderRadius.vertical(\n                top: Radius.circular(15.0),\n                bottom: Radius.circular(15.0),\n              ),\n            ),\n        avatar: _selectedValues.contains(item.value)\n            ? widget.icon != null\n                ? Icon(\n                    widget.icon!.icon,\n                    color: widget.colorator != null &&\n                            widget.colorator!(item.value) != null\n                        ? widget.colorator!(item.value)!.withOpacity(1)\n                        : widget.icon!.color ??\n                            widget.selectedChipColor ??\n                            Theme.of(context).primaryColor,\n                  )\n                : null\n            : null,\n        label: Container(\n          width: widget.chipWidth,\n          child: Text(\n            item.label,\n            overflow: TextOverflow.ellipsis,\n            style: _selectedValues.contains(item.value)\n                ? TextStyle(\n                    color: widget.colorator != null &&\n                            widget.colorator!(item.value) != null\n                        ? widget.colorator!(item.value)!.withOpacity(1)\n                        : widget.selectedTextStyle != null\n                            ? widget.selectedTextStyle!.color\n                            : null)\n                : TextStyle(\n                    color: widget.textStyle != null\n                        ? widget.textStyle!.color ?? widget.chipColor\n                        : widget.chipColor,\n                    fontSize: widget.textStyle != null\n                        ? widget.textStyle!.fontSize\n                        : null,\n                  ),\n          ),\n        ),\n        selected: _selectedValues.contains(item.value),\n        backgroundColor: widget.chipColor ?? Colors.white70,\n        selectedColor:\n            widget.colorator != null && widget.colorator!(item.value) != null\n                ? widget.colorator!(item.value)\n                : widget.selectedChipColor != null\n                    ? widget.selectedChipColor\n                    : Theme.of(context).primaryColor.withOpacity(0.33),\n        onSelected: (_) {\n          if (_) {\n            _selectedValues.add(item.value);\n            if (widget.state != null) {\n              widget.state!.didChange(_selectedValues);\n            }\n          } else {\n            _selectedValues.remove(item.value);\n            if (widget.state != null) {\n              widget.state!.didChange(_selectedValues);\n            }\n          }\n          if (widget.onTap != null) widget.onTap!(_selectedValues);\n        },\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/dialog/mult_select_dialog.dart",
    "content": "import 'package:flutter/material.dart';\nimport '../util/multi_select_actions.dart';\nimport '../util/multi_select_item.dart';\nimport '../util/multi_select_list_type.dart';\n\n/// A dialog containing either a classic checkbox style list, or a chip style list.\nclass MultiSelectDialog<T> extends StatefulWidget with MultiSelectActions<T> {\n  /// List of items to select from.\n  final List<MultiSelectItem<T>> items;\n\n  /// The list of selected values before interaction.\n  final List<T> initialValue;\n\n  /// The text at the top of the dialog.\n  final Widget? title;\n\n  /// Fires when the an item is selected / unselected.\n  final void Function(List<T>)? onSelectionChanged;\n\n  /// Fires when confirm is tapped.\n  final void Function(List<T>)? onConfirm;\n\n  /// Toggles search functionality. Default is false.\n  final bool searchable;\n\n  /// Text on the confirm button.\n  final Text? confirmText;\n\n  /// Text on the cancel button.\n  final Text? cancelText;\n\n  /// An enum that determines which type of list to render.\n  final MultiSelectListType? listType;\n\n  /// Sets the color of the checkbox or chip when it's selected.\n  final Color? selectedColor;\n\n  /// Sets a fixed height on the dialog.\n  final double? height;\n\n  /// Sets a fixed width on the dialog.\n  final double? width;\n\n  /// Set the placeholder text of the search field.\n  final String? searchHint;\n\n  /// A function that sets the color of selected items based on their value.\n  /// It will either set the chip color, or the checkbox color depending on the list type.\n  final Color? Function(T)? colorator;\n\n  /// The background color of the dialog.\n  final Color? backgroundColor;\n\n  /// The color of the chip body or checkbox border while not selected.\n  final Color? unselectedColor;\n\n  /// Icon button that shows the search field.\n  final Icon? searchIcon;\n\n  /// Icon button that hides the search field\n  final Icon? closeSearchIcon;\n\n  /// Style the text on the chips or list tiles.\n  final TextStyle? itemsTextStyle;\n\n  /// Style the text on the selected chips or list tiles.\n  final TextStyle? selectedItemsTextStyle;\n\n  /// Style the search text.\n  final TextStyle? searchTextStyle;\n\n  /// Style the search hint.\n  final TextStyle? searchHintStyle;\n\n  /// Moves the selected items to the top of the list.\n  final bool separateSelectedItems;\n\n  /// Set the color of the check in the checkbox\n  final Color? checkColor;\n\n  MultiSelectDialog({\n    required this.items,\n    required this.initialValue,\n    this.title,\n    this.onSelectionChanged,\n    this.onConfirm,\n    this.listType,\n    this.searchable = false,\n    this.confirmText,\n    this.cancelText,\n    this.selectedColor,\n    this.searchHint,\n    this.height,\n    this.width,\n    this.colorator,\n    this.backgroundColor,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchHintStyle,\n    this.searchTextStyle,\n    this.selectedItemsTextStyle,\n    this.separateSelectedItems = false,\n    this.checkColor,\n  });\n\n  @override\n  State<StatefulWidget> createState() => _MultiSelectDialogState<T>(items);\n}\n\nclass _MultiSelectDialogState<T> extends State<MultiSelectDialog<T>> {\n  List<T> _selectedValues = [];\n  bool _showSearch = false;\n  List<MultiSelectItem<T>> _items;\n\n  _MultiSelectDialogState(this._items);\n\n  @override\n  void initState() {\n    super.initState();\n    _selectedValues.addAll(widget.initialValue);\n\n    for (int i = 0; i < _items.length; i++) {\n      _items[i].selected = false;\n      if (_selectedValues.contains(_items[i].value)) {\n        _items[i].selected = true;\n      }\n    }\n\n    if (widget.separateSelectedItems) {\n      _items = widget.separateSelected(_items);\n    }\n  }\n\n  /// Returns a CheckboxListTile\n  Widget _buildListItem(MultiSelectItem<T> item) {\n    return Theme(\n      data: ThemeData(\n        unselectedWidgetColor: widget.unselectedColor ?? Colors.black54,\n      ),\n      child: CheckboxListTile(\n        checkColor: widget.checkColor,\n        value: item.selected,\n        activeColor: widget.colorator != null\n            ? widget.colorator!(item.value) ?? widget.selectedColor\n            : widget.selectedColor,\n        title: Text(\n          item.label,\n          style: item.selected\n              ? widget.selectedItemsTextStyle\n              : widget.itemsTextStyle,\n        ),\n        controlAffinity: ListTileControlAffinity.leading,\n        onChanged: (checked) {\n          setState(() {\n            _selectedValues = widget.onItemCheckedChange(\n                _selectedValues, item.value, checked!);\n\n            if (checked) {\n              item.selected = true;\n            } else {\n              item.selected = false;\n            }\n            if (widget.separateSelectedItems) {\n              _items = widget.separateSelected(_items);\n            }\n          });\n          if (widget.onSelectionChanged != null) {\n            widget.onSelectionChanged!(_selectedValues);\n          }\n        },\n      ),\n    );\n  }\n\n  /// Returns a ChoiceChip\n  Widget _buildChipItem(MultiSelectItem<T> item) {\n    return Container(\n      padding: const EdgeInsets.all(2.0),\n      child: ChoiceChip(\n        backgroundColor: widget.unselectedColor,\n        selectedColor: widget.colorator?.call(item.value) ??\n            widget.selectedColor ??\n            Theme.of(context).primaryColor.withOpacity(0.35),\n        label: Text(\n          item.label,\n          style: item.selected\n              ? TextStyle(\n                  color: widget.selectedItemsTextStyle?.color ??\n                      widget.colorator?.call(item.value) ??\n                      widget.selectedColor?.withOpacity(1) ??\n                      Theme.of(context).primaryColor,\n                  fontSize: widget.selectedItemsTextStyle?.fontSize,\n                )\n              : widget.itemsTextStyle,\n        ),\n        selected: item.selected,\n        onSelected: (checked) {\n          if (checked) {\n            item.selected = true;\n          } else {\n            item.selected = false;\n          }\n          setState(() {\n            _selectedValues = widget.onItemCheckedChange(\n                _selectedValues, item.value, checked);\n          });\n          if (widget.onSelectionChanged != null) {\n            widget.onSelectionChanged!(_selectedValues);\n          }\n        },\n      ),\n    );\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return AlertDialog(\n      backgroundColor: widget.backgroundColor,\n      title: widget.searchable == false\n          ? widget.title ?? const Text(\"Select\")\n          : Row(\n              mainAxisAlignment: MainAxisAlignment.spaceBetween,\n              children: <Widget>[\n                _showSearch\n                    ? Expanded(\n                        child: Container(\n                          padding: EdgeInsets.only(left: 10),\n                          child: TextField(\n                            style: widget.searchTextStyle,\n                            decoration: InputDecoration(\n                              hintStyle: widget.searchHintStyle,\n                              hintText: widget.searchHint ?? \"Search\",\n                              focusedBorder: UnderlineInputBorder(\n                                borderSide: BorderSide(\n                                  color: widget.selectedColor ??\n                                      Theme.of(context).primaryColor,\n                                ),\n                              ),\n                            ),\n                            onChanged: (val) {\n                              List<MultiSelectItem<T>> filteredList = [];\n                              filteredList =\n                                  widget.updateSearchQuery(val, widget.items);\n                              setState(() {\n                                if (widget.separateSelectedItems) {\n                                  _items =\n                                      widget.separateSelected(filteredList);\n                                } else {\n                                  _items = filteredList;\n                                }\n                              });\n                            },\n                          ),\n                        ),\n                      )\n                    : widget.title ?? Text(\"Select\"),\n                IconButton(\n                  icon: _showSearch\n                      ? widget.closeSearchIcon ?? Icon(Icons.close)\n                      : widget.searchIcon ?? Icon(Icons.search),\n                  onPressed: () {\n                    setState(() {\n                      _showSearch = !_showSearch;\n                      if (!_showSearch) {\n                        if (widget.separateSelectedItems) {\n                          _items = widget.separateSelected(widget.items);\n                        } else {\n                          _items = widget.items;\n                        }\n                      }\n                    });\n                  },\n                ),\n              ],\n            ),\n      contentPadding:\n          widget.listType == null || widget.listType == MultiSelectListType.LIST\n              ? EdgeInsets.only(top: 12.0)\n              : EdgeInsets.all(20),\n      content: Container(\n        height: widget.height,\n        width: widget.width ?? MediaQuery.of(context).size.width * 0.73,\n        child: widget.listType == null ||\n                widget.listType == MultiSelectListType.LIST\n            ? ListView.builder(\n                itemCount: _items.length,\n                itemBuilder: (context, index) {\n                  return _buildListItem(_items[index]);\n                },\n              )\n            : SingleChildScrollView(\n                child: Wrap(\n                  children: _items.map(_buildChipItem).toList(),\n                ),\n              ),\n      ),\n      actions: <Widget>[\n        TextButton(\n          child: widget.cancelText ??\n              Text(\n                \"CANCEL\",\n                style: TextStyle(\n                  color: (widget.selectedColor != null &&\n                          widget.selectedColor != Colors.transparent)\n                      ? widget.selectedColor!.withOpacity(1)\n                      : Theme.of(context).primaryColor,\n                ),\n              ),\n          onPressed: () {\n            widget.onCancelTap(context, widget.initialValue);\n          },\n        ),\n        TextButton(\n          child: widget.confirmText ??\n              Text(\n                'OK',\n                style: TextStyle(\n                  color: (widget.selectedColor != null &&\n                          widget.selectedColor != Colors.transparent)\n                      ? widget.selectedColor!.withOpacity(1)\n                      : Theme.of(context).primaryColor,\n                ),\n              ),\n          onPressed: () {\n            widget.onConfirmTap(context, _selectedValues, widget.onConfirm);\n          },\n        )\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/dialog/multi_select_dialog_field.dart",
    "content": "import 'package:collection/collection.dart' show IterableExtension;\nimport 'package:flutter/material.dart';\nimport '../util/multi_select_list_type.dart';\nimport '../util/multi_select_item.dart';\nimport '../chip_display/multi_select_chip_display.dart';\nimport 'mult_select_dialog.dart';\n\n/// A customizable InkWell widget that opens the MultiSelectDialog\n// ignore: must_be_immutable\nclass MultiSelectDialogField<V> extends FormField<List<V>> {\n  /// An enum that determines which type of list to render.\n  final MultiSelectListType? listType;\n\n  /// Style the Container that makes up the field.\n  final BoxDecoration? decoration;\n\n  /// Set text that is displayed on the button.\n  final Text? buttonText;\n\n  /// Specify the button icon.\n  final Icon? buttonIcon;\n\n  /// The text at the top of the dialog.\n  final Widget? title;\n\n  /// List of items to select from.\n  final List<MultiSelectItem<V>> items;\n\n  /// Fires when the an item is selected / unselected.\n  final void Function(List<V>)? onSelectionChanged;\n\n  /// Overrides the default MultiSelectChipDisplay attached to this field.\n  /// If you want to remove it, use MultiSelectChipDisplay.none().\n  final MultiSelectChipDisplay<V>? chipDisplay;\n\n  /// The list of selected values before interaction.\n  final List<V> initialValue;\n\n  /// Fires when confirm is tapped.\n  final void Function(List<V>) onConfirm;\n\n  /// Toggles search functionality.\n  final bool searchable;\n\n  /// Text on the confirm button.\n  final Text? confirmText;\n\n  /// Text on the cancel button.\n  final Text? cancelText;\n\n  /// Set the color of the space outside the BottomSheet.\n  final Color? barrierColor;\n\n  /// Sets the color of the checkbox or chip when it's selected.\n  final Color? selectedColor;\n\n  /// Sets a fixed height on the dialog.\n  final double? dialogHeight;\n\n  /// Sets a fixed width on the dialog.\n  final double? dialogWidth;\n\n  /// Set the placeholder text of the search field.\n  final String? searchHint;\n\n  /// A function that sets the color of selected items based on their value.\n  /// It will either set the chip color, or the checkbox color depending on the list type.\n  final Color Function(V)? colorator;\n\n  /// Set the background color of the dialog.\n  final Color? backgroundColor;\n\n  /// Color of the chip body or checkbox border while not selected.\n  final Color? unselectedColor;\n\n  /// Replaces the deafult search icon when searchable is true.\n  final Icon? searchIcon;\n\n  /// Replaces the default close search icon when searchable is true.\n  final Icon? closeSearchIcon;\n\n  /// Style the text on the chips or list tiles.\n  final TextStyle? itemsTextStyle;\n\n  /// Style the text on the selected chips or list tiles.\n  final TextStyle? selectedItemsTextStyle;\n\n  /// Style the text that is typed into the search field.\n  final TextStyle? searchTextStyle;\n\n  /// Style the search hint.\n  final TextStyle? searchHintStyle;\n\n  /// Moves the selected items to the top of the list.\n  final bool separateSelectedItems;\n\n  /// Set the color of the check in the checkbox\n  final Color? checkColor;\n\n  /// Whether the user can dismiss the widget by tapping outside\n  final bool isDismissible;\n\n  final AutovalidateMode autovalidateMode;\n  final FormFieldValidator<List<V>>? validator;\n  final FormFieldSetter<List<V>>? onSaved;\n  final GlobalKey<FormFieldState>? key;\n  FormFieldState<List<V>>? state;\n\n  MultiSelectDialogField({\n    required this.items,\n    required this.onConfirm,\n    this.title,\n    this.buttonText,\n    this.buttonIcon,\n    this.listType,\n    this.decoration,\n    this.onSelectionChanged,\n    this.chipDisplay,\n    this.searchable = false,\n    this.confirmText,\n    this.cancelText,\n    this.barrierColor,\n    this.selectedColor,\n    this.searchHint,\n    this.dialogHeight,\n    this.dialogWidth,\n    this.colorator,\n    this.backgroundColor,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchTextStyle,\n    this.searchHintStyle,\n    this.selectedItemsTextStyle,\n    this.separateSelectedItems = false,\n    this.checkColor,\n    this.isDismissible = true,\n    this.onSaved,\n    this.validator,\n    this.initialValue = const [],\n    this.autovalidateMode = AutovalidateMode.disabled,\n    this.key,\n  }) : super(\n            key: key,\n            onSaved: onSaved,\n            validator: validator,\n            autovalidateMode: autovalidateMode,\n            initialValue: initialValue,\n            builder: (FormFieldState<List<V>> state) {\n              _MultiSelectDialogFieldView<V> field =\n                  _MultiSelectDialogFieldView<V>(\n                title: title,\n                items: items,\n                buttonText: buttonText,\n                buttonIcon: buttonIcon,\n                chipDisplay: chipDisplay,\n                decoration: decoration,\n                listType: listType,\n                onConfirm: onConfirm,\n                onSelectionChanged: onSelectionChanged,\n                initialValue: initialValue,\n                searchable: searchable,\n                confirmText: confirmText,\n                cancelText: cancelText,\n                barrierColor: barrierColor,\n                selectedColor: selectedColor,\n                searchHint: searchHint,\n                dialogHeight: dialogHeight,\n                dialogWidth: dialogWidth,\n                colorator: colorator,\n                backgroundColor: backgroundColor,\n                unselectedColor: unselectedColor,\n                searchIcon: searchIcon,\n                closeSearchIcon: closeSearchIcon,\n                itemsTextStyle: itemsTextStyle,\n                searchTextStyle: searchTextStyle,\n                searchHintStyle: searchHintStyle,\n                selectedItemsTextStyle: selectedItemsTextStyle,\n                separateSelectedItems: separateSelectedItems,\n                checkColor: checkColor,\n                isDismissible: isDismissible,\n              );\n              return _MultiSelectDialogFieldView<V>._withState(field, state);\n            });\n}\n\n// ignore: must_be_immutable\nclass _MultiSelectDialogFieldView<V> extends StatefulWidget {\n  final MultiSelectListType? listType;\n  final BoxDecoration? decoration;\n  final Text? buttonText;\n  final Icon? buttonIcon;\n  final Widget? title;\n  final List<MultiSelectItem<V>> items;\n  final void Function(List<V>)? onSelectionChanged;\n  final MultiSelectChipDisplay<V>? chipDisplay;\n  final List<V> initialValue;\n  final void Function(List<V>)? onConfirm;\n  final bool? searchable;\n  final Text? confirmText;\n  final Text? cancelText;\n  final Color? barrierColor;\n  final Color? selectedColor;\n  final double? dialogHeight;\n  final double? dialogWidth;\n  final String? searchHint;\n  final Color Function(V)? colorator;\n  final Color? backgroundColor;\n  final Color? unselectedColor;\n  final Icon? searchIcon;\n  final Icon? closeSearchIcon;\n  final TextStyle? itemsTextStyle;\n  final TextStyle? selectedItemsTextStyle;\n  final TextStyle? searchTextStyle;\n  final TextStyle? searchHintStyle;\n  final bool separateSelectedItems;\n  final Color? checkColor;\n  final bool isDismissible;\n  FormFieldState<List<V>>? state;\n\n  _MultiSelectDialogFieldView({\n    required this.items,\n    this.title,\n    this.buttonText,\n    this.buttonIcon,\n    this.listType,\n    this.decoration,\n    this.onSelectionChanged,\n    this.onConfirm,\n    this.chipDisplay,\n    this.initialValue = const [],\n    this.searchable,\n    this.confirmText,\n    this.cancelText,\n    this.barrierColor,\n    this.selectedColor,\n    this.searchHint,\n    this.dialogHeight,\n    this.dialogWidth,\n    this.colorator,\n    this.backgroundColor,\n    this.unselectedColor,\n    this.searchIcon,\n    this.closeSearchIcon,\n    this.itemsTextStyle,\n    this.searchTextStyle,\n    this.searchHintStyle,\n    this.selectedItemsTextStyle,\n    this.separateSelectedItems = false,\n    this.checkColor,\n    required this.isDismissible,\n  });\n\n  /// This constructor allows a FormFieldState to be passed in. Called by MultiSelectDialogField.\n  _MultiSelectDialogFieldView._withState(\n      _MultiSelectDialogFieldView<V> field, FormFieldState<List<V>> state)\n      : items = field.items,\n        title = field.title,\n        buttonText = field.buttonText,\n        buttonIcon = field.buttonIcon,\n        listType = field.listType,\n        decoration = field.decoration,\n        onSelectionChanged = field.onSelectionChanged,\n        onConfirm = field.onConfirm,\n        chipDisplay = field.chipDisplay,\n        initialValue = field.initialValue,\n        searchable = field.searchable,\n        confirmText = field.confirmText,\n        cancelText = field.cancelText,\n        barrierColor = field.barrierColor,\n        selectedColor = field.selectedColor,\n        dialogHeight = field.dialogHeight,\n        dialogWidth = field.dialogWidth,\n        searchHint = field.searchHint,\n        colorator = field.colorator,\n        backgroundColor = field.backgroundColor,\n        unselectedColor = field.unselectedColor,\n        searchIcon = field.searchIcon,\n        closeSearchIcon = field.closeSearchIcon,\n        itemsTextStyle = field.itemsTextStyle,\n        searchHintStyle = field.searchHintStyle,\n        searchTextStyle = field.searchTextStyle,\n        selectedItemsTextStyle = field.selectedItemsTextStyle,\n        separateSelectedItems = field.separateSelectedItems,\n        checkColor = field.checkColor,\n        isDismissible = field.isDismissible,\n        state = state;\n\n  @override\n  __MultiSelectDialogFieldViewState createState() =>\n      __MultiSelectDialogFieldViewState<V>();\n}\n\nclass __MultiSelectDialogFieldViewState<V>\n    extends State<_MultiSelectDialogFieldView<V>> {\n  List<V> _selectedItems = [];\n\n  @override\n  void initState() {\n    super.initState();\n    _selectedItems.addAll(widget.initialValue);\n  }\n\n  @override\n  void didUpdateWidget(_MultiSelectDialogFieldView<V> oldWidget) {\n    super.didUpdateWidget(oldWidget);\n\n    if (oldWidget.initialValue != widget.initialValue) {\n      _selectedItems = [];\n      _selectedItems.addAll(widget.initialValue);\n\n      WidgetsBinding.instance.addPostFrameCallback((_) {\n        widget.state!.didChange(_selectedItems);\n      });\n    }\n  }\n\n  Widget _buildInheritedChipDisplay() {\n    List<MultiSelectItem<V>?> chipDisplayItems = [];\n    chipDisplayItems = _selectedItems\n        .map((e) =>\n            widget.items.firstWhereOrNull((element) => e == element.value))\n        .toList();\n    chipDisplayItems.removeWhere((element) => element == null);\n    if (widget.chipDisplay != null) {\n      // if user has specified a chipDisplay, use its params\n      if (widget.chipDisplay!.disabled!) {\n        return Container();\n      } else {\n        return MultiSelectChipDisplay<V>(\n          items: chipDisplayItems,\n          colorator: widget.chipDisplay!.colorator ?? widget.colorator,\n          onTap: (item) {\n            List<V>? newValues;\n            if (widget.chipDisplay!.onTap != null) {\n              dynamic result = widget.chipDisplay!.onTap!(item);\n              if (result is List<V>) newValues = result;\n            }\n            if (newValues != null) {\n              _selectedItems = newValues;\n              if (widget.state != null) {\n                widget.state!.didChange(_selectedItems);\n              }\n            }\n          },\n          decoration: widget.chipDisplay!.decoration,\n          chipColor: widget.chipDisplay!.chipColor ??\n              ((widget.selectedColor != null &&\n                      widget.selectedColor != Colors.transparent)\n                  ? widget.selectedColor!.withOpacity(0.35)\n                  : null),\n          alignment: widget.chipDisplay!.alignment,\n          textStyle: widget.chipDisplay!.textStyle,\n          icon: widget.chipDisplay!.icon,\n          shape: widget.chipDisplay!.shape,\n          scroll: widget.chipDisplay!.scroll,\n          scrollBar: widget.chipDisplay!.scrollBar,\n          height: widget.chipDisplay!.height,\n          chipWidth: widget.chipDisplay!.chipWidth,\n        );\n      }\n    } else {\n      // user didn't specify a chipDisplay, build the default\n      return MultiSelectChipDisplay<V>(\n        items: chipDisplayItems,\n        colorator: widget.colorator,\n        chipColor: (widget.selectedColor != null &&\n                widget.selectedColor != Colors.transparent)\n            ? widget.selectedColor!.withOpacity(0.35)\n            : null,\n      );\n    }\n  }\n\n  /// Calls showDialog() and renders a MultiSelectDialog.\n  _showDialog(BuildContext ctx) async {\n    await showDialog(\n      barrierColor: widget.barrierColor,\n      barrierDismissible: widget.isDismissible,\n      context: context,\n      builder: (ctx) {\n        return MultiSelectDialog<V>(\n          checkColor: widget.checkColor,\n          selectedItemsTextStyle: widget.selectedItemsTextStyle,\n          searchHintStyle: widget.searchHintStyle,\n          searchTextStyle: widget.searchTextStyle,\n          itemsTextStyle: widget.itemsTextStyle,\n          searchIcon: widget.searchIcon,\n          closeSearchIcon: widget.closeSearchIcon,\n          unselectedColor: widget.unselectedColor,\n          backgroundColor: widget.backgroundColor,\n          colorator: widget.colorator,\n          searchHint: widget.searchHint,\n          selectedColor: widget.selectedColor,\n          onSelectionChanged: widget.onSelectionChanged,\n          height: widget.dialogHeight,\n          width: widget.dialogWidth,\n          listType: widget.listType,\n          items: widget.items,\n          title: widget.title ?? const Text(\"Select\"),\n          initialValue: _selectedItems,\n          searchable: widget.searchable ?? false,\n          confirmText: widget.confirmText,\n          cancelText: widget.cancelText,\n          separateSelectedItems: widget.separateSelectedItems,\n          onConfirm: (selected) {\n            _selectedItems = selected;\n            if (widget.state != null) {\n              widget.state!.didChange(_selectedItems);\n            }\n            if (widget.onConfirm != null) widget.onConfirm!(_selectedItems);\n          },\n        );\n      },\n    );\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      mainAxisAlignment: MainAxisAlignment.start,\n      children: <Widget>[\n        InkWell(\n          onTap: () {\n            _showDialog(context);\n          },\n          child: Container(\n            decoration: widget.state != null\n                ? widget.decoration ??\n                    BoxDecoration(\n                      border: Border(\n                        bottom: BorderSide(\n                          color: widget.state != null && widget.state!.hasError\n                              ? Colors.red.shade800.withOpacity(0.6)\n                              : _selectedItems.isNotEmpty\n                                  ? (widget.selectedColor != null &&\n                                          widget.selectedColor !=\n                                              Colors.transparent)\n                                      ? widget.selectedColor!\n                                      : Theme.of(context).primaryColor\n                                  : Colors.black45,\n                          width: _selectedItems.isNotEmpty\n                              ? (widget.state != null && widget.state!.hasError)\n                                  ? 1.4\n                                  : 1.8\n                              : 1.2,\n                        ),\n                      ),\n                    )\n                : widget.decoration,\n            padding: const EdgeInsets.all(10),\n            child: Row(\n              mainAxisAlignment: MainAxisAlignment.spaceBetween,\n              children: <Widget>[\n                widget.buttonText ?? const Text(\"Select\"),\n                widget.buttonIcon ?? const Icon(Icons.arrow_downward),\n              ],\n            ),\n          ),\n        ),\n        _buildInheritedChipDisplay(),\n        widget.state != null && widget.state!.hasError\n            ? const SizedBox(height: 5)\n            : Container(),\n        widget.state != null && widget.state!.hasError\n            ? Row(\n                children: <Widget>[\n                  Padding(\n                    padding: const EdgeInsets.only(left: 4),\n                    child: Text(\n                      widget.state!.errorText!,\n                      style: TextStyle(\n                        color: Colors.red[800],\n                        fontSize: 12.5,\n                      ),\n                    ),\n                  ),\n                ],\n              )\n            : Container(),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/multi_select_flutter.dart",
    "content": "export 'util/multi_select_item.dart';\nexport 'util/multi_select_list_type.dart';\nexport 'util/multi_select_actions.dart';\nexport 'dialog/mult_select_dialog.dart';\nexport 'dialog/multi_select_dialog_field.dart';\nexport 'bottom_sheet/multi_select_bottom_sheet.dart';\nexport 'bottom_sheet/multi_select_bottom_sheet_field.dart';\nexport 'chip_display/multi_select_chip_display.dart';\nexport 'chip_field/multi_select_chip_field.dart';\nexport 'util/horizontal_scrollbar.dart';\n"
  },
  {
    "path": "lib/util/horizontal_scrollbar.dart",
    "content": "class HorizontalScrollBar {\n  final bool isAlwaysShown;\n\n  HorizontalScrollBar({this.isAlwaysShown = false});\n}\n"
  },
  {
    "path": "lib/util/multi_select_actions.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'multi_select_item.dart';\n\n/// Contains common actions that are used by different multi select classes.\nclass MultiSelectActions<T> {\n  List<T> onItemCheckedChange(\n      List<T> selectedValues, T itemValue, bool checked) {\n    if (checked) {\n      selectedValues.add(itemValue);\n    } else {\n      selectedValues.remove(itemValue);\n    }\n    return selectedValues;\n  }\n\n  /// Pops the dialog from the navigation stack and returns the initially selected values.\n  void onCancelTap(BuildContext ctx, List<T> initiallySelectedValues) {\n    Navigator.pop(ctx, initiallySelectedValues);\n  }\n\n  /// Pops the dialog from the navigation stack and returns the selected values.\n  /// Calls the onConfirm function if one was provided.\n  void onConfirmTap(\n      BuildContext ctx, List<T> selectedValues, Function(List<T>)? onConfirm) {\n    Navigator.pop(ctx, selectedValues);\n    if (onConfirm != null) {\n      onConfirm(selectedValues);\n    }\n  }\n\n  /// Accepts the search query, and the original list of items.\n  /// If the search query is valid, return a filtered list, otherwise return the original list.\n  List<MultiSelectItem<T>> updateSearchQuery(\n      String? val, List<MultiSelectItem<T>> allItems) {\n    if (val != null && val.trim().isNotEmpty) {\n      List<MultiSelectItem<T>> filteredItems = [];\n      for (var item in allItems) {\n        if (item.label.toLowerCase().contains(val.toLowerCase())) {\n          filteredItems.add(item);\n        }\n      }\n      return filteredItems;\n    } else {\n      return allItems;\n    }\n  }\n\n  /// Toggles the search field.\n  bool onSearchTap(bool showSearch) {\n    return !showSearch;\n  }\n\n  List<MultiSelectItem<T>> separateSelected(List<MultiSelectItem<T>> list) {\n    List<MultiSelectItem<T>> _selectedItems = [];\n    List<MultiSelectItem<T>> _nonSelectedItems = [];\n\n    _nonSelectedItems.addAll(list.where((element) => !element.selected));\n    _nonSelectedItems.sort((a, b) => a.label.compareTo(b.label));\n    _selectedItems.addAll(list.where((element) => element.selected));\n    _selectedItems.sort((a, b) => a.label.compareTo(b.label));\n\n    return [..._selectedItems, ..._nonSelectedItems];\n  }\n}\n"
  },
  {
    "path": "lib/util/multi_select_item.dart",
    "content": "/// A model class used to represent a selectable item.\nclass MultiSelectItem<T> {\n  final T value;\n  final String label;\n  bool selected = false;\n\n  MultiSelectItem(this.value, this.label);\n}\n"
  },
  {
    "path": "lib/util/multi_select_list_type.dart",
    "content": "/// Used by MultiSelectDialog and MultiSelectBottomSheet to determine which type of list to render.\nenum MultiSelectListType { LIST, CHIP }\n"
  },
  {
    "path": "pubspec.yaml",
    "content": "name: multi_select_flutter\ndescription: A flexible multi select package for Flutter. Make multi select widgets the way you want.\nversion: 4.1.3\nrepository: https://github.com/CHB61/flutter-multi-select\nissue_tracker: https://github.com/CHB61/flutter-multi-select\ndocumentation: https://github.com/CHB61/flutter-multi-select\nhomepage: https://github.com/CHB61/flutter-multi-select\n\nenvironment:\n  sdk: '>=2.12.0 <3.0.0'\n\ndependencies:\n  flutter:\n    sdk: flutter\n  collection: ^1.15.0\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n# For information on the generic Dart part of this file, see the\n# following page: https://dart.dev/tools/pub/pubspec\n\n# The following section is specific to Flutter.\nflutter:\n\n  # To add assets to your package, add an assets section, like this:\n  # assets:\n  #   - images/a_dot_burr.jpeg\n  #   - images/a_dot_ham.jpeg\n  #\n  # For details regarding assets in packages, see\n  # https://flutter.dev/assets-and-images/#from-packages\n  #\n  # An image asset can refer to one or more resolution-specific \"variants\", see\n  # https://flutter.dev/assets-and-images/#resolution-aware.\n\n  # To add custom fonts to your package, add a fonts section here,\n  # in this \"flutter\" section. Each entry in this list should have a\n  # \"family\" key with the font family name, and a \"fonts\" key with a\n  # list giving the asset and other descriptors for the font. For\n  # example:\n  # fonts:\n  #   - family: Schyler\n  #     fonts:\n  #       - asset: fonts/Schyler-Regular.ttf\n  #       - asset: fonts/Schyler-Italic.ttf\n  #         style: italic\n  #   - family: Trajan Pro\n  #     fonts:\n  #       - asset: fonts/TrajanPro.ttf\n  #       - asset: fonts/TrajanPro_Bold.ttf\n  #         weight: 700\n  #\n  # For details regarding fonts in packages, see\n  # https://flutter.dev/custom-fonts/#from-packages\n"
  },
  {
    "path": "test/multi_select_flutter_test.dart",
    "content": "// import 'package:flutter_test/flutter_test.dart';\n// import 'package:flutter_multi_select/flutter_multi_select.dart';\n\nvoid main() {\n\n}\n"
  }
]