From 69dff4ca411a1434621b67e2f5489695cc5a55d3 Mon Sep 17 00:00:00 2001 From: Isaque Neves Date: Wed, 31 Jan 2024 22:27:14 -0300 Subject: [PATCH] refactoring so that the behavior is similar to CorelDraw and Photoshop and migration to angular 8 and dart 3.2, removal of dependencies on outdated packages and angular_components --- CHANGELOG.md | 4 + build.yaml => build.yaml.old | 0 example/{build.yaml => build.yaml.old} | 0 example/lib/app_component.dart | 59 --- example/lib/{ => src}/app_component.css | 0 example/lib/src/app_component.dart | 15 + example/lib/src/app_component.html | 11 + example/main.dart | 11 - example/pubspec.lock | 616 +++++++++++++--------- example/pubspec.yaml | 31 +- example/{ => web}/index.html | 2 +- example/web/main.dart | 9 + example/{ => web}/styles.css | 0 lib/builder.dart | 8 +- lib/src/color_picker.dart | 332 ++++++------ lib/src/color_picker.html | 46 +- lib/src/color_picker.scss | 53 +- lib/src/deps/color/hsl.dart | 228 ++++++++ lib/src/deps/color/hsv.dart | 195 +++++++ lib/src/deps/color/lib_colors.dart | 77 +++ lib/src/deps/color/parser.dart | 35 ++ lib/src/deps/color/rgb.dart | 317 +++++++++++ lib/src/deps/color/utils/hex.dart | 78 +++ lib/src/deps/color/utils/names.dart | 308 +++++++++++ lib/src/deps/color/utils/num.dart | 7 + lib/src/deps/deferred_content.dart | 157 ++++++ lib/src/deps/deferred_content_aware.dart | 12 + lib/src/deps/dispose/dispose_angular.dart | 22 + lib/src/deps/dispose/generic.dart | 492 +++++++++++++++++ lib/src/deps/dispose/interval.dart | 73 +++ lib/src/deps/disposer.dart | 189 +++++++ lib/src/deps/tuple.dart | 463 ++++++++++++++++ pubspec.lock | 616 +++++++++++++--------- pubspec.yaml | 32 +- 34 files changed, 3702 insertions(+), 796 deletions(-) rename build.yaml => build.yaml.old (100%) rename example/{build.yaml => build.yaml.old} (100%) delete mode 100644 example/lib/app_component.dart rename example/lib/{ => src}/app_component.css (100%) create mode 100644 example/lib/src/app_component.dart create mode 100644 example/lib/src/app_component.html delete mode 100644 example/main.dart rename example/{ => web}/index.html (90%) create mode 100644 example/web/main.dart rename example/{ => web}/styles.css (100%) create mode 100644 lib/src/deps/color/hsl.dart create mode 100644 lib/src/deps/color/hsv.dart create mode 100644 lib/src/deps/color/lib_colors.dart create mode 100644 lib/src/deps/color/parser.dart create mode 100644 lib/src/deps/color/rgb.dart create mode 100644 lib/src/deps/color/utils/hex.dart create mode 100644 lib/src/deps/color/utils/names.dart create mode 100644 lib/src/deps/color/utils/num.dart create mode 100644 lib/src/deps/deferred_content.dart create mode 100644 lib/src/deps/deferred_content_aware.dart create mode 100644 lib/src/deps/dispose/dispose_angular.dart create mode 100644 lib/src/deps/dispose/generic.dart create mode 100644 lib/src/deps/dispose/interval.dart create mode 100644 lib/src/deps/disposer.dart create mode 100644 lib/src/deps/tuple.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 38a2163..e1d65fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,7 @@ - Sdk constraint - Doc on component properties + +## 1.0.0 + +- refactoring so that the behavior is similar to CorelDraw and Photoshop and migration to angular 8 and dart 3.2, removal of dependencies on outdated packages and angular_components diff --git a/build.yaml b/build.yaml.old similarity index 100% rename from build.yaml rename to build.yaml.old diff --git a/example/build.yaml b/example/build.yaml.old similarity index 100% rename from example/build.yaml rename to example/build.yaml.old diff --git a/example/lib/app_component.dart b/example/lib/app_component.dart deleted file mode 100644 index 3a9a7f6..0000000 --- a/example/lib/app_component.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:angular/angular.dart'; -import 'package:angular_components/angular_components.dart'; -import 'package:ng_color_picker/ng_color_picker.dart'; - -@Component( - selector: 'ng-color-picker-example', - template: r''' -
Chosen color: {{css}}
-
- -
- - {{showPopup ? 'Close' : 'Open'}} Popup - - - - -
-
-
-
- Simple color picker for AngularDart. - GitHub - Pub -
- ''', - directives: [ - coreDirectives, - ColorPickerComponent, - MaterialButtonComponent, - MaterialPopupComponent, - PopupSourceDirective, - ], - providers: [popupBindings], - changeDetection: ChangeDetectionStrategy.OnPush, - styleUrls: ['app_component.css'], -) -class AppComponent { - String css = 'rgba(85, 73, 172, 1)'; - bool showPopup = false; - - final popupPos = [RelativePosition.AdjacentRight, - RelativePosition.OffsetBottomRight]; - - ColorPickerComponent? _popupPicker; - - @ViewChild('popupPicker') - set popupPicker(ColorPickerComponent picker) => _popupPicker; - - ColorPickerComponent get popupPicker => _popupPicker!; -} diff --git a/example/lib/app_component.css b/example/lib/src/app_component.css similarity index 100% rename from example/lib/app_component.css rename to example/lib/src/app_component.css diff --git a/example/lib/src/app_component.dart b/example/lib/src/app_component.dart new file mode 100644 index 0000000..5bb5858 --- /dev/null +++ b/example/lib/src/app_component.dart @@ -0,0 +1,15 @@ +import 'package:ngdart/angular.dart'; +import 'package:ng_color_picker/ng_color_picker.dart'; + +@Component( + selector: 'my-app', + templateUrl: 'app_component.html', + directives: [ + coreDirectives, + ColorPickerComponent, + ], + styleUrls: ['app_component.css'], +) +class AppComponent { + String css = 'rgba(85, 73, 172, 1)'; +} diff --git a/example/lib/src/app_component.html b/example/lib/src/app_component.html new file mode 100644 index 0000000..f774f1b --- /dev/null +++ b/example/lib/src/app_component.html @@ -0,0 +1,11 @@ +
Chosen color: {{css}}
+
+ + +
+
+
+ Simple color picker for AngularDart. + GitHub + Pub +
\ No newline at end of file diff --git a/example/main.dart b/example/main.dart deleted file mode 100644 index d774be2..0000000 --- a/example/main.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:angular/angular.dart'; -import 'lib/app_component.template.dart' as ng_root; -import 'main.template.dart' as ng_main; - -// Visit the github to see the app_component.dart and app_component.html -void main() { - runApp(ng_root.AppComponentNgFactory, createInjector: rootInjector); -} - -@GenerateInjector([]) -final InjectorFactory rootInjector = ng_main.rootInjector$Injector; diff --git a/example/pubspec.lock b/example/pubspec.lock index a8f1dea..b755052 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,670 +5,808 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" source: hosted - version: "30.0.0" + version: "67.0.0" analyzer: - dependency: transitive + dependency: "direct overridden" description: name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "2.7.0" - angular: - dependency: "direct main" - description: - name: angular - url: "https://pub.dartlang.org" - source: hosted - version: "7.0.2" - angular_ast: - dependency: transitive - description: - name: angular_ast - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - angular_compiler: - dependency: transitive - description: - name: angular_compiler - url: "https://pub.dartlang.org" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" source: hosted - version: "2.0.2" - angular_components: - dependency: "direct main" - description: - path: angular_components - ref: "migrated/bug-fix-1" - resolved-ref: "8a965dbc264ce89f8a4125c70eecc7cf3364bc57" - url: "https://github.com/dukefirehawk/angular_components/" - source: git - version: "2.0.0" - angular_forms: - dependency: transitive - description: - name: angular_forms - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.1" + version: "6.4.1" archive: dependency: transitive description: name: archive - url: "https://pub.dartlang.org" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.4.10" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.2" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.8.2" + version: "2.11.0" bazel_worker: dependency: transitive description: name: bazel_worker - url: "https://pub.dartlang.org" + sha256: "6f306845d941808bed2fdbd7db3a39de273a8248a9303cfebf0cfa861372616e" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" build: dependency: transitive description: name: build - url: "https://pub.dartlang.org" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - url: "https://pub.dartlang.org" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - url: "https://pub.dartlang.org" + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "4.0.1" build_modules: - dependency: transitive + dependency: "direct overridden" description: name: build_modules - url: "https://pub.dartlang.org" + sha256: "66f0f746a239ff6cceba9d235a679ec70a6d9037ddddb36a24a0791a639a8486" + url: "https://pub.dev" source: hosted - version: "4.0.3" + version: "5.0.7" build_resolvers: dependency: transitive description: name: build_resolvers - url: "https://pub.dartlang.org" + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - url: "https://pub.dartlang.org" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.4.8" build_runner_core: dependency: transitive description: name: build_runner_core - url: "https://pub.dartlang.org" + sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" + url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "7.3.0" build_test: - dependency: transitive + dependency: "direct dev" description: name: build_test - url: "https://pub.dartlang.org" + sha256: "260dbba934f41b0a42935e9cae1f5731b94f0c3e489dc97bcf8e281265aaa5ae" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.2" build_web_compilers: dependency: "direct dev" description: name: build_web_compilers - url: "https://pub.dartlang.org" + sha256: aad1d705faa53d060e7ccb7855ee74705a8e3d9ea1634e63e362cc2c1bd47afa + url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "4.0.9" built_collection: dependency: transitive description: name: built_collection - url: "https://pub.dartlang.org" + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" source: hosted version: "5.1.1" built_value: dependency: transitive description: name: built_value - url: "https://pub.dartlang.org" + sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6 + url: "https://pub.dev" + source: hosted + version: "8.9.0" + change_notifier: + dependency: "direct main" + description: + name: change_notifier + sha256: "9a50ab5290b93a2f164d20a12998ef10571d57947b47f144296dc53cc24f4f5b" + url: "https://pub.dev" source: hosted - version: "8.1.3" + version: "0.24.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.dartlang.org" + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + url: "https://pub.dev" source: hosted version: "1.3.1" checked_yaml: dependency: transitive description: name: checked_yaml - url: "https://pub.dartlang.org" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" + cli_pkg: + dependency: transitive + description: + name: cli_pkg + sha256: "7b088621eb3d486c17a4122389d8b3f36658450d5a405fa229166b1a71a7ce4a" + url: "https://pub.dev" + source: hosted + version: "2.7.2" cli_repl: dependency: transitive description: name: cli_repl - url: "https://pub.dartlang.org" + sha256: a2ee06d98f211cb960c777519cb3d14e882acd90fe5e078668e3ab4baab0ddd4 + url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.2.3" cli_util: dependency: transitive description: name: cli_util - url: "https://pub.dartlang.org" + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.4.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" code_builder: dependency: transitive description: name: code_builder - url: "https://pub.dartlang.org" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.10.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.18.0" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.1" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.7.2" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.3" csslib: dependency: transitive description: name: csslib - url: "https://pub.dartlang.org" + sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" + url: "https://pub.dev" source: hosted - version: "0.17.1" + version: "0.17.3" dart_internal: dependency: transitive description: name: dart_internal - url: "https://pub.dartlang.org" + sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567" + url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.2.9" dart_style: dependency: transitive description: name: dart_style - url: "https://pub.dartlang.org" + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + url: "https://pub.dev" source: hosted - version: "2.2.0" - dispose: + version: "2.3.4" + ffi: dependency: transitive description: - name: dispose - url: "https://pub.dartlang.org" + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" source: hosted - version: "0.0.7" + version: "2.1.0" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "7.0.0" fixnum: dependency: transitive description: name: fixnum - url: "https://pub.dartlang.org" + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" frontend_server_client: dependency: transitive description: name: frontend_server_client - url: "https://pub.dartlang.org" + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "3.2.0" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.2" graphs: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.1" + grinder: + dependency: transitive + description: + name: grinder + sha256: e1996e485d2b56bb164a8585679758d488fbf567273f51c432c8733fee1f6188 + url: "https://pub.dev" + source: hosted + version: "0.9.5" html: dependency: transitive description: name: html - url: "https://pub.dartlang.org" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" source: hosted - version: "0.15.0" + version: "0.15.4" http: dependency: transitive description: name: http - url: "https://pub.dartlang.org" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + url: "https://pub.dev" source: hosted - version: "0.13.4" + version: "1.2.0" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.2.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" intl: dependency: transitive description: name: intl - url: "https://pub.dartlang.org" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" source: hosted - version: "0.6.3" + version: "0.6.7" json_annotation: dependency: transitive description: name: json_annotation - url: "https://pub.dartlang.org" + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" source: hosted - version: "4.3.0" - lib_colors: - dependency: transitive - description: - path: "../../lib_colors" - relative: true - source: path - version: "1.0.18" + version: "4.8.1" lints: dependency: "direct dev" description: name: lints - url: "https://pub.dartlang.org" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "2.1.1" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.2.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" source: hosted - version: "0.12.11" + version: "0.12.16+1" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.11.0" mime: dependency: transitive description: name: mime - url: "https://pub.dartlang.org" + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.5" + native_synchronization: + dependency: transitive + description: + name: native_synchronization + sha256: ff200fe0a64d733ff7d4dde2005271c297db81007604c8cd21037959858133ab + url: "https://pub.dev" + source: hosted + version: "0.2.0" ng_color_picker: dependency: "direct main" description: path: ".." relative: true source: path - version: "0.0.2" + version: "1.0.0" + ngast: + dependency: transitive + description: + name: ngast + sha256: "681f2099cd8d20868e4309ebd9f2c20596c220c041966a22ce2f7d81b21ec951" + url: "https://pub.dev" + source: hosted + version: "3.0.0-dev.0" + ngcompiler: + dependency: transitive + description: + name: ngcompiler + sha256: "9cd0f122b872cb42c1b6ef5c8f2f6d64eacfdc5d8dbd97a38a4e3346b8d3d0d6" + url: "https://pub.dev" + source: hosted + version: "3.0.0-dev.1" + ngdart: + dependency: "direct main" + description: + name: ngdart + sha256: "0d92d05a9dadef120b0eaee34ffd417f8608066ba0ce1e69958290c08d440b84" + url: "https://pub.dev" + source: hosted + version: "8.0.0-dev.2" + ngforms: + dependency: "direct main" + description: + name: ngforms + sha256: "05c49fc995177d8eccae4fc617576da621ccde62e98f5210f9dbbeefa7448292" + url: "https://pub.dev" + source: hosted + version: "5.0.0-dev.1" + ngrouter: + dependency: "direct main" + description: + name: ngrouter + sha256: f5d8a746c7225a8a6c6c500ba69acb509a1caa195a6262de15563319262c2af0 + url: "https://pub.dev" + source: hosted + version: "4.0.0-dev.1" node_interop: dependency: transitive description: name: node_interop - url: "https://pub.dartlang.org" + sha256: "3af2420c728173806f4378cf89c53ba9f27f7f67792b898561bff9d390deb98e" + url: "https://pub.dev" source: hosted version: "2.1.0" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" source: hosted - version: "2.0.1" - observable: - dependency: transitive - description: - path: "." - ref: HEAD - resolved-ref: "8c49e71daa4c4d41e9103c4c562a8f3e9cecdd61" - url: "https://github.com/google/observable" - source: git - version: "0.24.0-dev" + version: "2.0.2" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.0" - pedantic: + version: "1.9.0" + petitparser: dependency: transitive description: - name: pedantic - url: "https://pub.dartlang.org" + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "6.0.2" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + url: "https://pub.dev" + source: hosted + version: "3.7.4" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.5.1" protobuf: dependency: transitive description: name: protobuf - url: "https://pub.dartlang.org" + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.1.0" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - url: "https://pub.dartlang.org" + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.3" quiver: dependency: transitive description: name: quiver - url: "https://pub.dartlang.org" + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" source: hosted - version: "3.0.1+1" + version: "3.2.1" + retry: + dependency: transitive + description: + name: retry + sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sass: dependency: transitive description: name: sass - url: "https://pub.dartlang.org" + sha256: f5b39a1f2601d5a67d5a83a8f6d03de8418a88f545e108df7e59f100fe8db1dd + url: "https://pub.dev" source: hosted - version: "1.43.4" + version: "1.70.0" sass_builder: - dependency: transitive + dependency: "direct main" description: name: sass_builder - url: "https://pub.dartlang.org" + sha256: "8f714e91a19272b7f0b68a5a100c8c000f3101731288376fdcbfb0e464274eb5" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" scratch_space: dependency: transitive description: name: scratch_space - url: "https://pub.dartlang.org" + sha256: "8510fbff458d733a58fc427057d1ac86303b376d609d6e1bc43f240aad9aa445" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.4" source_gen: dependency: transitive description: name: source_gen - url: "https://pub.dartlang.org" + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.5.0" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" source: hosted - version: "0.10.10" + version: "0.10.12" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" stream_transform: dependency: transitive description: name: stream_transform - url: "https://pub.dartlang.org" + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" test: - dependency: transitive + dependency: "direct dev" description: name: test - url: "https://pub.dartlang.org" + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + url: "https://pub.dev" source: hosted - version: "1.19.3" + version: "1.25.2" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" source: hosted - version: "0.4.7" + version: "0.7.0" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + url: "https://pub.dev" source: hosted - version: "0.4.8" - timing: + version: "0.6.0" + test_process: dependency: transitive description: - name: timing - url: "https://pub.dartlang.org" + name: test_process + sha256: "217f19b538926e4922bdb2a01410100ec4e3beb4cc48eae5ae6b20037b07bbd6" + url: "https://pub.dev" source: hosted - version: "1.0.0" - tuple: + version: "2.1.0" + timing: dependency: transitive description: - name: tuple - url: "https://pub.dartlang.org" + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: a2662fb1f114f4296cf3f5a50786a2d888268d7776cf681aa17d660ffa23b246 + url: "https://pub.dev" source: hosted - version: "7.4.0" + version: "14.0.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05" + url: "https://pub.dev" + source: hosted + version: "0.4.2" web_socket_channel: dependency: transitive description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.4.3" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.2.1" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" sdks: - dart: ">=2.14.0 <2.16.0" + dart: ">=3.2.0 <3.3.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bf274ee..b5994c6 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,20 +4,29 @@ description: Color picker example #homepage: https://www.example.com environment: - sdk: '>=2.12.0 <3.0.0' + sdk: ^3.2.0 dependencies: - angular: ^7.0.2 - angular_components: - git: - url: https://github.com/dukefirehawk/angular_components/ - path: angular_components - ref: migrated/bug-fix-1 + ngdart: ^8.0.0-dev.2 + ngrouter: ^4.0.0-dev.1 + ngforms: ^5.0.0-dev.1 + sass_builder: ^2.1.4 + change_notifier: ^0.24.0 ng_color_picker: path: ../ -dev_dependencies: - build_runner: ^2.1.5 - build_web_compilers: ^3.2.1 - lints: ^1.0.1 +dev_dependencies: + build_runner: ^2.1.2 + build_test: ^2.1.3 + build_web_compilers: ^4.0.0 + lints: ^2.1.0 + test: ^1.24.0 + +dependency_overrides: + build_modules: ^5.0.0 + analyzer: ^6.4.1 + + + + diff --git a/example/index.html b/example/web/index.html similarity index 90% rename from example/index.html rename to example/web/index.html index 7f2a78a..389c409 100644 --- a/example/index.html +++ b/example/web/index.html @@ -14,7 +14,7 @@ - + diff --git a/example/web/main.dart b/example/web/main.dart new file mode 100644 index 0000000..8023639 --- /dev/null +++ b/example/web/main.dart @@ -0,0 +1,9 @@ +import 'package:ng_color_picker_example/src/app_component.template.dart' as ng; +import 'package:ngdart/angular.dart'; + +import 'main.template.dart' as self; + +// Visit the github to see the app_component.dart and app_component.html +void main() { + runApp(ng.AppComponentNgFactory); +} diff --git a/example/styles.css b/example/web/styles.css similarity index 100% rename from example/styles.css rename to example/web/styles.css diff --git a/lib/builder.dart b/lib/builder.dart index b91693a..1874032 100644 --- a/lib/builder.dart +++ b/lib/builder.dart @@ -1,5 +1,5 @@ -import 'package:build/build.dart'; -import 'package:sass_builder/sass_builder.dart'; +// import 'package:build/build.dart'; +// import 'package:sass_builder/sass_builder.dart'; -Builder scssBuilder(BuilderOptions options) => - SassBuilder(outputExtension: '.scss.css'); +// Builder scssBuilder(BuilderOptions options) => +// SassBuilder(outputExtension: '.scss.css'); diff --git a/lib/src/color_picker.dart b/lib/src/color_picker.dart index 3044e10..c633152 100644 --- a/lib/src/color_picker.dart +++ b/lib/src/color_picker.dart @@ -1,11 +1,13 @@ +// ignore_for_file: constant_identifier_names import 'dart:async'; import 'dart:html'; import 'dart:math' as math; - -import 'package:angular/angular.dart'; -import 'package:angular_components/angular_components.dart'; -import 'package:dispose/dispose.dart'; -import 'package:lib_colors/lib_colors.dart'; +import 'package:ngdart/angular.dart'; +import 'package:ngforms/ngforms.dart'; +import 'deps/color/lib_colors.dart'; +import 'deps/dispose/generic.dart'; +//import 'deps/dispose/interval.dart'; +import 'deps/deferred_content_aware.dart'; const RGB_MAX = 255.0; const HUE_MAX = 360.0; @@ -14,7 +16,7 @@ const pointerHalfSize = 10; const alphaGutter = 8, alphaHalfGutter = 4; extension PickerHsv on Hsv { - String toCss() => toRgb!.toCss(); + String toCss() => toRgb.toCss(); } extension PickerRgb on Rgb { @@ -28,54 +30,35 @@ extension PickerRgb on Rgb { @Component( selector: 'color-picker', templateUrl: 'color_picker.html', - styleUrls: ['color_picker.scss.css'], - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrls: ['color_picker.css'], + changeDetection: ChangeDetectionStrategy.onPush, directives: [ coreDirectives, - materialInputDirectives, - MaterialIconComponent, - MaterialRippleComponent, - MaterialInputComponent + formDirectives, ]) -class ColorPickerComponent with Disposable implements OnInit { +class ColorPickerComponent with Disposable implements OnInit, OnDestroy { final StreamController _rgbChange = StreamController(); final StreamController _cssChange = StreamController(); final Rgb defaultColor = Rgb(r: 255, g: 255, b: 255, a: 1); final ChangeDetectorRef _cd; + + // ignore: unused_field final NgZone _zone; + // ignore: unused_field final DeferredContentAware? _parent; - Hsv? _currentHsv; - bool _initiated = false; - @HostBinding('class.initiated') - bool get initiated => _initiated; + Hsv? _currentHsv; - bool _rectOk = false; - @HostBinding('class.rectOk') - bool get rectOk => !_observeResize || _rectOk; + StreamSubscription? ssMousemove; + StreamSubscription? ssMousedown; + StreamSubscription? ssMouseup; ColorPickerComponent(this._cd, this._zone, @Optional() this._parent) { - final par = _parent; - - if (par != null) { - _observeResize = true; - - each(par.contentVisible, (bool visible) { - _zone.runAfterChangesObserved(() { - _rectOk = visible; - - if (visible) { - _refresh(); - } - - _cd.markForCheck(); - }); - }); - } + ssMousemove = document.body?.onMouseMove.listen(onMouseMove); + ssMousedown = document.body?.onMouseDown.listen(onMousedown); + ssMouseup = document.body?.onMouseUp.listen(onMouseup); } - bool _observeResize = false; - Rgb? _rgb; @Input() set rgb(Rgb? value) { @@ -86,8 +69,6 @@ class ColorPickerComponent with Disposable implements OnInit { Rgb? get rgb => _rgb; - late StreamedIntervalTimer _saturationBeat; - /// Makes the cursors invisible until manually call [initiate]. @Input() bool manualInitiate = false; @@ -111,6 +92,7 @@ class ColorPickerComponent with Disposable implements OnInit { String? _inputCss; String? get inputCss => _inputCss; + /// CSS input: rgba() or #hex. @Input('css') set inputCss(String? value) { @@ -121,11 +103,9 @@ class ColorPickerComponent with Disposable implements OnInit { final n = Rgb.parse(value); rgb = n; - _currentHsv = RGBtoHSV(_rgb!.clone(a: 1)); + _currentHsv = rgbTohsv(_rgb!.clone(a: 1)); - if (_initiated) { - _refresh(); - } + _refresh(); } catch (e) { _invalidCss = true; _inputError = ' '; @@ -140,50 +120,33 @@ class ColorPickerComponent with Disposable implements OnInit { String? _hueCss; String? get hueCss => _hueCss; - String? _huePos; - String? get huePos => _huePos; + late String huePos; - String? _alphaPos, _alphaOriginPos; - String? get alphaPos => _alphaPos; + String? alphaOriginPos; + String? alphaPos; - String? _saturationLeft; - String? get saturationLeft => _saturationLeft; + String? saturationLeft; - String? _saturationTop; - String? get saturationTop => _saturationTop; + String? saturationTop; - Hsv? _hsv; + late Hsv _hsv; - DivElement? _hue; @ViewChild('hue') - set hue(DivElement? element) => _hue = element; - DivElement get hue => _hue!; + DivElement? hue; - DivElement? _saturation; @ViewChild('saturation') - set saturation(DivElement? element) => _saturation = element; - DivElement get saturation => _saturation!; + DivElement? saturation; - DivElement? _alpha; @ViewChild('alpha') - set alpha(DivElement? element) => _alpha = element; - DivElement get alpha => _alpha!; + DivElement? alpha; + num alphaValue = 1; + num hueValue = 1; - MaterialRippleComponent? _saturationRipple; - @ViewChild('saturationRipple') - set saturationRipple(MaterialRippleComponent? element) => - _saturationRipple = element; - MaterialRippleComponent get saturationRipple => _saturationRipple!; + Rectangle? get saturationRect => saturation!.getBoundingClientRect(); + Rectangle? get hueRect => hue?.getBoundingClientRect(); + Rectangle? get alphaRect => alpha?.getBoundingClientRect(); - MaterialRippleComponent? _selectedRipple; - @ViewChild('selectedRipple') - set selectedRipple(MaterialRippleComponent? element) => - _selectedRipple = element; - MaterialRippleComponent get selectedRipple => _selectedRipple!; - - Rectangle? _hueRect, _saturationRect, _alphaRect; - - Hsv RGBtoHSV(Rgb rgb) { + Hsv rgbTohsv(Rgb rgb) { // It converts [0,255] format, to [0,1] final r = (rgb.r == RGB_MAX) ? 1 : (rgb.r % RGB_MAX / (RGB_MAX)); final g = (rgb.g == RGB_MAX) ? 1 : (rgb.g % RGB_MAX / (RGB_MAX)); @@ -212,38 +175,50 @@ class ColorPickerComponent with Disposable implements OnInit { return Hsv(h: h, s: (s * SV_MAX).round(), v: (v * SV_MAX).round()); } - void saturationMove(MouseEvent? event) { - if (event == null) { - return; + void updateSaturation(num posX, num posY) { + if (posX < 1) { + posX = 0; + } + if (posX > saturationRect!.width) { + posX = saturationRect!.width; + } + if (posY < 1) { + posY = 0; + } + if (posY > saturationRect!.height) { + posY = saturationRect!.height; } - _saturationRect ??= saturation.getBoundingClientRect(); - - final posX = event.page.x - _saturationRect!.left; - final sraw = posX / _saturationRect!.width; - final posY = event.page.y - _saturationRect!.top; - final vraw = posY / _saturationRect!.height; + final sraw = posX / saturationRect!.width; + final vraw = posY / saturationRect!.height; - _saturationLeft = '${posX - pointerHalfSize}px'; - _saturationTop = '${posY - pointerHalfSize}px'; + saturationLeft = '${posX - pointerHalfSize}px'; + saturationTop = '${posY - pointerHalfSize}px'; - final h = (_hsv ?? RGBtoHSV(_rgb!)).h; + //final h = _hsv.h; final num s = math.max(sraw, 0) * SV_MAX; final num v = (1 - math.max(vraw, 0)) * SV_MAX; - _hsv = Hsv( - h: h, - s: s, - v: v, - ); + //_hsv = Hsv(h: h, s: s, v: v, a: alphaValue); + _hsv.s = s; + _hsv.v = v; - _inputCss = _css = _hsv!.clone(a: rgb!.a).toCss(); - _cd.markForCheck(); + updateInputVal(); } - void hueClick(MouseEvent event) { - click(event); - _currentHsv = _hsv!.clone(a: 1); + void _calcSaturationPos() { + lastSaturationPosX = ((_hsv.s / SV_MAX) * saturationRect!.width); + lastSaturationPosY = ((1 - (_hsv.v / SV_MAX)) * saturationRect!.height); + + saturationLeft = '${lastSaturationPosX - pointerHalfSize}px'; + saturationTop = '${lastSaturationPosY - pointerHalfSize}px'; + } + + void saturationClick(MouseEvent event) { + final posX = event.page.x - saturationRect!.left; + final posY = event.page.y - saturationRect!.top; + updateSaturation(posX, posY); + //_add((_hsv!.clone(a: rgb!.a)).toRgb); } void _add(Rgb newRgb) { @@ -252,69 +227,105 @@ class ColorPickerComponent with Disposable implements OnInit { _cssChange.add(newRgb.toCss()); } - void click(MouseEvent event, {bool ripple = true}) { - _add((_hsv!.clone(a: rgb!.a)).toRgb!); - - if (ripple) { - saturationRipple.createRipple(event.client.x as int, event.client.y as int); - } - - selectedRipple.createRipple(event.client.x as int, event.client.y as int); - } - @HostListener('mouseout', [r'$event']) void sliderOut(MouseEvent event) { - _refresh(); + //_refresh(); } @HostListener('mousemove', [r'$event']) void checkOut(MouseEvent event) { - if (_hueRect != null && ![saturation, hue, alpha].contains(event.target)) { - _refresh(); + // if (hueRect != null && ![saturation, hue, alpha].contains(event.target)) { + // _refresh(); + // } + } + + bool isHueMove = false; + bool isAlphaMove = false; + bool isSaturationMove = false; + num lastSaturationPosX = 0; + num lastSaturationPosY = 0; + + /// global mouse move event handler + void onMouseMove(MouseEvent event) { + if (isHueMove) { + final posX = event.page.x - hueRect!.left; + updateHue(posX); + //updateSaturation(lastSaturationPosX, lastSaturationPosY); + } + if (isAlphaMove) { + final posX = event.page.x - (alphaRect!.left + alphaHalfGutter); + updateAlpha(posX); + } + if (isSaturationMove) { + lastSaturationPosX = event.page.x - saturationRect!.left; + lastSaturationPosY = event.page.y - saturationRect!.top; + updateSaturation(lastSaturationPosX, lastSaturationPosY); } } - void hueMove(MouseEvent event) { - _hueRect ??= hue.getBoundingClientRect(); - final pos = event.page.x - _hueRect!.left; - final v = pos / _hueRect!.width; + void onMousedown(MouseEvent event) { + isHueMove = event.target == hue; + isAlphaMove = event.target == alpha; + isSaturationMove = event.target == saturation; + } - _huePos = '${pos - pointerHalfSize}px'; - _hsv = Hsv(h: math.max(v, -0), s: 100, v: 100); - _calcSaturationPos(); + void onMouseup(MouseEvent event) { + isHueMove = false; + isAlphaMove = false; + isSaturationMove = false; + } - _hueCss = _hsv!.toCss(); - _inputCss = _css = _hsv!.clone(a: rgb!.a).toCss(); + void hueClick(MouseEvent event) { + final pos = event.page.x - hueRect!.left; + updateHue(pos); + } + + void updateHue(num posX) { + if (posX < 1) { + posX = 0; + } + if (posX > hueRect!.width) { + posX = hueRect!.width; + } + final v = posX / hueRect!.width; + huePos = '${posX - pointerHalfSize}px'; + + hueValue = math.max(v, -0); + _hsv.h = hueValue; + + _hueCss = Hsv(h: hueValue, s: 100, v: 100).toCss(); + updateInputVal(); } void alphaClick(MouseEvent event) { - _alphaOriginPos = alphaPos; - _add(alphaMove(event)); + alphaOriginPos = alphaPos; + final pos = event.page.x - (alphaRect!.left + alphaHalfGutter); + updateAlpha(pos); } - Rgb alphaMove(MouseEvent event) { - _alphaRect ??= alpha.getBoundingClientRect(); - final pos = event.page.x - (_alphaRect!.left + alphaHalfGutter); - var a = pos / (_alphaRect!.width - alphaGutter); + void updateAlpha(num posX) { + if (posX < 1) { + posX = 0; + } + if (posX > alphaRect!.width) { + posX = alphaRect!.width; + } + + var a = posX / (alphaRect!.width - alphaGutter); final mod = math.pow(10.0, 2); a = (a * mod).round().toDouble() / mod; - _alphaPos = '${pos - pointerHalfSize}px'; - - final h2 = _rgb!.clone(a: 1 - math.min(math.max(a, 0), 1)); - - _inputCss = _css = h2.toCss(); + alphaPos = '${posX - pointerHalfSize}px'; - return h2; + alphaValue = 1 - math.min(math.max(a, 0), 1); + _hsv.a = alphaValue; + updateInputVal(); } - void _calcSaturationPos() { - _saturationRect ??= saturation.getBoundingClientRect(); - - _saturationLeft = - '${((_hsv!.s / SV_MAX) * _saturationRect!.width) - pointerHalfSize}px'; - _saturationTop = - '${((1 - (_hsv!.v / SV_MAX)) * _saturationRect!.height) - pointerHalfSize}px'; + void updateInputVal() { + _inputCss = _css = _hsv.toCss(); + _cd.markForCheck(); + _add(_hsv.toRgb); } void refresh() { @@ -324,17 +335,14 @@ class ColorPickerComponent with Disposable implements OnInit { void _refresh() { final rgb = _rgb!.clone(a: 1); - final width = hue.getBoundingClientRect().width; - final alphaWidth = - alpha.getBoundingClientRect().width - alphaGutter; + final width = hueRect!.width; + final alphaWidth = alphaRect!.width - alphaGutter; - _clearBeats(); - - _hsv = RGBtoHSV(rgb); + _hsv = rgbTohsv(rgb); _calcSaturationPos(); - _huePos = '${(_hsv!.h * width) - pointerHalfSize}px'; - _alphaPos = _alphaOriginPos ?? + huePos = '${(_hsv.h * width) - pointerHalfSize}px'; + alphaPos = alphaOriginPos ?? '${(((1 - _rgb!.a) * alphaWidth) - pointerHalfSize)}px'; _css = _rgb!.toCss(); @@ -342,37 +350,23 @@ class ColorPickerComponent with Disposable implements OnInit { _inputCss = _css; } - _hueCss = ((_currentHsv ?? _hsv)!.clone() + _hueCss = ((_currentHsv ?? _hsv).clone() ..s = 100 ..v = 100) .toCss(); - - _saturationRect = _alphaRect = _hueRect = null; } @override void ngOnInit() { rgb ??= defaultColor; - _currentHsv = RGBtoHSV(_rgb!.clone(a: 1)); + _currentHsv = rgbTohsv(_rgb!.clone(a: 1)); _refresh(); - - _saturationBeat = streamedInterval(saturation.onMouseMove, - const Duration(milliseconds: 1), saturationMove); - - _initiated = !manualInitiate; } - void _clearBeats() { - if (_initiated) { - _saturationBeat.clear(); - } - } - - void initiate() { - if (!_initiated) { - _initiated = true; - _currentHsv = RGBtoHSV(_rgb!.clone(a: 1)); - refresh(); - } + @override + void ngOnDestroy() { + ssMousemove?.cancel(); + ssMousedown?.cancel(); + ssMouseup?.cancel(); } } diff --git a/lib/src/color_picker.html b/lib/src/color_picker.html index 0d3b0f6..acaab77 100644 --- a/lib/src/color_picker.html +++ b/lib/src/color_picker.html @@ -1,39 +1,27 @@ - -
- -
+
+
-
-
- -
- -
-
- -
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
- - +
+[style.background]="css">{{css}}, {{saturationLeft}}, {{saturationTop}}
--> \ No newline at end of file diff --git a/lib/src/color_picker.scss b/lib/src/color_picker.scss index 289b37f..fc9e918 100644 --- a/lib/src/color_picker.scss +++ b/lib/src/color_picker.scss @@ -49,11 +49,11 @@ &.alpha { width: calc(100% - 6px); - border-left-width: 4px; + border-left-width: 1px; border-left-color: #cdcdcd; - border-right-width: 4px; + border-right-width: 1px; border-right-color: white; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAAQCAYAAAD06IYnAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AIWDwYQlZMa3gAAAWVJREFUaN7tmEGO6jAQRCsOArHgBpyAJYGjcGocxAm4A2IHpmoWE0eBH+ezmFlNvU06shJ3W6VEelWMUQAIIF9f6qZpimsA1LYtS2uF51/u27YVAFZVRUkEoGHdPV/sIcbIEIIkUdI/9Xa7neyv61+SWFUVAVCSct00TWn2fv6u3+Ecfd3tXzy/0+nEUu+SPjo/kqzrmiQpScN6v98XewfA8/lMkiLJ2WxGSUopcT6fM6U0NX9/frfbjev1WtfrlZfLhYfDQQHG/AIOlnGwjINlHCxjHCzjYJm/TJWdCwquJXseFFzGwDNNeiKMOJTO8xQdDQaeB29+K9efeLaBo9J7vdvtJj1RjFFjfiv7qv95tjx/7leSQgh93e1ffMeIp6O+YQjho/N791t1XVOSSI7N//K+4/GoxWLBx+PB5/Op5XLJ+/3OlJJWqxU3m83ovv5iGf8KjYNlHCxjHCzjYBkHy5gf5gusvQU7U37jTAAAAABJRU5ErkJggg=='); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAAQCAYAAAD06IYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFJGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDIgNzkuZjM1NGVmYywgMjAyMy8xMS8wOS0xMjo0MDoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjQgKDIwMjMxMjA3Lm0uMjQyNiA0OTViMmQxKSAgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyNC0wMS0zMVQyMDowNDozNy0wMzowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjQtMDEtMzFUMjA6MDc6MTMtMDM6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjQtMDEtMzFUMjA6MDc6MTMtMDM6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmYzOTBmZGNmLTgwYjktNmM0MC05NTRlLWUxYzJlYzAwOTNjNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpmMzkwZmRjZi04MGI5LTZjNDAtOTU0ZS1lMWMyZWMwMDkzYzQiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpmMzkwZmRjZi04MGI5LTZjNDAtOTU0ZS1lMWMyZWMwMDkzYzQiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmYzOTBmZGNmLTgwYjktNmM0MC05NTRlLWUxYzJlYzAwOTNjNCIgc3RFdnQ6d2hlbj0iMjAyNC0wMS0zMVQyMDowNDozNy0wMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI1LjQgKDIwMjMxMjA3Lm0uMjQyNiA0OTViMmQxKSAgKFdpbmRvd3MpIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlNbMYQAAAFOSURBVGje7ZjJjYQwEEXtwvQNkQMhsERNKCxHIiADDgjEMpTbbgHDJk3f5j/J+CP5+5dRCSTkPM8khJDLIDO0rqqKmqYhpZR8vV7Uti05jiNd16Wu6yhJkrXn1x55nhMjF8Zx1JpnvmcdhuFhrh1lWcppmni99qw0LVrGcXyYazXnyzdkvFrb80ZRdFo7z0VRaI9Zr318b/WSf1q7PT/nsTbejTb5Z3tIk/+pd6+fPD9b+1F9q/Mf7sH5V/XdPT8WAHwdNBZAYwE0FkBjAYDGAmgs8J9RfEnTVARBIHzfF3VdC8/zRBRFl8aiKIRSSvR9r2f+xTMMgyAiPeI4vvRnWaY9vHYcx43m+Uk+e6Zp0vNe3+WXZSnmedaa1+/1k3yG175/b231k/yz2lnf+W3+Ue3M0/rP+KsfbyyATyFAYwE0FgBoLIDGAmgsAL7MD7uppZpkT2c+AAAAAElFTkSuQmCC'); &:before { content: " "; @@ -88,7 +88,7 @@ top: -2px; cursor: default; pointer-events: none; - display: none; + } &.saturation-lightness { @@ -112,26 +112,37 @@ text-align: center; padding: 0 10px; - material-input { - width: 100%; - color: #666; - - ::ng-deep input { - text-align: center; - } - } } &.bordered { - box-shadow: 0 4px 5px 0 rgb(0 0 0 / 14%), - 0 1px 10px 0 rgb(0 0 0 / 12%), 0 2px 4px -1px rgb(0 0 0 / 20%); + // box-shadow: 0 4px 5px 0 rgb(0 0 0 / 14%), + // 0 1px 10px 0 rgb(0 0 0 / 12%), 0 2px 4px -1px rgb(0 0 0 / 20%); + border: solid 1px #6666664d; } +} - &.initiated.rectOk { - .slider { - .cursor { - display: block; - } - } - } +//cursor: url('path-to-image.png'), auto; +input { + border: 1px transparent solid; + outline: none; + box-shadow: none; + padding-block: 1px; + padding-inline: 2px; + padding-bottom: 8px; + font-size: 15px; + color: #666; + text-align: center; + margin: 0; + background-color: transparent; + width: 100%; + border-bottom: 1px transparent solid; + outline: none; +} + +input[type=text]:focus { + border-bottom: 1px #4285f4 solid; } + + + +//---------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/lib/src/deps/color/hsl.dart b/lib/src/deps/color/hsl.dart new file mode 100644 index 0000000..401a4e0 --- /dev/null +++ b/lib/src/deps/color/hsl.dart @@ -0,0 +1,228 @@ +import 'lib_colors.dart'; + +import 'utils/num.dart'; + +class Hsl implements Color { + double _h = 0; + + double _s = 0; + + double _l = 0; + + double _a = 0; + + Hsl({num h = 0, num s = sMax, num l = 50, num a = 1.0}) { + this.h = h; + this.s = s; + this.l = l; + this.a = a; + } + + factory Hsl.parse(String css) { + var match = hslRegExp.matchAsPrefix(css); + if (match != null) { + return Hsl( + h: double.parse(match.group(1)!), + s: double.parse(match.group(2) ?? match.group(3)!), + l: double.parse(match.group(4) ?? match.group(5)!), + ); + } + + match = hslaRegExp.matchAsPrefix(css); + if (match != null) { + return Hsl( + h: double.parse(match.group(1)!), + s: double.parse(match.group(2) ?? match.group(3)!), + l: double.parse(match.group(4) ?? match.group(5)!), + a: double.parse(match.group(6) ?? match.group(7)!), + ); + } + + throw FormatException(); + } + + num get h => _h; + + num get s => _s; + + num get l => _l; + + @override + double get a => _a; + + double get opacity => a / 255; + + set h(num v) { + if (v < hMin || v > hMax) throw ArgumentError.value(v); + _h = v.toDouble(); + } + + set s(num v) { + if (v < sMin || v > sMax) throw ArgumentError.value(v); + _s = v.toDouble(); + } + + set l(num v) { + if (lMin < 0 || v > lMax) throw ArgumentError.value(v); + _l = v.toDouble(); + } + + @override + set a(num v) { + if (v < 0 || v > 1.0) throw ArgumentError.value(v); + _a = v.toDouble(); + } + + @override + void assignRgb(Rgb rgb) { + assignHsl(rgb.toHsl); + } + + @override + void assignHsl(Hsl hsl) { + a = hsl.a; + h = hsl.h; + s = hsl.s; + l = hsl.l; + } + + @override + bool get isDark => brightness < 128.0; + + @override + bool get isLight => !isDark; + + @override + double get brightness => toRgb.brightness; + + @override + void brighten({num percent = 10}) { + assignRgb(toRgb..brighten(percent: percent)); + } + + @override + void lighten({num percent = 10}) { + l = (l + percent).clamp(sMin, sMax); + } + + @override + void darken({num percent = 10}) { + l = (l - percent).clamp(sMin, sMax); + } + + @override + void desaturate({num percent = 10}) { + s = (s - percent).clamp(sMin, sMax); + } + + @override + void saturate({num percent = 10}) { + s = (s + percent).clamp(sMin, sMax); + } + + @override + void greyscale() { + s = 0; + } + + @override + void spin(num degrees) { + final hue = (h + degrees) % 360; + h = hue < 0 ? 360 + hue : hue; + } + + @override + void complement() { + h = (h + 180) % 360; + } + + @override + void mix(Color withColor, {num percent = 50}) { + assignRgb(toRgb..mix(withColor, percent: percent)); + } + + @override + void tint({num percent = 10}) { + mix(white, percent: percent); + } + + @override + void shade({num percent = 10}) { + mix(black, percent: percent); + } + + @override + Hsl clone({num? h, num? s, num? l, num? a}) => + Hsl(h: h ?? this.h, s: s ?? this.s, l: l ?? this.l, a: a ?? this.a); + + @override + Rgb get toRgb { + List rgb = [0, 0, 0]; + + num hue = h / 360 % 1; + num saturation = s / 100; + num luminance = l / 100; + + if (hue < 1 / 6) { + rgb[0] = 1; + rgb[1] = hue * 6; + } else if (hue < 2 / 6) { + rgb[0] = 2 - hue * 6; + rgb[1] = 1; + } else if (hue < 3 / 6) { + rgb[1] = 1; + rgb[2] = hue * 6 - 2; + } else if (hue < 4 / 6) { + rgb[1] = 4 - hue * 6; + rgb[2] = 1; + } else if (hue < 5 / 6) { + rgb[0] = hue * 6 - 4; + rgb[2] = 1; + } else { + rgb[0] = 1; + rgb[2] = 6 - hue * 6; + } + + rgb = rgb.map((val) => val + (1 - saturation) * (0.5 - val)).toList(); + + if (luminance < 0.5) { + rgb = rgb.map((val) => luminance * 2 * val).toList(); + } else { + rgb = rgb.map((val) => luminance * 2 * (1 - val) + 2 * val - 1).toList(); + } + + rgb = rgb.map((val) => (val * 255).round()).toList(); + + return Rgb(r: rgb[0] as int, g: rgb[1] as int, b: rgb[2] as int, a: a); + } + + @override + Hsl get toHsl => clone(); + + @override + Hsv get toHsv => toRgb.toHsv; + + @override + String get css { + return 'hsl(${shortenDouble(h as double)}, ${shortenDouble(s as double)}%, ${shortenDouble(l as double)}%, ${shortenDouble(a)})'; + } + + @override + String hex({bool shorten = true, bool withAlpha = true}) => + toRgb.hex(shorten: shorten, withAlpha: withAlpha); + + @override + String toString() => css; + + static const double hMin = 0; + static const double sMin = 0; + static const double lMin = 0; + static const double hMax = 360; + static const double sMax = 100; + static const double lMax = 100; + + static final hslRegExp = RegExp( + r'^hsl\(\s*(\d+(\.\d*)?|\.\d+)\s*,\s*(\d+(\.\d*)?|\.\d+)%\s*,\s*(\d+(\.\d*)?|\.\d+)%\s*\)$'); + static final hslaRegExp = RegExp( + r'^hsl\(\s*(\d+(\.\d*)?|\.\d+)\s*,\s*(\d+(\.\d*)?|\.\d+)%\s*,\s*(\d+(\.\d*)?|\.\d+)%\s*,\s*(\d+(\.\d*)?|\.\d+)\s*\)$'); +} diff --git a/lib/src/deps/color/hsv.dart b/lib/src/deps/color/hsv.dart new file mode 100644 index 0000000..0c536c1 --- /dev/null +++ b/lib/src/deps/color/hsv.dart @@ -0,0 +1,195 @@ +import 'lib_colors.dart'; + +class Hsv implements Color { + double _h = 0; + + double _s= 0; + + double _v= 0; + + double _a= 0; + + Hsv({num h = 0, num s = 0, num v = 0, num a = 1.0}) { + this.h = h; + this.s = s; + this.v = v; + this.a = a; + } + + num get h => _h; + + num get s => _s; + + num get v => _v; + + @override + double get a => _a; + + double get opacity => a / 255; + + set h(num v) { + if (v < hMin || v > hMax) throw ArgumentError.value(v); + _h = v.toDouble(); + } + + set s(num v) { + if (v < sMin || v > sMax) throw ArgumentError.value(v); + _s = v.toDouble(); + } + + set v(num v) { + if (vMin < 0 || v > vMax) throw ArgumentError.value(v); + _v = v.toDouble(); + } + + @override + set a(num v) { + if (v < 0 || v > 1.0) throw ArgumentError.value(v); + _a = v.toDouble(); + } + + @override + void assignRgb(Rgb rgb) { + assignHsv(rgb.toHsv); + } + + @override + void assignHsl(Hsl hsl) { + assignHsv(hsl.toHsv); + } + + void assignHsv(Hsv hsl) { + a = hsl.a; + h = hsl.h; + s = hsl.s; + v = hsl.v; + } + + @override + Hsv clone({num? h, num? s, num? v, num? a}) => + Hsv(h: h ?? this.h, s: s ?? this.s, v: v ?? this.v, a: a ?? this.a); + + @override + bool get isDark => brightness < 128.0; + + @override + bool get isLight => !isDark; + + @override + double get brightness => toRgb.brightness; + + @override + void brighten({num percent = 10}) { + assignRgb(toRgb..brighten(percent: percent)); + } + + @override + void lighten({num percent = 10}) { + // TODO throw + throw UnimplementedError(); + } + + @override + void darken({num percent = 10}) { + // TODO throw + throw UnimplementedError(); + } + + @override + void desaturate({num percent = 10}) { + // TODO throw + throw UnimplementedError(); + } + + @override + void saturate({num percent = 10}) { + // TODO throw + throw UnimplementedError(); + } + + @override + void greyscale() { + // TODO throw + throw UnimplementedError(); + } + + @override + void spin(num degrees) { + final hue = (h + degrees) % 360; + h = hue < 0 ? 360 + hue : hue; + } + + @override + void complement() { + h = (h + 180) % 360; + } + + @override + void mix(Color withColor, {num percent = 50}) { + assignRgb(toRgb..mix(withColor, percent: percent)); + } + + @override + void tint({num percent = 10}) { + this.mix(white, percent: percent); + } + + @override + void shade({num percent = 10}) { + this.mix(black, percent: percent); + } + + @override + Rgb get toRgb { + final int i = (h * 6.0).floor(); + final double f = h * 6.0 - i.toDouble(); + final int p = ((v / 100 * (1.0 - s / 100)) * 255).toInt(); + final int q = ((v / 100 * (1.0 - f * s / 100)) * 255).toInt(); + final int t = ((v / 100 * (1.0 - (1.0 - f) * s / 100)) * 255).toInt(); + final int cmax = (v / 100 * 255).toInt(); + + late Rgb rgb; + switch (i % 6) { + case 0: + rgb = Rgb(r: cmax, g: t, b: p, a: a); + break; + case 1: + rgb = Rgb(r: q, g: cmax, b: p, a: a); + break; + case 2: + rgb = Rgb(r: p, g: cmax, b: t, a: a); + break; + case 3: + rgb = Rgb(r: p, g: q, b: cmax, a: a); + break; + case 4: + rgb = Rgb(r: t, g: p, b: cmax, a: a); + break; + case 5: + rgb = Rgb(r: cmax, g: p, b: q, a: a); + break; + } + + return rgb; + } + + @override + Hsv get toHsv => clone(); + + @override + Hsl get toHsl => toRgb.toHsl; + + @override + String get css => toRgb.css; + + @override + String hex({bool shorten = true, bool withAlpha = true}) => + toRgb.hex(shorten: shorten, withAlpha: withAlpha); + + static const double hMin = 0; + static const double sMin = 0; + static const double vMin = 0; + static const double hMax = 360; + static const double sMax = 100; + static const double vMax = 100; +} \ No newline at end of file diff --git a/lib/src/deps/color/lib_colors.dart b/lib/src/deps/color/lib_colors.dart new file mode 100644 index 0000000..b2f0202 --- /dev/null +++ b/lib/src/deps/color/lib_colors.dart @@ -0,0 +1,77 @@ +import 'hsl.dart'; +import 'rgb.dart'; +import 'hsv.dart'; +import 'utils/hex.dart'; +import 'utils/names.dart'; + +export 'hsl.dart'; +export 'rgb.dart'; +export 'hsv.dart'; +export 'utils/names.dart'; + +abstract class Color { + static Color parse(String css) { + if (css.startsWith('#')) { + return HexColorCodec.decode(css); + } else if (css.startsWith('rgb')) { + return Rgb.parse(css); + } else if (css.startsWith('hsl')) { + return Hsl.parse(css); + } + + { + final ret = NamedColors.decode(css); + if (ret != null) return ret; + } + + throw FormatException('Unknown CSS color format!'); + } + + /// Returns CSS representation of the color + String get css; + + /// Returns HEX representation of the color + String hex({bool shorten = true, bool withAlpha = true}); + + Color clone(); + + void assignRgb(Rgb rgb); + + void assignHsl(Hsl hsl); + + bool get isDark; + + bool get isLight; + + double get brightness; + + void brighten({num percent = 10}); + + void lighten({num percent = 10}); + + void darken({num percent = 10}); + + void mix(Color withColor, {num percent = 50}); + + void tint({num percent = 10}); + + void shade({num percent = 10}); + + void desaturate({num percent = 10}); + + void saturate({num percent = 10}); + + void greyscale(); + + void spin(num degree); + + void complement(); + + double a =0; + + Rgb get toRgb; + + Hsl get toHsl; + + Hsv get toHsv; +} \ No newline at end of file diff --git a/lib/src/deps/color/parser.dart b/lib/src/deps/color/parser.dart new file mode 100644 index 0000000..02246d8 --- /dev/null +++ b/lib/src/deps/color/parser.dart @@ -0,0 +1,35 @@ +/* +class ColorParser { + + static final RegExp _beginsHash = new RegExp("^#"); + static final RegExp _hexColorRegExp = new RegExp("^#?([\\da-fA-F]{6})\$"); + static final RegExp _hexColorAbbreviatedRegExp = new RegExp("^#?([\\da-fA-F]{3})\$"); + + static Color parse(String toParse, { Color orElse() }) { + toParse = toParse.trim(); + return _parseRgb(toParse) ?? _parseHex(toParse) ?? _parseHsl(toParse) ?? _parseNamed(toParse) ?? orElse?.call() ?? null; + } + + static Color _parseHex(String toParse) { + if (_hexColorRegExp.hasMatch(toParse)) { + return new HexColor(toParse); + } + + if (_hexColorAbbreviatedRegExp.hasMatch(toParse)) { + String _unAbbreviated = new String.fromCharCodes(toParse.replaceFirst(_beginsHash, "").codeUnits.map((c) => [c, c]).expand((c) => c)); + return new HexColor(_unAbbreviated); + } + + return null; + } + + static Color _parseNamed(String toParse) { + try { + return new RgbColor.name(toParse.toLowerCase()); + } catch (argumentError) { + return null; + } + } + +} + */ \ No newline at end of file diff --git a/lib/src/deps/color/rgb.dart b/lib/src/deps/color/rgb.dart new file mode 100644 index 0000000..6506f20 --- /dev/null +++ b/lib/src/deps/color/rgb.dart @@ -0,0 +1,317 @@ +import 'dart:math'; + +import 'utils/hex.dart'; +import 'utils/num.dart'; + +import 'lib_colors.dart'; + +class Rgb implements Color { + int _r = 0; + + int _g = 0; + + int _b = 0; + + double _a = 0; + + Rgb({int r = 0, int g = 0, int b = 0, num a = 1.0}) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + factory Rgb.parse(String css) { + if (css.startsWith('rgba')) { + var match = rgbaRegExp.matchAsPrefix(css); + if (match == null) throw FormatException("Invalid value!"); + + var r = int.tryParse(match[1]!); + if (r == null) throw FormatException("Invalid red compenent!"); + var g = int.tryParse(match[2]!); + if (g == null) throw FormatException("Invalid green compenent!"); + var b = int.tryParse(match[3]!); + if (b == null) throw FormatException("Invalid blue compenent!"); + var a = double.tryParse(match[4] ?? match[5]!); + if (a == null) throw FormatException("Invalid alpha compenent!"); + return Rgb(r: r, g: g, b: b, a: a); + } + + if (css.startsWith('rgb')) { + var match = rgbRegExp.matchAsPrefix(css); + if (match == null) throw FormatException("Invalid value!"); + + var r = int.tryParse(match[1]!); + if (r == null) throw FormatException("Invalid red compenent!"); + var g = int.tryParse(match[2]!); + if (g == null) throw FormatException("Invalid green compenent!"); + var b = int.tryParse(match[3]!); + if (b == null) throw FormatException("Invalid blue compenent!"); + return Rgb(r: r, g: g, b: b); + } + + { + final ret = NamedColors.decode(css); + if (ret != null) return ret; + } + // TODO Eu Isaque implementei isso e não testei muito ainda + if (css.startsWith('#')) { + var hexColor = css.replaceAll('#', ''); + // if (hexColor.length == 3) { + // hexColor = '$hexColor$hexColor'; + // var r = int.tryParse(hexColor.substring(0, 2), radix: 16); + // if (r == null) throw FormatException("Invalid red compenent!"); + // var g = int.tryParse(hexColor.substring(2, 4), radix: 16); + // if (g == null) throw FormatException("Invalid green compenent!"); + // var b = int.tryParse(hexColor.substring(4, 6), radix: 16); + // if (b == null) throw FormatException("Invalid blue compenent!"); + // return Rgb(r: r, g: g, b: b); + // } + if (hexColor.length == 6) { + var r = int.tryParse(hexColor.substring(0, 2), radix: 16); + if (r == null) throw FormatException("Invalid red compenent!"); + var g = int.tryParse(hexColor.substring(2, 4), radix: 16); + if (g == null) throw FormatException("Invalid green compenent!"); + var b = int.tryParse(hexColor.substring(4, 6), radix: 16); + if (b == null) throw FormatException("Invalid blue compenent!"); + return Rgb(r: r, g: g, b: b); + } else if (hexColor.length == 8) { + + var r = int.tryParse(hexColor.substring(0, 2), radix: 16); + if (r == null) throw FormatException("Invalid red compenent!"); + var g = int.tryParse(hexColor.substring(2, 4), radix: 16); + if (g == null) throw FormatException("Invalid green compenent!"); + var b = int.tryParse(hexColor.substring(4, 6), radix: 16); + if (b == null) throw FormatException("Invalid blue compenent!"); + num? a = int.tryParse(hexColor.substring(6, 8), radix: 16); + + if (a == null) throw FormatException("Invalid blue compenent!"); + + if (a >= 0 && a <= 255) { + a = a / 255.0; + } else { + throw ArgumentError("Input value must be in the range 0-255"); + } + + return Rgb(r: r, g: g, b: b, a: a); + } + } + + throw FormatException("Invalid value!"); + } + + factory Rgb.fromHex(String hex) => HexColorCodec.decode(hex); + + factory Rgb.fromCssName(String name) { + final ret = NamedColors.decode(name); + if (ret == null) throw FormatException('Unknown color name $name'); + return ret; + } + + factory Rgb.fromInt(int color) { + double a = (color & 0xFF) / 0xFF; + int b = (color >> 8) & 0xFF; + int g = (color >> 16) & 0xFF; + int r = (color >> 24) & 0xFF; + return Rgb(r: r, g: g, b: b, a: a); + } + + int get r => _r; + + int get g => _g; + + int get b => _b; + + @override + double get a => _a; + + set r(int v) { + if (v < 0 || v > 255) throw ArgumentError.value(v); + _r = v; + } + + set g(int v) { + if (v < 0 || v > 255) throw ArgumentError.value(v); + _g = v; + } + + set b(int v) { + if (v < 0 || v > 255) throw ArgumentError.value(v); + _b = v; + } + + @override + set a(num v) { + if (v < 0 || v > 1.0) throw ArgumentError.value(v); + _a = v.toDouble(); + } + + @override + Rgb clone({int? r, int? g, int? b, num? a}) => + Rgb(r: r ?? this.r, g: g ?? this.g, b: b ?? this.b, a: a ?? this.a); + + @override + void assignRgb(Rgb rgb) { + r = rgb.r; + g = rgb.g; + b = rgb.b; + a = rgb.a; + } + + @override + void assignHsl(Hsl hsl) { + assignRgb(hsl.toRgb); + } + + @override + double get brightness => (r * 299 + g * 587 + b * 114) / 1000; + + @override + bool get isDark => brightness < 128.0; + + @override + bool get isLight => !isDark; + + @override + void brighten({num percent = 10}) { + final term = (-(255 * percent / 100)).round(); + + r = max(0, min(255, r - term)); + g = max(0, min(255, g - term)); + b = max(0, min(255, b - term)); + } + + @override + void lighten({num percent = 10}) { + assignHsl(toHsl..lighten(percent: percent)); + } + + @override + void darken({num percent = 10}) { + assignHsl(toHsl..darken(percent: percent)); + } + + @override + void mix(Color withColor, {num percent = 50}) { + final int p = (percent / 100).round(); + + final withRgb = withColor.toRgb; + a = (withRgb.a - a) * p + a; + r = (withRgb.r - r) * p + r; + g = (withRgb.g - g) * p + g; + b = (withRgb.b - b) * p + b; + } + + @override + void tint({num percent = 10}) { + mix(white, percent: percent); + } + + @override + void shade({num percent = 10}) { + mix(black, percent: percent); + } + + @override + void desaturate({num percent = 10}) { + assignHsl(toHsl..desaturate(percent: percent)); + } + + @override + void saturate({num percent = 10}) { + assignHsl(toHsl..saturate(percent: percent)); + } + + @override + void greyscale() { + assignHsl(toHsl..s = 0); + } + + @override + void spin(num degree) { + assignHsl(toHsl..spin(degree)); + } + + @override + void complement() { + assignHsl(toHsl..complement()); + } + + @override + Rgb get toRgb => clone(); + + @override + Hsl get toHsl { + num rf = r / 255; + num gf = g / 255; + num bf = b / 255; + num cMax = [rf, gf, bf].reduce(max); + num cMin = [rf, gf, bf].reduce(min); + num delta = cMax - cMin; + num hue; + num saturation; + num luminance; + + if (cMax == rf) { + hue = 60 * ((gf - bf) / delta % 6); + } else if (cMax == gf) { + hue = 60 * ((bf - rf) / delta + 2); + } else { + hue = 60 * ((rf - gf) / delta + 4); + } + + if (hue.isNaN || hue.isInfinite) { + hue = 0; + } + + luminance = (cMax + cMin) / 2; + + if (delta == 0) { + saturation = 0; + } else { + saturation = delta / (1 - (luminance * 2 - 1).abs()); + } + + return Hsl(h: hue, s: saturation * 100, l: luminance * 100, a: a); + } + + @override + Hsv get toHsv { + final int max_ = max(max(r, g), b); + final int min_ = min(min(r, g), b); + final int d = max_ - min_; + final int v = max_; + final double s = max_ == 0 ? 0 : d / max_; + double h = 0.0; + + if (max_ != min_) { + if (max_ == r) { + h = (g - b) / d + (g < b ? 6.0 : 0.0); + } else if (max_ == g) { + h = (b - r) / d + 2.0; + } else { + h = (r - g) / d + 4.0; + } + + h /= 6.0; + } + + return Hsv(h: h, s: s, v: v, a: a); + } + + @override + String get css => 'rgba($r, $g, $b, ${shortenDouble(a)})'; + + @override + String hex({bool shorten = true, bool withAlpha = true}) { + return HexColorCodec.encode(this, shorten: shorten, withAlpha: withAlpha); + } + + @override + String toString() => css; + + static final rgbRegExp = + RegExp(r'rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$'); + static final rgbaRegExp = RegExp( + r'rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d+(\.\d*)?|\.\d+)\s*\)$'); +} diff --git a/lib/src/deps/color/utils/hex.dart b/lib/src/deps/color/utils/hex.dart new file mode 100644 index 0000000..f7bc7ab --- /dev/null +++ b/lib/src/deps/color/utils/hex.dart @@ -0,0 +1,78 @@ + + +import '../lib_colors.dart'; + + +abstract class HexColorCodec { + static final RegExp longRegExp = RegExp( + r'\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})(?:([0-9a-f]{2}))?', + caseSensitive: false); + static final RegExp shortRegExp = RegExp( + r'\#?([0-9a-f])([0-9a-f])([0-9a-f])(?:([0-9a-f]))?', + caseSensitive: false); + + /// Convert the color as a string in the format '#FF0F00', '#FFFF0F00', '#FF0' + /// or '#FFF0' (with or without a leading '#', case insensitive) to the + /// corresponding color value and store it in [result]. The first group is + /// treated as the alpha channel if a [value] with four groups is passed. + static Rgb decode(String value) { + final longMatch = longRegExp.matchAsPrefix(value); + + if (longMatch != null) { + final int r = int.parse(longMatch[1]!, radix: 16); + final int g = int.parse(longMatch[2]!, radix: 16); + final int b = int.parse(longMatch[3]!, radix: 16); + int a = 255; + + if (longMatch[4] != null) { + a = int.parse(longMatch[4]!, radix: 16); + } + + return Rgb(r: r, g: g, b: b, a: a / 255); + } + + final smallMatch = shortRegExp.matchAsPrefix(value); + + if (smallMatch != null) { + final int r = int.parse(smallMatch[1]! + smallMatch[1]!, radix: 16); + final int g = int.parse(smallMatch[2]! + smallMatch[2]!, radix: 16); + final int b = int.parse(smallMatch[3]! + smallMatch[3]!, radix: 16); + int a = 255; + + if (smallMatch[4] != null) { + a = int.parse(smallMatch[4]! + smallMatch[4]!, radix: 16); + } + + return Rgb(r: r, g: g, b: b, a: a / 255); + } + + throw FormatException('Invalid hex color: $value'); + } + + static String encode(Color color, + {bool shorten = true, bool withAlpha = true}) { + final rgb = color.toRgb; + + int alpha = (rgb.a * 255).floor(); + + final bool isShort = shorten && + ((rgb.r >> 4) == (rgb.r & 0xF)) && + ((rgb.g >> 4) == (rgb.g & 0xF)) && + ((rgb.b >> 4) == (rgb.b & 0xF)) && + (!withAlpha || (alpha >> 4) == (alpha & 0xF)); + + if (isShort) { + final String rgbStr = (rgb.r & 0xF).toRadixString(16) + + (rgb.g & 0xF).toRadixString(16) + + (rgb.b & 0xF).toRadixString(16); + + return "#$rgbStr${withAlpha ? (alpha & 0xF).toRadixString(16) : ""}"; + } else { + final String rgbStr = rgb.r.toRadixString(16).padLeft(2, '0') + + rgb.g.toRadixString(16).padLeft(2, '0') + + rgb.b.toRadixString(16).padLeft(2, '0'); + + return "#$rgbStr${withAlpha ? alpha.toRadixString(16).padLeft(2, '0') : ""}"; + } + } +} \ No newline at end of file diff --git a/lib/src/deps/color/utils/names.dart b/lib/src/deps/color/utils/names.dart new file mode 100644 index 0000000..4f21449 --- /dev/null +++ b/lib/src/deps/color/utils/names.dart @@ -0,0 +1,308 @@ + +import '../rgb.dart'; + +abstract class NamedColors { + + static Rgb? decode(String name) => { + 'aliceblue': aliceblue, + 'antiquewhite': antiquewhite, + 'aqua': aqua, + 'aquamarine': aquamarine, + 'azure': azure, + 'beige': beige, + 'bisque': bisque, + 'black': black, + 'blanchedalmond': blanchedalmond, + 'blue': blue, + 'blueviolet': blueviolet, + 'brown': brown, + 'burlywood': burlywood, + 'cadetblue': cadetblue, + 'chartreuse': chartreuse, + 'chocolate': chocolate, + 'coral': coral, + 'cornflowerblue': cornflowerblue, + 'cornsilk': cornsilk, + 'crimson': crimson, + 'cyan': cyan, + 'darkblue': darkblue, + 'darkcyan': darkcyan, + 'darkgoldenrod': darkgoldenrod, + 'darkgray': darkgray, + 'darkgreen': darkgreen, + 'darkgrey': darkgrey, + 'darkkhaki': darkkhaki, + 'darkmagenta': darkmagenta, + 'darkolivegreen': darkolivegreen, + 'darkorange': darkorange, + 'darkorchid': darkorchid, + 'darkred': darkred, + 'darksalmon': darksalmon, + 'darkseagreen': darkseagreen, + 'darkslateblue': darkslateblue, + 'darkslategray': darkslategray, + 'darkslategrey': darkslategrey, + 'darkturquoise': darkturquoise, + 'darkviolet': darkviolet, + 'deeppink': deeppink, + 'deepskyblue': deepskyblue, + 'dimgray': dimgray, + 'dimgrey': dimgrey, + 'dodgerblue': dodgerblue, + 'firebrick': firebrick, + 'floralwhite': floralwhite, + 'forestgreen': forestgreen, + 'fuchsia': fuchsia, + 'gainsboro': gainsboro, + 'ghostwhite': ghostwhite, + 'gold': gold, + 'goldenrod': goldenrod, + 'gray': gray, + 'green': green, + 'greenyellow': greenyellow, + 'grey': grey, + 'honeydew': honeydew, + 'hotpink': hotpink, + 'indianred': indianred, + 'indigo': indigo, + 'ivory': ivory, + 'khaki': khaki, + 'lavender': lavender, + 'lavenderblush': lavenderblush, + 'lawngreen': lawngreen, + 'lemonchiffon': lemonchiffon, + 'lightblue': lightblue, + 'lightcoral': lightcoral, + 'lightcyan': lightcyan, + 'lightgoldenrodyellow': lightgoldenrodyellow, + 'lightgray': lightgray, + 'lightgreen': lightgreen, + 'lightgrey': lightgrey, + 'lightpink': lightpink, + 'lightsalmon': lightsalmon, + 'lightseagreen': lightseagreen, + 'lightskyblue': lightskyblue, + 'lightslategray': lightslategray, + 'lightslategrey': lightslategrey, + 'lightsteelblue': lightsteelblue, + 'lightyellow': lightyellow, + 'lime': lime, + 'limegreen': limegreen, + 'linen': linen, + 'magenta': magenta, + 'maroon': maroon, + 'mediumaquamarine': mediumaquamarine, + 'mediumblue': mediumblue, + 'mediumorchid': mediumorchid, + 'mediumpurple': mediumpurple, + 'mediumseagreen': mediumseagreen, + 'mediumslateblue': mediumslateblue, + 'mediumspringgreen': mediumspringgreen, + 'mediumturquoise': mediumturquoise, + 'mediumvioletred': mediumvioletred, + 'midnightblue': midnightblue, + 'mintcream': mintcream, + 'mistyrose': mistyrose, + 'moccasin': moccasin, + 'navajowhite': navajowhite, + 'navy': navy, + 'oldlace': oldlace, + 'olive': olive, + 'olivedrab': olivedrab, + 'orange': orange, + 'orangered': orangered, + 'orchid': orchid, + 'palegoldenrod': palegoldenrod, + 'palegreen': palegreen, + 'paleturquoise': paleturquoise, + 'palevioletred': palevioletred, + 'papayawhip': papayawhip, + 'peachpuff': peachpuff, + 'peru': peru, + 'pink': pink, + 'plum': plum, + 'powderblue': powderblue, + 'purple': purple, + 'rebeccapurple': rebeccapurple, + 'red': red, + 'rosybrown': rosybrown, + 'royalblue': royalblue, + 'saddlebrown': saddlebrown, + 'salmon': salmon, + 'sandybrown': sandybrown, + 'seagreen': seagreen, + 'seashell': seashell, + 'sienna': sienna, + 'silver': silver, + 'skyblue': skyblue, + 'slateblue': slateblue, + 'slategray': slategray, + 'slategrey': slategrey, + 'snow': snow, + 'springgreen': springgreen, + 'steelblue': steelblue, + 'tan': tan, + 'teal': teal, + 'thistle': thistle, + 'tomato': tomato, + 'turquoise': turquoise, + 'violet': violet, + 'wheat': wheat, + 'white': white, + 'whitesmoke': whitesmoke, + 'yellow': yellow, + 'yellowgreen': yellowgreen, + 'transparent': transparent, + }[name.toLowerCase()]; +} + +Rgb get aliceblue => Rgb(r: 0xf0, g: 0xf8, b: 0xff, a: 1); +Rgb get antiquewhite => Rgb(r: 0xfa, g: 0xeb, b: 0xd7, a: 1); +Rgb get aqua => Rgb(r: 0x00, g: 0xff, b: 0xff, a: 1); +Rgb get aquamarine => Rgb(r: 0x7f, g: 0xff, b: 0xd4, a: 1); +Rgb get azure => Rgb(r: 0xf0, g: 0xff, b: 0xff, a: 1); +Rgb get beige => Rgb(r: 0xf5, g: 0xf5, b: 0xdc, a: 1); +Rgb get bisque => Rgb(r: 0xff, g: 0xe4, b: 0xc4, a: 1); +Rgb get black => Rgb(r: 0x00, g: 0x00, b: 0x00, a: 1); +Rgb get blanchedalmond => Rgb(r: 0xff, g: 0xeb, b: 0xcd, a: 1); +Rgb get blue => Rgb(r: 0x00, g: 0x00, b: 0xff, a: 1); +Rgb get blueviolet => Rgb(r: 0x8a, g: 0x2b, b: 0xe2, a: 1); +Rgb get brown => Rgb(r: 0xa5, g: 0x2a, b: 0x2a, a: 1); +Rgb get burlywood => Rgb(r: 0xde, g: 0xb8, b: 0x87, a: 1); +Rgb get cadetblue => Rgb(r: 0x5f, g: 0x9e, b: 0xa0, a: 1); +Rgb get chartreuse => Rgb(r: 0x7f, g: 0xff, b: 0x00, a: 1); +Rgb get chocolate => Rgb(r: 0xd2, g: 0x69, b: 0x1e, a: 1); +Rgb get coral => Rgb(r: 0xff, g: 0x7f, b: 0x50, a: 1); +Rgb get cornflowerblue => Rgb(r: 0x64, g: 0x95, b: 0xed, a: 1); +Rgb get cornsilk => Rgb(r: 0xff, g: 0xf8, b: 0xdc, a: 1); +Rgb get crimson => Rgb(r: 0xdc, g: 0x14, b: 0x3c, a: 1); +Rgb get cyan => Rgb(r: 0x00, g: 0xff, b: 0xff, a: 1); +Rgb get darkblue => Rgb(r: 0x00, g: 0x00, b: 0x8b, a: 1); +Rgb get darkcyan => Rgb(r: 0x00, g: 0x8b, b: 0x8b, a: 1); +Rgb get darkgoldenrod => Rgb(r: 0xb8, g: 0x86, b: 0x0b, a: 1); +Rgb get darkgray => Rgb(r: 0xa9, g: 0xa9, b: 0xa9, a: 1); +Rgb get darkgreen => Rgb(r: 0x00, g: 0x64, b: 0x00, a: 1); +Rgb get darkgrey => Rgb(r: 0xa9, g: 0xa9, b: 0xa9, a: 1); +Rgb get darkkhaki => Rgb(r: 0xbd, g: 0xb7, b: 0x6b, a: 1); +Rgb get darkmagenta => Rgb(r: 0x8b, g: 0x00, b: 0x8b, a: 1); +Rgb get darkolivegreen => Rgb(r: 0x55, g: 0x6b, b: 0x2f, a: 1); +Rgb get darkorange => Rgb(r: 0xff, g: 0x8c, b: 0x00, a: 1); +Rgb get darkorchid => Rgb(r: 0x99, g: 0x32, b: 0xcc, a: 1); +Rgb get darkred => Rgb(r: 0x8b, g: 0x00, b: 0x00, a: 1); +Rgb get darksalmon => Rgb(r: 0xe9, g: 0x96, b: 0x7a, a: 1); +Rgb get darkseagreen => Rgb(r: 0x8f, g: 0xbc, b: 0x8f, a: 1); +Rgb get darkslateblue => Rgb(r: 0x48, g: 0x3d, b: 0x8b, a: 1); +Rgb get darkslategray => Rgb(r: 0x2f, g: 0x4f, b: 0x4f, a: 1); +Rgb get darkslategrey => Rgb(r: 0x2f, g: 0x4f, b: 0x4f, a: 1); +Rgb get darkturquoise => Rgb(r: 0x00, g: 0xce, b: 0xd1, a: 1); +Rgb get darkviolet => Rgb(r: 0x94, g: 0x00, b: 0xd3, a: 1); +Rgb get deeppink => Rgb(r: 0xff, g: 0x14, b: 0x93, a: 1); +Rgb get deepskyblue => Rgb(r: 0x00, g: 0xbf, b: 0xff, a: 1); +Rgb get dimgray => Rgb(r: 0x69, g: 0x69, b: 0x69, a: 1); +Rgb get dimgrey => Rgb(r: 0x69, g: 0x69, b: 0x69, a: 1); +Rgb get dodgerblue => Rgb(r: 0x1e, g: 0x90, b: 0xff, a: 1); +Rgb get firebrick => Rgb(r: 0xb2, g: 0x22, b: 0x22, a: 1); +Rgb get floralwhite => Rgb(r: 0xff, g: 0xfa, b: 0xf0, a: 1); +Rgb get forestgreen => Rgb(r: 0x22, g: 0x8b, b: 0x22, a: 1); +Rgb get fuchsia => Rgb(r: 0xff, g: 0x00, b: 0xff, a: 1); +Rgb get gainsboro => Rgb(r: 0xdc, g: 0xdc, b: 0xdc, a: 1); +Rgb get ghostwhite => Rgb(r: 0xf8, g: 0xf8, b: 0xff, a: 1); +Rgb get gold => Rgb(r: 0xff, g: 0xd7, b: 0x00, a: 1); +Rgb get goldenrod => Rgb(r: 0xda, g: 0xa5, b: 0x20, a: 1); +Rgb get gray => Rgb(r: 0x80, g: 0x80, b: 0x80, a: 1); +Rgb get green => Rgb(r: 0x00, g: 0x80, b: 0x00, a: 1); +Rgb get greenyellow => Rgb(r: 0xad, g: 0xff, b: 0x2f, a: 1); +Rgb get grey => Rgb(r: 0x80, g: 0x80, b: 0x80, a: 1); +Rgb get honeydew => Rgb(r: 0xf0, g: 0xff, b: 0xf0, a: 1); +Rgb get hotpink => Rgb(r: 0xff, g: 0x69, b: 0xb4, a: 1); +Rgb get indianred => Rgb(r: 0xcd, g: 0x5c, b: 0x5c, a: 1); +Rgb get indigo => Rgb(r: 0x4b, g: 0x00, b: 0x82, a: 1); +Rgb get ivory => Rgb(r: 0xff, g: 0xff, b: 0xf0, a: 1); +Rgb get khaki => Rgb(r: 0xf0, g: 0xe6, b: 0x8c, a: 1); +Rgb get lavender => Rgb(r: 0xe6, g: 0xe6, b: 0xfa, a: 1); +Rgb get lavenderblush => Rgb(r: 0xff, g: 0xf0, b: 0xf5, a: 1); +Rgb get lawngreen => Rgb(r: 0x7c, g: 0xfc, b: 0x00, a: 1); +Rgb get lemonchiffon => Rgb(r: 0xff, g: 0xfa, b: 0xcd, a: 1); +Rgb get lightblue => Rgb(r: 0xad, g: 0xd8, b: 0xe6, a: 1); +Rgb get lightcoral => Rgb(r: 0xf0, g: 0x80, b: 0x80, a: 1); +Rgb get lightcyan => Rgb(r: 0xe0, g: 0xff, b: 0xff, a: 1); +Rgb get lightgoldenrodyellow => Rgb(r: 0xfa, g: 0xfa, b: 0xd2, a: 1); +Rgb get lightgray => Rgb(r: 0xd3, g: 0xd3, b: 0xd3, a: 1); +Rgb get lightgreen => Rgb(r: 0x90, g: 0xee, b: 0x90, a: 1); +Rgb get lightgrey => Rgb(r: 0xd3, g: 0xd3, b: 0xd3, a: 1); +Rgb get lightpink => Rgb(r: 0xff, g: 0xb6, b: 0xc1, a: 1); +Rgb get lightsalmon => Rgb(r: 0xff, g: 0xa0, b: 0x7a, a: 1); +Rgb get lightseagreen => Rgb(r: 0x20, g: 0xb2, b: 0xaa, a: 1); +Rgb get lightskyblue => Rgb(r: 0x87, g: 0xce, b: 0xfa, a: 1); +Rgb get lightslategray => Rgb(r: 0x77, g: 0x88, b: 0x99, a: 1); +Rgb get lightslategrey => Rgb(r: 0x77, g: 0x88, b: 0x99, a: 1); +Rgb get lightsteelblue => Rgb(r: 0xb0, g: 0xc4, b: 0xde, a: 1); +Rgb get lightyellow => Rgb(r: 0xff, g: 0xff, b: 0xe0, a: 1); +Rgb get lime => Rgb(r: 0x00, g: 0xff, b: 0x00, a: 1); +Rgb get limegreen => Rgb(r: 0x32, g: 0xcd, b: 0x32, a: 1); +Rgb get linen => Rgb(r: 0xfa, g: 0xf0, b: 0xe6, a: 1); +Rgb get magenta => Rgb(r: 0xff, g: 0x00, b: 0xff, a: 1); +Rgb get maroon => Rgb(r: 0x80, g: 0x00, b: 0x00, a: 1); +Rgb get mediumaquamarine => Rgb(r: 0x66, g: 0xcd, b: 0xaa, a: 1); +Rgb get mediumblue => Rgb(r: 0x00, g: 0x00, b: 0xcd, a: 1); +Rgb get mediumorchid => Rgb(r: 0xba, g: 0x55, b: 0xd3, a: 1); +Rgb get mediumpurple => Rgb(r: 0x93, g: 0x70, b: 0xdb, a: 1); +Rgb get mediumseagreen => Rgb(r: 0x3c, g: 0xb3, b: 0x71, a: 1); +Rgb get mediumslateblue => Rgb(r: 0x7b, g: 0x68, b: 0xee, a: 1); +Rgb get mediumspringgreen => Rgb(r: 0x00, g: 0xfa, b: 0x9a, a: 1); +Rgb get mediumturquoise => Rgb(r: 0x48, g: 0xd1, b: 0xcc, a: 1); +Rgb get mediumvioletred => Rgb(r: 0xc7, g: 0x15, b: 0x85, a: 1); +Rgb get midnightblue => Rgb(r: 0x19, g: 0x19, b: 0x70, a: 1); +Rgb get mintcream => Rgb(r: 0xf5, g: 0xff, b: 0xfa, a: 1); +Rgb get mistyrose => Rgb(r: 0xff, g: 0xe4, b: 0xe1, a: 1); +Rgb get moccasin => Rgb(r: 0xff, g: 0xe4, b: 0xb5, a: 1); +Rgb get navajowhite => Rgb(r: 0xff, g: 0xde, b: 0xad, a: 1); +Rgb get navy => Rgb(r: 0x00, g: 0x00, b: 0x80, a: 1); +Rgb get oldlace => Rgb(r: 0xfd, g: 0xf5, b: 0xe6, a: 1); +Rgb get olive => Rgb(r: 0x80, g: 0x80, b: 0x00, a: 1); +Rgb get olivedrab => Rgb(r: 0x6b, g: 0x8e, b: 0x23, a: 1); +Rgb get orange => Rgb(r: 0xff, g: 0xa5, b: 0x00, a: 1); +Rgb get orangered => Rgb(r: 0xff, g: 0x45, b: 0x00, a: 1); +Rgb get orchid => Rgb(r: 0xda, g: 0x70, b: 0xd6, a: 1); +Rgb get palegoldenrod => Rgb(r: 0xee, g: 0xe8, b: 0xaa, a: 1); +Rgb get palegreen => Rgb(r: 0x98, g: 0xfb, b: 0x98, a: 1); +Rgb get paleturquoise => Rgb(r: 0xaf, g: 0xee, b: 0xee, a: 1); +Rgb get palevioletred => Rgb(r: 0xdb, g: 0x70, b: 0x93, a: 1); +Rgb get papayawhip => Rgb(r: 0xff, g: 0xef, b: 0xd5, a: 1); +Rgb get peachpuff => Rgb(r: 0xff, g: 0xda, b: 0xb9, a: 1); +Rgb get peru => Rgb(r: 0xcd, g: 0x85, b: 0x3f, a: 1); +Rgb get pink => Rgb(r: 0xff, g: 0xc0, b: 0xcb, a: 1); +Rgb get plum => Rgb(r: 0xdd, g: 0xa0, b: 0xdd, a: 1); +Rgb get powderblue => Rgb(r: 0xb0, g: 0xe0, b: 0xe6, a: 1); +Rgb get purple => Rgb(r: 0x80, g: 0x00, b: 0x80, a: 1); +Rgb get rebeccapurple => Rgb(r: 0x66, g: 0x33, b: 0x99, a: 1); +Rgb get red => Rgb(r: 0xff, g: 0x00, b: 0x00, a: 1); +Rgb get rosybrown => Rgb(r: 0xbc, g: 0x8f, b: 0x8f, a: 1); +Rgb get royalblue => Rgb(r: 0x41, g: 0x69, b: 0xe1, a: 1); +Rgb get saddlebrown => Rgb(r: 0x8b, g: 0x45, b: 0x13, a: 1); +Rgb get salmon => Rgb(r: 0xfa, g: 0x80, b: 0x72, a: 1); +Rgb get sandybrown => Rgb(r: 0xf4, g: 0xa4, b: 0x60, a: 1); +Rgb get seagreen => Rgb(r: 0x2e, g: 0x8b, b: 0x57, a: 1); +Rgb get seashell => Rgb(r: 0xff, g: 0xf5, b: 0xee, a: 1); +Rgb get sienna => Rgb(r: 0xa0, g: 0x52, b: 0x2d, a: 1); +Rgb get silver => Rgb(r: 0xc0, g: 0xc0, b: 0xc0, a: 1); +Rgb get skyblue => Rgb(r: 0x87, g: 0xce, b: 0xeb, a: 1); +Rgb get slateblue => Rgb(r: 0x6a, g: 0x5a, b: 0xcd, a: 1); +Rgb get slategray => Rgb(r: 0x70, g: 0x80, b: 0x90, a: 1); +Rgb get slategrey => Rgb(r: 0x70, g: 0x80, b: 0x90, a: 1); +Rgb get snow => Rgb(r: 0xff, g: 0xfa, b: 0xfa, a: 1); +Rgb get springgreen => Rgb(r: 0x00, g: 0xff, b: 0x7f, a: 1); +Rgb get steelblue => Rgb(r: 0x46, g: 0x82, b: 0xb4, a: 1); +Rgb get tan => Rgb(r: 0xd2, g: 0xb4, b: 0x8c, a: 1); +Rgb get teal => Rgb(r: 0x00, g: 0x80, b: 0x80, a: 1); +Rgb get thistle => Rgb(r: 0xd8, g: 0xbf, b: 0xd8, a: 1); +Rgb get tomato => Rgb(r: 0xff, g: 0x63, b: 0x47, a: 1); +Rgb get turquoise => Rgb(r: 0x40, g: 0xe0, b: 0xd0, a: 1); +Rgb get violet => Rgb(r: 0xee, g: 0x82, b: 0xee, a: 1); +Rgb get wheat => Rgb(r: 0xf5, g: 0xde, b: 0xb3, a: 1); +Rgb get white => Rgb(r: 0xff, g: 0xff, b: 0xff, a: 1); +Rgb get whitesmoke => Rgb(r: 0xf5, g: 0xf5, b: 0xf5, a: 1); +Rgb get yellow => Rgb(r: 0xff, g: 0xff, b: 0x00, a: 1); +Rgb get yellowgreen => Rgb(r: 0x9a, g: 0xcd, b: 0x32, a: 1); + +Rgb get transparent => Rgb(a: 0.0); \ No newline at end of file diff --git a/lib/src/deps/color/utils/num.dart b/lib/src/deps/color/utils/num.dart new file mode 100644 index 0000000..1ea5e4a --- /dev/null +++ b/lib/src/deps/color/utils/num.dart @@ -0,0 +1,7 @@ +/// Skips fraction part for whole number +String shortenDouble(double v) { + if (v.isNegative) throw ArgumentError.value(v, 'v', 'Cannot be negative!'); + num ret = v.truncate(); + if (ret != v) ret = v; + return ret.toString(); +} \ No newline at end of file diff --git a/lib/src/deps/deferred_content.dart b/lib/src/deps/deferred_content.dart new file mode 100644 index 0000000..f9b3d86 --- /dev/null +++ b/lib/src/deps/deferred_content.dart @@ -0,0 +1,157 @@ + + +import 'dart:html'; + +import 'package:ngdart/angular.dart'; +import 'disposer.dart'; + +import 'deferred_content_aware.dart'; + +/// When put on an element B, this directive creates B each time the nearest +/// strict ancestor [DeferredContentAware] container A becomes visible and +/// destroys B each time A becomes invisible. +/// +/// Throws if A does not exist. +/// This directive can be used to avoid the cost of eagerly instantiating +/// invisible content and the cost of change-detection on invisible content. +@Directive( + selector: '[deferredContent]', +) +class DeferredContentDirective implements OnDestroy { + final _disposer = Disposer.oneShot(); + final _placeholder = DivElement(); + + + final ViewContainerRef _viewContainer; + + EmbeddedViewRef? _viewRef; + final TemplateRef _template; + + /// Create a placeholder element to maintain content size when hidden. + /// + /// Used like: + /// ```html + /// + /// ``` + @Input('deferredContent') + bool preserveDimensions = false; + + /// Even when the content is not-visible force it to be on the page. + /// + /// Only use this for common components which needs to give options to it's + /// content. + @Input() + set deferredContentForceContent(bool value) { + _forceContent = value; + _setVisible(); + } + + // Keep around the current state. + bool _shown = false; + bool _visible = false; + bool _forceContent = false; + + void _setVisible() { + bool value = _visible || _forceContent; + if (value == _shown) return; + if (value) { + if (preserveDimensions) { + // Remove the placeholder and add the deferred content. + _placeholder.remove(); + } + _viewRef = _viewContainer.createEmbeddedView(_template); + } else { + if (preserveDimensions) { + // Save the dimensions of the deferred content. + var rootNodes = _viewRef?.rootNodes ?? []; + var content = rootNodes.isNotEmpty ? rootNodes.first : null; + if (content is HtmlElement) { + // This isn't in DomService.schedule{Read,Write} because + // it needs to work with components that aren't scheduled. + var dimensions = content.getBoundingClientRect(); + _placeholder.style + ..width = '${dimensions.width}px' + ..height = '${dimensions.height}px'; + } + } + + // Remove the deferred content. + _viewContainer.clear(); + + if (preserveDimensions) { + // Add the placeholder so the parent's size doesn't change. + var container = _viewContainer.element.nativeElement; + if (container?.parentNode != null) { + container.parentNode.insertBefore(_placeholder, container); + } + } + } + _shown = value; + } + + DeferredContentDirective( + this._viewContainer, + this._template, + DeferredContentAware parent, + ChangeDetectorRef changeDetector, + ) { + _disposer.addStreamSubscription(parent.contentVisible.listen((value) { + _visible = value; + _setVisible(); + changeDetector.markForCheck(); + })); + } + + @override + void ngOnDestroy() { + _disposer.dispose(); + // _viewContainer = null; + // _template = null; + } +} + +/// Nested inside a [DeferredContentAware] container, this directive creates +/// its content the first time the parent container becomes visible. +/// +/// This directive is not recommended as it will cause Angular to change-detect +/// the contents even when hidden. If your hidden content has push-detection +/// enabled, go for it. +@Directive( + selector: '[cachedDeferredContent]', +) +class CachingDeferredContentDirective implements OnDestroy { + final ViewContainerRef _viewContainer; + final TemplateRef _template; + final _disposer = Disposer.oneShot(); + ViewRef? _view; + + // Keep around the current state. + bool _visible = false; + + void _setVisible(bool value) { + if (value == _visible) return; + if (value && _view == null) { + _view = _viewContainer.createEmbeddedView(_template); + } + _visible = value; + } + + CachingDeferredContentDirective( + this._viewContainer, + this._template, + DeferredContentAware parent, + ChangeDetectorRef changeDetector, + ) { + _disposer.addStreamSubscription(parent.contentVisible.listen((value) { + _setVisible(value); + changeDetector.markForCheck(); + })); + } + + @override + void ngOnDestroy() { + _disposer.dispose(); + // _viewContainer = null; + // _template = null; + } +} \ No newline at end of file diff --git a/lib/src/deps/deferred_content_aware.dart b/lib/src/deps/deferred_content_aware.dart new file mode 100644 index 0000000..d7e7917 --- /dev/null +++ b/lib/src/deps/deferred_content_aware.dart @@ -0,0 +1,12 @@ + +import 'dart:async'; + +/// A container which controls the visibility of its content via a Stream. +/// +/// This allows content to defer its view creation until it is actually visible. +/// The `DeferredContentDirective` is a directive which looks for a parent +/// providing this stream and creates/clears its view based on the stream. +abstract class DeferredContentAware { + /// Component publishes to this stream to control the visibility of contents. + Stream get contentVisible; +} \ No newline at end of file diff --git a/lib/src/deps/dispose/dispose_angular.dart b/lib/src/deps/dispose/dispose_angular.dart new file mode 100644 index 0000000..d7f04c0 --- /dev/null +++ b/lib/src/deps/dispose/dispose_angular.dart @@ -0,0 +1,22 @@ +import 'dart:async'; +import 'dart:html'; +import 'package:ngdart/angular.dart'; +import 'package:meta/meta.dart'; +import 'generic.dart'; + +abstract class DisposableComponent extends Disposable implements OnDestroy { + @mustCallSuper + @override + void ngOnDestroy() => dispose(); + + StreamSubscription documentListen( + String eventName, Function(T) fn) { + final ctrl = controller(); + + document.addEventListener(eventName, (event) { + ctrl.add(event as T); + }); + + return each(ctrl.stream, fn); + } +} \ No newline at end of file diff --git a/lib/src/deps/dispose/generic.dart b/lib/src/deps/dispose/generic.dart new file mode 100644 index 0000000..c50c0b1 --- /dev/null +++ b/lib/src/deps/dispose/generic.dart @@ -0,0 +1,492 @@ +import 'dart:async'; + +import 'package:change_notifier/change_notifier.dart'; +import '../tuple.dart'; +import 'interval.dart'; + +class _Timer implements Timer { + final Timer delegate; + final Disposable _handler; + final Symbol? id; + + @override + bool get isActive => delegate.isActive; + + @override + int get tick => delegate.tick; + + void _rem() { + if (id == null) { + _handler._timers.remove(this); + } else { + _handler._uniqueTimers.remove(id); + } + } + + @override + void cancel() { + delegate.cancel(); + + _rem(); + } + + _Timer(this._handler, this.delegate, this.id); +} + +class ControlledStreamController implements StreamController { + ControlledStreamController({FutureOr Function()? onCancel}) + : _ctrl = StreamController(onCancel: onCancel); + + ControlledStreamController.broadcast({FutureOr Function()? onCancel}) + : _ctrl = StreamController.broadcast(onCancel: onCancel); + + final StreamController _ctrl; + final List> _subscriptions = []; + + @override + FutureOr Function()? get onCancel => _ctrl.onCancel; + + @override + void Function()? get onListen => _ctrl.onListen; + + @override + void Function()? get onPause => _ctrl.onPause; + + @override + void Function()? get onResume => _ctrl.onResume; + + @override + void add(T event) { + _ctrl.add(event); + } + + @override + void addError(Object error, [StackTrace? stackTrace]) { + _ctrl.addError(error, stackTrace); + } + + @override + Future addStream(Stream source, {bool? cancelOnError}) { + assert(cancelOnError != true, 'Not implemented'); + + final subs = source.listen((ev) => _ctrl.add(ev)); + + _subscriptions.add(subs); + + return subs.asFuture(); + } + + @override + Future close() async { + for (final sub in _subscriptions) { + await sub.cancel(); + } + + return _ctrl.close(); + } + + @override + Future get done => _ctrl.done; + + @override + bool get hasListener => _ctrl.hasListener; + + @override + bool get isClosed => _ctrl.isClosed; + + @override + bool get isPaused => _ctrl.isPaused; + + @override + StreamSink get sink => _ctrl.sink; + + @override + Stream get stream => _ctrl.stream; + + @override + set onCancel(FutureOr Function()? onCancel) => + _ctrl.onCancel = onCancel; + + @override + set onListen(void Function()? onListen) => _ctrl.onListen = onListen; + + @override + set onPause(void Function()? onPause) => _ctrl.onPause = onPause; + + @override + set onResume(void Function()? onResume) => _ctrl.onResume = onResume; +} + +class ControlledStreamSubscription implements StreamSubscription { + final StreamSubscription _delegate; + final void Function() _cancel; + + @override + Future cancel() { + _cancel(); + return _delegate.cancel(); + } + + @override + void onData(void Function(T)? handleData) => _delegate.onData(handleData); + + @override + void onError(Function? handleError) => _delegate.onError(handleError); + + @override + void onDone(void Function()? handleDone) => _delegate.onDone(handleDone); + + @override + void pause([Future? resumeSignal]) => _delegate.pause(resumeSignal); + + @override + void resume() => _delegate.resume(); + + @override + bool get isPaused => _delegate.isPaused; + + @override + Future asFuture([E? futureValue]) => _delegate.asFuture(futureValue); + + ControlledStreamSubscription(this._delegate, this._cancel); +} + +mixin class Disposable { + Set _subs = {}; + Map _uniqueSubs = {}; + Map> _uniqueListeners = {}; + Set _ctrls = {}; + Set<_Timer> _timers = {}; + Map _uniqueTimers = {}; + Set _disposables = {}; + Disposable? _parent; + bool _canceling = false; + + void _sanity() { + assert(!_canceling); + } + + Disposable reusable() { + final ret = Disposable(); + + disposable(ret); + + return ret; + } + + Future cancelBind(Symbol key) async { + final ret = _uniqueSubs[key]; + + if (ret != null) { + await ret.cancel(); + return true; + } + + return false; + } + + bool cancelTimer(Symbol key) { + final ret = _uniqueTimers[key]; + + if (ret != null) { + ret.cancel(); + return true; + } + + return false; + } + + /// Listens and iterates through [stream] by calling [fn]. + /// The listener is disposed in the [dispose] function. + /// + /// If you add a [uniqueId], it means that whenever you call [each], + /// we will make sure that clear any listener with the same [uniqueId]. + StreamSubscription each(Stream stream, void Function(T item) fn, + {@Deprecated('Use [uniqueEach] instead') Symbol? uniqueId}) { + late StreamSubscription ret; + + _sanity(); + + if (uniqueId == null) { + ret = ControlledStreamSubscription( + stream.listen(fn), () => _subs.remove(ret)); + _subs.add(ret); + } else { + ret = ControlledStreamSubscription( + stream.listen(fn), () => _uniqueSubs.remove(uniqueId)); + + _uniqueSubs[uniqueId]?.cancel(); + + _uniqueSubs[uniqueId] = ret; + } + + return ret; + } + + Future takeFirst(Stream stream) { + final cmp = Completer(); + late StreamSubscription subs; + + subs = each(stream, (item) { + subs.cancel(); + cmp.complete(item); + }); + + return cmp.future; + } + + Future cancelUnique(Symbol id) async { + final sub = _uniqueSubs[id]; + + if (sub != null) { + _uniqueSubs.remove(id); + return sub.cancel(); + } + } + + Future cancelUniques(Set ids) async { + ids.forEach(cancelUnique); + } + + /// Listens and iterates through [stream] by calling [fn]. + /// The listener is disposed in the [dispose] function. + /// + /// If you add a [uniqueId], it means that whenever you call [each], + /// we will make sure that clear any listener with the same [uniqueId]. + StreamSubscription uniqueEach( + Symbol id, Stream stream, void Function(T item) fn) { + late StreamSubscription ret; + + _sanity(); + + ret = ControlledStreamSubscription( + stream.listen(fn), () => _uniqueSubs.remove(id)); + + _uniqueSubs[id]?.cancel(); + + _uniqueSubs[id] = ret; + + return ret; + } + + /// Listens and iterates through [obj.addListener] by calling [fn]. + /// The listener is disposed in the [dispose] function. + /// + /// Whenever you call [uniqueListen] + /// we will make sure that clear any listener with the same [id]. + void uniqueListen(Symbol id, ChangeNotifier obj, void Function() fn) { + _sanity(); + + obj.addListener(fn); + + final cur = _uniqueListeners[id]; + + if (cur != null) { + cur.item1.removeListener(cur.item2); + } + + _uniqueListeners[id] = Tuple2(obj, fn); + } + + /// Creates a [StreamController] that is closed within [dispose]. + /// + /// Set [broadcast] to true if you need a + /// broadcasting controller as in [StreamController.broadcast]. + StreamController controller( + {bool broadcast = false, FutureOr Function()? onCancel /*?*/ + }) { + StreamController ret; + + _sanity(); + + if (broadcast) { + ret = ControlledStreamController.broadcast(onCancel: onCancel); + } else { + ret = ControlledStreamController(onCancel: onCancel); + } + + ret.done.then((ev) => _ctrls.remove(ret)); + + _ctrls.add(ret); + + return ret; + } + + /// Creates a [StreamController.broadcast] that is closed within [dispose]. + StreamController broadcaster({FutureOr Function()? onCancel /*?*/ + }) { + _sanity(); + + final ret = ControlledStreamController.broadcast(onCancel: onCancel); + + ret.done.then((ev) => _ctrls.remove(ret)); + + _ctrls.add(ret); + + return ret; + } + + /// Binds another [Disposable] object to be disposed when this + /// is disposed. + void disposable(Disposable disposable) { + _sanity(); + + disposable._parent = this; + _disposables.add(disposable); + } + + /// Creates a periodic [Timer.periodic] that gets cancelled within [dispose]. + /// + /// Set [uniqueId] to some [Symbol] to make this timer unique. + /// This means that we will cancel the previous timer with same symbol + /// before assigning a new one. + Timer periodic(Duration duration, Function(Timer) fn, {Symbol? uniqueId}) { + final tm = Timer.periodic(duration, (t) => fn(t)); + + return _timer(tm, uniqueId: uniqueId); + } + + Timer interval(Duration duration, Function(Timer) fn, + {Symbol? uniqueId, bool execNow = true}) { + final tm = IntervalTimer(fn, duration, execNow: execNow); + + return _timer(tm, uniqueId: uniqueId); + } + + StreamedIntervalTimer streamedInterval( + Stream valueStream, Duration duration, Function(T?) fn, + {Symbol? uniqueId}) { + final tm = StreamedIntervalTimer(fn, duration, execNow: true); + + each(valueStream, (ev) { + tm.add(ev); + }); + + _timer(tm, uniqueId: uniqueId); + + return tm; + } + + _Timer _timer(Timer tm, {Symbol? uniqueId}) { + _sanity(); + + final ret = _Timer(this, tm, uniqueId); + + if (uniqueId != null) { + _uniqueTimers[uniqueId]?.cancel(); + _uniqueTimers[uniqueId] = ret; + } else { + _timers.add(ret); + } + + return ret; + } + + /// Cancel all active listeners, timers, close the controllers + /// and disposes other disposables bound with [bind]. + /// + /// You should not use this class after it's disposal. + /// If you only want to cancel/clear stuff, use [cancelBindings]. + Future dispose() async { + _canceling = true; + + final ret = []; + + if (_parent != null) { + _parent!._disposables.remove(this); + } + + final disposables = _disposables; + _disposables = {}; + + for (var disposable in disposables) { + ret.add(disposable.dispose()); + } + + assert(_disposables.isEmpty); + + ret.add(cancelBindings()); + + await Future.wait(ret); + _canceling = false; + } + + /// Cancel all active listeners, timers and close the controllers. + /// This *does not* dispose other disposables bound with [bind]. + /// + /// [dispose] calls this function internally. + Future cancelBindings() { + final ret = []; + final subs = _subs; + final uniques = _uniqueSubs; + final ctrls = _ctrls; + final timers = _timers; + final utimers = _uniqueTimers; + final listeners = _uniqueListeners; + + _subs = {}; + _uniqueSubs = {}; + _ctrls = {}; + _timers = {}; + _uniqueTimers = {}; + _uniqueListeners = {}; + + for (final s in subs) { + ret.add(s.cancel()); + } + + for (final s in uniques.values) { + ret.add(s.cancel()); + } + + for (final tup in listeners.values) { + tup.item1.removeListener(tup.item2); + } + + for (final c in ctrls) { + ret.add(c.close()); + } + + for (final t in timers) { + t.cancel(); + } + + for (final t in utimers.values) { + t.cancel(); + } + + return Future.wait(ret); + } + + /// Creates a [Timer] that gets cancelled within [dispose] if not executed. + /// + /// Set [uniqueId] to some [Symbol] to make this timer unique. + /// This means that we will cancel the previous timer with same symbol + /// before assigning a new one. + Timer timer(Duration duration, Function() fn) { + late _Timer ret; + final tm = Timer(duration, () { + ret._rem(); + fn(); + }); + ret = _timer(tm); + + return ret; + } + + /// Creates a [Timer] that gets cancelled within [dispose] if not executed. + /// + /// Set [uniqueId] to some [Symbol] to make this timer unique. + /// This means that we will cancel the previous timer with same symbol + /// before assigning a new one. + Timer uniqueTimer(Symbol uniqueId, Duration duration, Function() fn) { + late _Timer ret; + final tm = Timer(duration, () { + ret._rem(); + fn(); + }); + ret = _timer(tm, uniqueId: uniqueId); + + return ret; + } +} \ No newline at end of file diff --git a/lib/src/deps/dispose/interval.dart b/lib/src/deps/dispose/interval.dart new file mode 100644 index 0000000..c14abf5 --- /dev/null +++ b/lib/src/deps/dispose/interval.dart @@ -0,0 +1,73 @@ +import 'dart:async'; + +class IntervalTimer implements Timer { + final FutureOr Function(IntervalTimer)? fn; + final Duration duration; + late bool _open; + @override + bool get isActive => _open; + int _tick = 0; + @override + int get tick => _tick; + + void _exec() async { + if (_open) { + await fn!(this); + _tick++; + + Timer(duration, _exec); + } + } + + void start() { + _open = true; + + return _exec(); + } + + @override + void cancel() { + _open = false; + } + + IntervalTimer(this.fn, this.duration, {bool execNow = true}) { + if (fn != null) { + if (execNow) { + start(); + } else { + Timer(duration, start); + } + } + } +} + +class StreamedIntervalTimer extends IntervalTimer { + T? _obj; + + @override + // ignore: overridden_fields + FutureOr Function(IntervalTimer)? fn; + + void add(T item) { + _obj = item; + } + + void clear() { + _obj = null; + } + + StreamedIntervalTimer(FutureOr Function(T?) func, + Duration duration, {bool execNow = true}): + super(null, duration, execNow: false) { + fn = (tm) { + func(_obj); + _obj = null; + }; + + if (execNow) { + start(); + } else { + Timer(duration, start); + } + } +} \ No newline at end of file diff --git a/lib/src/deps/disposer.dart b/lib/src/deps/disposer.dart new file mode 100644 index 0000000..d718e57 --- /dev/null +++ b/lib/src/deps/disposer.dart @@ -0,0 +1,189 @@ +import 'dart:async'; + +import 'package:meta/meta.dart'; + +const String _oneShotDisposerMemoryLeakWarning = + 'Possible memory leak detected: A disposable should not be added to ' + 'one shot disposers after the dispose() method has been called.'; + +/// A function, that when called, will cleanup any resources or subscriptions. +typedef DisposeFunction = void Function(); + +/// A class with a [dispose] method for cleaning up resources or subscriptions. +abstract class Disposable { + /// A disposable that does nothing. + // ignore: constant_identifier_names + static const Disposable Noop = _NoopDisposable(); + + /// Creates a simple disposable that just executes [disposeFn]. + factory Disposable(DisposeFunction disposeFn) = _SingleFunctionDisposable; + + /// Disposes this disposable and any resources it has open. + void dispose(); +} + +/// A no-op implementation of [Disposable]. +class _NoopDisposable implements Disposable { + const _NoopDisposable(); + + @override + void dispose() {} +} + +/// A simple implementation of [Disposable]. +class _SingleFunctionDisposable implements Disposable { + final DisposeFunction _disposeFn; + + _SingleFunctionDisposable(this._disposeFn); + + @override + void dispose() { + _disposeFn(); + } +} + +/// Tracks disposables that are added to it for later disposal. +/// +/// Example usage: +/// final disposer = new Disposer() +/// ..addDisposable(() => print('Clean up');) +/// ..addDisposable(stream.listen()) +/// ..addDisposable(myCustomDisposable); +/// +/// disposer.dispose(); +/// +/// Example usage of 'oneShot' mode. Please use this for cases where there +/// is a single call to dispose as it will help detect potential memory leaks +/// where a disposable is being added after the disposer has been disposed. +/// This is very typical for Angular components where disposer.dispose() is +/// called in ngOnDestroy. +/// +/// final disposer = new Disposer.oneShot() +/// ..addDisposable(() => print('Clean up');) +/// ..addDisposable(stream.listen()); +/// +/// disposer.dispose(); +/// // The following call will assert. +/// disposer.addDisposable(myCustomDisposable); +/// +/// Prefer typed functions whenever possible: +/// [addEventSink] +/// [addFunction] +/// [addStreamSubscription] +/// +/// Note that you should not rely on the disposal sequence for each added +/// [disposable], just treat it random. +class Disposer implements Disposable { + List? _disposeFunctions; + List>? _disposeSubs; + List>? _disposeSinks; + List? _disposeDisposables; + final bool _oneShot; + bool _disposeCalled = false; + + /// Pass [oneShot] as true if no disposables are meant to be added after + /// the dispose method is called. + @Deprecated("Please use oneShot or multi instead") + Disposer({bool oneShot = false}) : _oneShot = oneShot; + + /// Convenience constructor for one shot mode or single dispose mode. + Disposer.oneShot() : _oneShot = true; + + /// Convenience constructor for supporting multiple calls to dispose. + Disposer.multi() : _oneShot = false; + + /// Registers [disposable] for disposal when [dispose] is called later. + /// + /// Prefer typed functions whenever possible, as this is megamorphic: + /// [addEventSink] + /// [addStreamSubscription] + /// [addFunction] + T addDisposable(T disposable) { + // TODO(google): `disposable_` is a workaround to make this code + // strong-clean. We should be able to get rid of it once dartbug.com/26439 + // is addressed in the language. + dynamic disposable_ = disposable; + if (disposable_ is Disposable) { + _disposeDisposables ??= []; + _disposeDisposables!.add(disposable as Disposable); + _checkIfAlreadyDisposed(); + } else if (disposable_ is StreamSubscription) { + addStreamSubscription(disposable_); + } else if (disposable_ is EventSink) { + addEventSink(disposable_); + } else if (disposable_ is DisposeFunction) { + addFunction(disposable_); + } else { + throw ArgumentError.value(disposable, 'disposable'); + } + return disposable; + } + + /// Registers [disposable]. + StreamSubscription? addStreamSubscription( + StreamSubscription? disposable) { + _disposeSubs ??= []; + if (disposable != null) { + _disposeSubs?.add(disposable); + } + _checkIfAlreadyDisposed(); + return disposable; + } + + /// Registers [disposable]. + EventSink addEventSink(EventSink disposable) { + _disposeSinks ??= []; + _disposeSinks!.add(disposable); + _checkIfAlreadyDisposed(); + return disposable; + } + + /// Registers [disposable]. + DisposeFunction addFunction(DisposeFunction disposable) { + // TODO(GZGavinZhao): not sure why it's here... Maybe future needs this. + // assert(disposable != null); + _disposeFunctions ??= []; + _disposeFunctions!.add(disposable); + _checkIfAlreadyDisposed(); + return disposable; + } + + // In dev-mode, throws if a oneShot disposer was already disposed. + void _checkIfAlreadyDisposed() { + assert(!(_oneShot && _disposeCalled), _oneShotDisposerMemoryLeakWarning); + } + + @mustCallSuper + @override + void dispose() { + if (_disposeSubs != null) { + int len = _disposeSubs!.length; + for (var i = 0; i < len; i++) { + _disposeSubs![i].cancel(); + } + _disposeSubs = null; + } + if (_disposeSinks != null) { + int len = _disposeSinks!.length; + for (var i = 0; i < len; i++) { + _disposeSinks![i].close(); + } + _disposeSinks = null; + } + if (_disposeDisposables != null) { + int len = _disposeDisposables!.length; + for (var i = 0; i < len; i++) { + _disposeDisposables![i].dispose(); + } + _disposeDisposables = null; + } + if (_disposeFunctions != null) { + int len = _disposeFunctions!.length; + for (var i = 0; i < len; i++) { + _disposeFunctions![i](); + } + _disposeFunctions = null; + } + _disposeCalled = true; + } +} diff --git a/lib/src/deps/tuple.dart b/lib/src/deps/tuple.dart new file mode 100644 index 0000000..77edd02 --- /dev/null +++ b/lib/src/deps/tuple.dart @@ -0,0 +1,463 @@ +/// # Tuple data structure +/// +/// - [Tuple2], [Tuple3]... +/// +/// ## Usage example +/// +/// ```dart +/// const t = const Tuple2('a', 10); +/// +/// print(t.item1); // prints 'a' +/// print(t.item2); // prints '10' +/// ``` +/// +/// ```dart +/// const t1 = const Tuple2('a', 10); +/// final t2 = t1.withItem1('c'); +/// // t2 is a new [Tuple2] object with item1 is 'c' and item2 is 10. +/// ``` + +/// Represents a 2-tuple, or pair. +class Tuple2 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Creates a new tuple value with the specified items. + const Tuple2(this.item1, this.item2); + + /// Create a new tuple value with the specified list [items]. + factory Tuple2.fromList(List items) { + if (items.length != 2) { + throw ArgumentError('items must have length 2'); + } + + return Tuple2(items[0] as T1, items[1] as T2); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple2 withItem1(T1 v) => Tuple2(v, item2); + + /// Returns a tuple with the second item set to the specified value. + Tuple2 withItem2(T2 v) => Tuple2(item1, v); + + /// Creates a [List] containing the items of this [Tuple2]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2], growable: growable); + + @override + String toString() => '[$item1, $item2]'; + + @override + bool operator ==(Object other) => + other is Tuple2 && other.item1 == item1 && other.item2 == item2; + + @override + int get hashCode => Object.hash(item1.hashCode, item2.hashCode); +} + +/// Represents a 3-tuple, or triple. +class Tuple3 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Returns the third item of the tuple + final T3 item3; + + /// Creates a new tuple value with the specified items. + const Tuple3(this.item1, this.item2, this.item3); + + /// Create a new tuple value with the specified list [items]. + factory Tuple3.fromList(List items) { + if (items.length != 3) { + throw ArgumentError('items must have length 3'); + } + + return Tuple3(items[0] as T1, items[1] as T2, items[2] as T3); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple3 withItem1(T1 v) => Tuple3(v, item2, item3); + + /// Returns a tuple with the second item set to the specified value. + Tuple3 withItem2(T2 v) => Tuple3(item1, v, item3); + + /// Returns a tuple with the third item set to the specified value. + Tuple3 withItem3(T3 v) => Tuple3(item1, item2, v); + + /// Creates a [List] containing the items of this [Tuple3]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2, item3], growable: growable); + + @override + String toString() => '[$item1, $item2, $item3]'; + + @override + bool operator ==(Object other) => + other is Tuple3 && + other.item1 == item1 && + other.item2 == item2 && + other.item3 == item3; + + @override + int get hashCode => + Object.hash(item1.hashCode, item2.hashCode, item3.hashCode); +} + +/// Represents a 4-tuple, or quadruple. +class Tuple4 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Returns the third item of the tuple + final T3 item3; + + /// Returns the fourth item of the tuple + final T4 item4; + + /// Creates a new tuple value with the specified items. + const Tuple4(this.item1, this.item2, this.item3, this.item4); + + /// Create a new tuple value with the specified list [items]. + factory Tuple4.fromList(List items) { + if (items.length != 4) { + throw ArgumentError('items must have length 4'); + } + + return Tuple4( + items[0] as T1, items[1] as T2, items[2] as T3, items[3] as T4); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple4 withItem1(T1 v) => + Tuple4(v, item2, item3, item4); + + /// Returns a tuple with the second item set to the specified value. + Tuple4 withItem2(T2 v) => + Tuple4(item1, v, item3, item4); + + /// Returns a tuple with the third item set to the specified value. + Tuple4 withItem3(T3 v) => + Tuple4(item1, item2, v, item4); + + /// Returns a tuple with the fourth item set to the specified value. + Tuple4 withItem4(T4 v) => + Tuple4(item1, item2, item3, v); + + /// Creates a [List] containing the items of this [Tuple4]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2, item3, item4], growable: growable); + + @override + String toString() => '[$item1, $item2, $item3, $item4]'; + + @override + bool operator ==(Object other) => + other is Tuple4 && + other.item1 == item1 && + other.item2 == item2 && + other.item3 == item3 && + other.item4 == item4; + + @override + int get hashCode => Object.hash( + item1.hashCode, item2.hashCode, item3.hashCode, item4.hashCode); +} + +/// Represents a 5-tuple, or quintuple. +class Tuple5 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Returns the third item of the tuple + final T3 item3; + + /// Returns the fourth item of the tuple + final T4 item4; + + /// Returns the fifth item of the tuple + final T5 item5; + + /// Creates a new tuple value with the specified items. + const Tuple5(this.item1, this.item2, this.item3, this.item4, this.item5); + + /// Create a new tuple value with the specified list [items]. + factory Tuple5.fromList(List items) { + if (items.length != 5) { + throw ArgumentError('items must have length 5'); + } + + return Tuple5(items[0] as T1, items[1] as T2, + items[2] as T3, items[3] as T4, items[4] as T5); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple5 withItem1(T1 v) => + Tuple5(v, item2, item3, item4, item5); + + /// Returns a tuple with the second item set to the specified value. + Tuple5 withItem2(T2 v) => + Tuple5(item1, v, item3, item4, item5); + + /// Returns a tuple with the third item set to the specified value. + Tuple5 withItem3(T3 v) => + Tuple5(item1, item2, v, item4, item5); + + /// Returns a tuple with the fourth item set to the specified value. + Tuple5 withItem4(T4 v) => + Tuple5(item1, item2, item3, v, item5); + + /// Returns a tuple with the fifth item set to the specified value. + Tuple5 withItem5(T5 v) => + Tuple5(item1, item2, item3, item4, v); + + /// Creates a [List] containing the items of this [Tuple5]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2, item3, item4, item5], growable: growable); + + @override + String toString() => '[$item1, $item2, $item3, $item4, $item5]'; + + @override + bool operator ==(Object other) => + other is Tuple5 && + other.item1 == item1 && + other.item2 == item2 && + other.item3 == item3 && + other.item4 == item4 && + other.item5 == item5; + + @override + int get hashCode => Object.hashAll([ + item1.hashCode, + item2.hashCode, + item3.hashCode, + item4.hashCode, + item5.hashCode + ]); +} + +/// Represents a 6-tuple, or sextuple. +class Tuple6 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Returns the third item of the tuple + final T3 item3; + + /// Returns the fourth item of the tuple + final T4 item4; + + /// Returns the fifth item of the tuple + final T5 item5; + + /// Returns the sixth item of the tuple + final T6 item6; + + /// Creates a new tuple value with the specified items. + const Tuple6( + this.item1, this.item2, this.item3, this.item4, this.item5, this.item6); + + /// Create a new tuple value with the specified list [items]. + factory Tuple6.fromList(List items) { + if (items.length != 6) { + throw ArgumentError('items must have length 6'); + } + + return Tuple6(items[0] as T1, items[1] as T2, + items[2] as T3, items[3] as T4, items[4] as T5, items[5] as T6); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple6 withItem1(T1 v) => + Tuple6(v, item2, item3, item4, item5, item6); + + /// Returns a tuple with the second item set to the specified value. + Tuple6 withItem2(T2 v) => + Tuple6(item1, v, item3, item4, item5, item6); + + /// Returns a tuple with the third item set to the specified value. + Tuple6 withItem3(T3 v) => + Tuple6(item1, item2, v, item4, item5, item6); + + /// Returns a tuple with the fourth item set to the specified value. + Tuple6 withItem4(T4 v) => + Tuple6(item1, item2, item3, v, item5, item6); + + /// Returns a tuple with the fifth item set to the specified value. + Tuple6 withItem5(T5 v) => + Tuple6(item1, item2, item3, item4, v, item6); + + /// Returns a tuple with the sixth item set to the specified value. + Tuple6 withItem6(T6 v) => + Tuple6(item1, item2, item3, item4, item5, v); + + /// Creates a [List] containing the items of this [Tuple5]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2, item3, item4, item5, item6], growable: growable); + + @override + String toString() => '[$item1, $item2, $item3, $item4, $item5, $item6]'; + + @override + bool operator ==(Object other) => + other is Tuple6 && + other.item1 == item1 && + other.item2 == item2 && + other.item3 == item3 && + other.item4 == item4 && + other.item5 == item5 && + other.item6 == item6; + + @override + int get hashCode => Object.hashAll([ + item1.hashCode, + item2.hashCode, + item3.hashCode, + item4.hashCode, + item5.hashCode, + item6.hashCode + ]); +} + +/// Represents a 7-tuple, or septuple. +class Tuple7 { + /// Returns the first item of the tuple + final T1 item1; + + /// Returns the second item of the tuple + final T2 item2; + + /// Returns the third item of the tuple + final T3 item3; + + /// Returns the fourth item of the tuple + final T4 item4; + + /// Returns the fifth item of the tuple + final T5 item5; + + /// Returns the sixth item of the tuple + final T6 item6; + + /// Returns the seventh item of the tuple + final T7 item7; + + /// Creates a new tuple value with the specified items. + const Tuple7(this.item1, this.item2, this.item3, this.item4, this.item5, + this.item6, this.item7); + + /// Create a new tuple value with the specified list [items]. + factory Tuple7.fromList(List items) { + if (items.length != 7) { + throw ArgumentError('items must have length 7'); + } + + return Tuple7( + items[0] as T1, + items[1] as T2, + items[2] as T3, + items[3] as T4, + items[4] as T5, + items[5] as T6, + items[6] as T7); + } + + /// Returns a tuple with the first item set to the specified value. + Tuple7 withItem1(T1 v) => + Tuple7( + v, item2, item3, item4, item5, item6, item7); + + /// Returns a tuple with the second item set to the specified value. + Tuple7 withItem2(T2 v) => + Tuple7( + item1, v, item3, item4, item5, item6, item7); + + /// Returns a tuple with the third item set to the specified value. + Tuple7 withItem3(T3 v) => + Tuple7( + item1, item2, v, item4, item5, item6, item7); + + /// Returns a tuple with the fourth item set to the specified value. + Tuple7 withItem4(T4 v) => + Tuple7( + item1, item2, item3, v, item5, item6, item7); + + /// Returns a tuple with the fifth item set to the specified value. + Tuple7 withItem5(T5 v) => + Tuple7( + item1, item2, item3, item4, v, item6, item7); + + /// Returns a tuple with the sixth item set to the specified value. + Tuple7 withItem6(T6 v) => + Tuple7( + item1, item2, item3, item4, item5, v, item7); + + /// Returns a tuple with the seventh item set to the specified value. + Tuple7 withItem7(T7 v) => + Tuple7( + item1, item2, item3, item4, item5, item6, v); + + /// Creates a [List] containing the items of this [Tuple5]. + /// + /// The elements are in item order. The list is variable-length + /// if [growable] is true. + List toList({bool growable = false}) => + List.from([item1, item2, item3, item4, item5, item6, item7], + growable: growable); + + @override + String toString() => + '[$item1, $item2, $item3, $item4, $item5, $item6, $item7]'; + + @override + bool operator ==(Object other) => + other is Tuple7 && + other.item1 == item1 && + other.item2 == item2 && + other.item3 == item3 && + other.item4 == item4 && + other.item5 == item5 && + other.item6 == item6 && + other.item7 == item7; + + @override + int get hashCode => Object.hashAll([ + item1.hashCode, + item2.hashCode, + item3.hashCode, + item4.hashCode, + item5.hashCode, + item6.hashCode, + item7.hashCode + ]); +} diff --git a/pubspec.lock b/pubspec.lock index 436ffe9..3ae1116 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,661 +5,801 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" source: hosted - version: "30.0.0" + version: "67.0.0" analyzer: - dependency: transitive + dependency: "direct overridden" description: name: analyzer - url: "https://pub.dartlang.org" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" source: hosted - version: "2.7.0" - angular: - dependency: "direct main" - description: - name: angular - url: "https://pub.dartlang.org" - source: hosted - version: "7.0.2" - angular_ast: - dependency: transitive - description: - name: angular_ast - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - angular_compiler: - dependency: transitive - description: - name: angular_compiler - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - angular_components: - dependency: "direct main" - description: - path: "../angular_components/angular_components" - relative: true - source: path - version: "2.0.0" - angular_forms: - dependency: transitive - description: - name: angular_forms - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.1" + version: "6.4.1" archive: dependency: transitive description: name: archive - url: "https://pub.dartlang.org" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.4.10" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.2" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.8.2" + version: "2.11.0" bazel_worker: dependency: transitive description: name: bazel_worker - url: "https://pub.dartlang.org" + sha256: "6f306845d941808bed2fdbd7db3a39de273a8248a9303cfebf0cfa861372616e" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" build: - dependency: "direct main" + dependency: transitive description: name: build - url: "https://pub.dartlang.org" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - url: "https://pub.dartlang.org" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - url: "https://pub.dartlang.org" + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "4.0.1" build_modules: - dependency: transitive + dependency: "direct overridden" description: name: build_modules - url: "https://pub.dartlang.org" + sha256: "66f0f746a239ff6cceba9d235a679ec70a6d9037ddddb36a24a0791a639a8486" + url: "https://pub.dev" source: hosted - version: "4.0.3" + version: "5.0.7" build_resolvers: dependency: transitive description: name: build_resolvers - url: "https://pub.dartlang.org" + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - url: "https://pub.dartlang.org" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.4.8" build_runner_core: dependency: transitive description: name: build_runner_core - url: "https://pub.dartlang.org" + sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" + url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "7.3.0" build_test: - dependency: transitive + dependency: "direct dev" description: name: build_test - url: "https://pub.dartlang.org" + sha256: "260dbba934f41b0a42935e9cae1f5731b94f0c3e489dc97bcf8e281265aaa5ae" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.2" build_web_compilers: dependency: "direct dev" description: name: build_web_compilers - url: "https://pub.dartlang.org" + sha256: aad1d705faa53d060e7ccb7855ee74705a8e3d9ea1634e63e362cc2c1bd47afa + url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "4.0.9" built_collection: dependency: transitive description: name: built_collection - url: "https://pub.dartlang.org" + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" source: hosted version: "5.1.1" built_value: dependency: transitive description: name: built_value - url: "https://pub.dartlang.org" + sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6 + url: "https://pub.dev" + source: hosted + version: "8.9.0" + change_notifier: + dependency: "direct main" + description: + name: change_notifier + sha256: "9a50ab5290b93a2f164d20a12998ef10571d57947b47f144296dc53cc24f4f5b" + url: "https://pub.dev" source: hosted - version: "8.1.3" + version: "0.24.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.dartlang.org" + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + url: "https://pub.dev" source: hosted version: "1.3.1" checked_yaml: dependency: transitive description: name: checked_yaml - url: "https://pub.dartlang.org" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" + cli_pkg: + dependency: transitive + description: + name: cli_pkg + sha256: "7b088621eb3d486c17a4122389d8b3f36658450d5a405fa229166b1a71a7ce4a" + url: "https://pub.dev" + source: hosted + version: "2.7.2" cli_repl: dependency: transitive description: name: cli_repl - url: "https://pub.dartlang.org" + sha256: a2ee06d98f211cb960c777519cb3d14e882acd90fe5e078668e3ab4baab0ddd4 + url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.2.3" cli_util: dependency: transitive description: name: cli_util - url: "https://pub.dartlang.org" + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.4.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" code_builder: dependency: transitive description: name: code_builder - url: "https://pub.dartlang.org" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.10.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.18.0" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.1" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.7.2" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.3" csslib: dependency: transitive description: name: csslib - url: "https://pub.dartlang.org" + sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" + url: "https://pub.dev" source: hosted - version: "0.17.1" + version: "0.17.3" dart_internal: dependency: transitive description: name: dart_internal - url: "https://pub.dartlang.org" + sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567" + url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.2.9" dart_style: dependency: transitive description: name: dart_style - url: "https://pub.dartlang.org" + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + url: "https://pub.dev" source: hosted - version: "2.2.0" - dispose: - dependency: "direct main" + version: "2.3.4" + ffi: + dependency: transitive description: - name: dispose - url: "https://pub.dartlang.org" + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" source: hosted - version: "0.0.7" + version: "2.1.0" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "7.0.0" fixnum: dependency: transitive description: name: fixnum - url: "https://pub.dartlang.org" + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" frontend_server_client: dependency: transitive description: name: frontend_server_client - url: "https://pub.dartlang.org" + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "3.2.0" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.2" graphs: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.1" + grinder: + dependency: transitive + description: + name: grinder + sha256: e1996e485d2b56bb164a8585679758d488fbf567273f51c432c8733fee1f6188 + url: "https://pub.dev" + source: hosted + version: "0.9.5" html: dependency: transitive description: name: html - url: "https://pub.dartlang.org" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" source: hosted - version: "0.15.0" + version: "0.15.4" http: dependency: transitive description: name: http - url: "https://pub.dartlang.org" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + url: "https://pub.dev" source: hosted - version: "0.13.4" + version: "1.2.0" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.2.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" intl: dependency: transitive description: name: intl - url: "https://pub.dartlang.org" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" source: hosted - version: "0.6.3" + version: "0.6.7" json_annotation: dependency: transitive description: name: json_annotation - url: "https://pub.dartlang.org" + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" source: hosted - version: "4.3.0" - lib_colors: - dependency: "direct main" - description: - path: "../lib_colors" - relative: true - source: path - version: "1.0.18" + version: "4.8.1" lints: dependency: "direct dev" description: name: lints - url: "https://pub.dartlang.org" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "2.1.1" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.2.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" source: hosted - version: "0.12.11" + version: "0.12.16+1" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.11.0" mime: dependency: transitive description: name: mime - url: "https://pub.dartlang.org" + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.5" + native_synchronization: + dependency: transitive + description: + name: native_synchronization + sha256: ff200fe0a64d733ff7d4dde2005271c297db81007604c8cd21037959858133ab + url: "https://pub.dev" + source: hosted + version: "0.2.0" + ngast: + dependency: transitive + description: + name: ngast + sha256: "681f2099cd8d20868e4309ebd9f2c20596c220c041966a22ce2f7d81b21ec951" + url: "https://pub.dev" + source: hosted + version: "3.0.0-dev.0" + ngcompiler: + dependency: transitive + description: + name: ngcompiler + sha256: "9cd0f122b872cb42c1b6ef5c8f2f6d64eacfdc5d8dbd97a38a4e3346b8d3d0d6" + url: "https://pub.dev" + source: hosted + version: "3.0.0-dev.1" + ngdart: + dependency: "direct main" + description: + name: ngdart + sha256: "0d92d05a9dadef120b0eaee34ffd417f8608066ba0ce1e69958290c08d440b84" + url: "https://pub.dev" + source: hosted + version: "8.0.0-dev.2" + ngforms: + dependency: "direct main" + description: + name: ngforms + sha256: "05c49fc995177d8eccae4fc617576da621ccde62e98f5210f9dbbeefa7448292" + url: "https://pub.dev" + source: hosted + version: "5.0.0-dev.1" + ngrouter: + dependency: "direct main" + description: + name: ngrouter + sha256: f5d8a746c7225a8a6c6c500ba69acb509a1caa195a6262de15563319262c2af0 + url: "https://pub.dev" + source: hosted + version: "4.0.0-dev.1" node_interop: dependency: transitive description: name: node_interop - url: "https://pub.dartlang.org" + sha256: "3af2420c728173806f4378cf89c53ba9f27f7f67792b898561bff9d390deb98e" + url: "https://pub.dev" source: hosted version: "2.1.0" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" source: hosted - version: "2.0.1" - observable: - dependency: transitive - description: - path: "." - ref: HEAD - resolved-ref: "8c49e71daa4c4d41e9103c4c562a8f3e9cecdd61" - url: "https://github.com/google/observable" - source: git - version: "0.24.0-dev" + version: "2.0.2" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.0" - pedantic: + version: "1.9.0" + petitparser: dependency: transitive description: - name: pedantic - url: "https://pub.dartlang.org" + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "6.0.2" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + url: "https://pub.dev" + source: hosted + version: "3.7.4" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.5.1" protobuf: dependency: transitive description: name: protobuf - url: "https://pub.dartlang.org" + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.1.0" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - url: "https://pub.dartlang.org" + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.3" quiver: dependency: transitive description: name: quiver - url: "https://pub.dartlang.org" + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" source: hosted - version: "3.0.1+1" + version: "3.2.1" + retry: + dependency: transitive + description: + name: retry + sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sass: dependency: transitive description: name: sass - url: "https://pub.dartlang.org" + sha256: f5b39a1f2601d5a67d5a83a8f6d03de8418a88f545e108df7e59f100fe8db1dd + url: "https://pub.dev" source: hosted - version: "1.43.4" + version: "1.70.0" sass_builder: dependency: "direct main" description: name: sass_builder - url: "https://pub.dartlang.org" + sha256: "8f714e91a19272b7f0b68a5a100c8c000f3101731288376fdcbfb0e464274eb5" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" scratch_space: dependency: transitive description: name: scratch_space - url: "https://pub.dartlang.org" + sha256: "8510fbff458d733a58fc427057d1ac86303b376d609d6e1bc43f240aad9aa445" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.4" source_gen: dependency: transitive description: name: source_gen - url: "https://pub.dartlang.org" + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.5.0" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" source: hosted - version: "0.10.10" + version: "0.10.12" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" stream_transform: - dependency: "direct main" + dependency: transitive description: name: stream_transform - url: "https://pub.dartlang.org" + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" test: - dependency: transitive + dependency: "direct dev" description: name: test - url: "https://pub.dartlang.org" + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + url: "https://pub.dev" source: hosted - version: "1.19.3" + version: "1.25.2" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" source: hosted - version: "0.4.7" + version: "0.7.0" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + url: "https://pub.dev" source: hosted - version: "0.4.8" - timing: + version: "0.6.0" + test_process: dependency: transitive description: - name: timing - url: "https://pub.dartlang.org" + name: test_process + sha256: "217f19b538926e4922bdb2a01410100ec4e3beb4cc48eae5ae6b20037b07bbd6" + url: "https://pub.dev" source: hosted - version: "1.0.0" - tuple: + version: "2.1.0" + timing: dependency: transitive description: - name: tuple - url: "https://pub.dartlang.org" + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: a2662fb1f114f4296cf3f5a50786a2d888268d7776cf681aa17d660ffa23b246 + url: "https://pub.dev" source: hosted - version: "7.4.0" + version: "14.0.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05" + url: "https://pub.dev" + source: hosted + version: "0.4.2" web_socket_channel: dependency: transitive description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.4.3" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.2.1" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" sdks: - dart: ">=2.14.0 <2.16.0" + dart: ">=3.2.0 <3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2e5150f..92bbed0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,24 +1,28 @@ name: ng_color_picker description: Simple and lightweight color picker component for AngularDart -version: 0.0.2 +version: 1.0.0 homepage: https://jodinathan.github.io/ng_color_picker/ environment: - sdk: '>=2.12.0 <3.0.0' + sdk: ^3.2.0 dependencies: - angular: ^7.0.2 - angular_components: - path: ../angular_components/angular_components - build: ^2.1.1 - lib_colors: - path: ../lib_colors + ngdart: ^8.0.0-dev.2 + ngrouter: ^4.0.0-dev.1 + ngforms: ^5.0.0-dev.1 sass_builder: ^2.1.4 - dispose: ^0.0.7 - stream_transform: ^2.0.0 + change_notifier: ^0.24.0 + # dispose: ^0.0.7 + # stream_transform: ^2.0.0 -dev_dependencies: - build_runner: ^2.1.5 - build_web_compilers: ^3.2.1 - lints: ^1.0.1 +dev_dependencies: + build_runner: ^2.1.2 + build_test: ^2.1.3 + build_web_compilers: ^4.0.0 + lints: ^2.1.0 + test: ^1.24.0 + +dependency_overrides: + build_modules: ^5.0.0 + analyzer: ^6.4.1