From b1f51a81f4fc11956dcd1c300d4dd1949821599d Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Thu, 6 May 2021 22:46:14 +0200 Subject: [PATCH 01/14] migrate to vuepress successfully --- .gitignore | 35 +- .prettierrc | 22 + .travis.yml | 9 - CNAME | 1 - ISSUE_TEMPLATE.md | 11 - LICENSE | 2 +- README.md | 31 +- css/site.css | 177 - gulpfile.js | 27 - index.html | 98 - package.json | 54 +- pages/community.html | 37 - pages/docs.html | 42 - pages/home.html | 406 - pages/support.html | 42 - src/.vuepress/config.js | 99 + src/.vuepress/defaults/navbar.js | 19 + src/.vuepress/enhanceApp.js | 14 + src/.vuepress/locales/en.js | 56 + src/.vuepress/locales/es.js | 56 + src/.vuepress/locales/ro.js | 56 + {img => src/.vuepress/public}/angular.png | Bin {img => src/.vuepress/public}/basics.png | Bin {img => src/.vuepress/public}/bg.jpg | Bin {img => src/.vuepress/public}/browserify.png | Bin .../.vuepress/public}/coming-soon-ribbon.png | Bin {img => src/.vuepress/public}/cover.jpg | Bin {img => src/.vuepress/public}/devtools1.png | Bin {img => src/.vuepress/public}/devtools2.png | Bin {img => src/.vuepress/public}/devtools3.png | Bin {img => src/.vuepress/public}/ember.png | Bin .../.vuepress/public}/favicon/Thumbs.db | Bin .../public}/favicon/android-icon-144x144.png | Bin .../public}/favicon/android-icon-192x192.png | Bin .../public}/favicon/android-icon-36x36.png | Bin .../public}/favicon/android-icon-48x48.png | Bin .../public}/favicon/android-icon-72x72.png | Bin .../public}/favicon/android-icon-96x96.png | Bin .../public}/favicon/apple-icon-114x114.png | Bin .../public}/favicon/apple-icon-120x120.png | Bin .../public}/favicon/apple-icon-144x144.png | Bin .../public}/favicon/apple-icon-152x152.png | Bin .../public}/favicon/apple-icon-180x180.png | Bin .../public}/favicon/apple-icon-57x57.png | Bin .../public}/favicon/apple-icon-60x60.png | Bin .../public}/favicon/apple-icon-72x72.png | Bin .../public}/favicon/apple-icon-76x76.png | Bin .../favicon/apple-icon-precomposed.png | Bin .../.vuepress/public}/favicon/apple-icon.png | Bin .../public}/favicon/browserconfig.xml | 0 .../public}/favicon/favicon-16x16.png | Bin .../public}/favicon/favicon-32x32.png | Bin .../public}/favicon/favicon-96x96.png | Bin .../.vuepress/public}/favicon/favicon.ico | Bin .../.vuepress/public}/favicon/manifest.json | 0 .../public}/favicon/ms-icon-144x144.png | Bin .../public}/favicon/ms-icon-150x150.png | Bin .../public}/favicon/ms-icon-310x310.png | Bin .../public}/favicon/ms-icon-70x70.png | Bin {img => src/.vuepress/public}/forkme.png | Bin {img => src/.vuepress/public}/header-1.jpg | Bin {img => src/.vuepress/public}/logo.png | Bin .../.vuepress/public}/logo_inverse.png | Bin .../.vuepress/public}/logo_transparent.svg | 0 {img => src/.vuepress/public}/marionette.png | Bin {img => src/.vuepress/public}/node.png | Bin {img => src/.vuepress/public}/plug.jpg | Bin {img => src/.vuepress/public}/require.png | Bin {img => src/.vuepress/public}/so.png | Bin {img => src/.vuepress/public}/ts.png | Bin .../.vuepress/public}/twitter-ribbon.png | Bin {img => src/.vuepress/public}/universal.png | Bin src/.vuepress/seo/default.js | 21 + src/.vuepress/styles/palette.styl | 1 + .../theme/components/AlgoliaSearchBox.vue | 172 + .../theme/components/DropdownLink.vue | 252 + .../theme/components/DropdownTransition.vue | 33 + src/.vuepress/theme/components/Home.vue | 207 + src/.vuepress/theme/components/NavLink.vue | 90 + src/.vuepress/theme/components/NavLinks.vue | 156 + src/.vuepress/theme/components/Navbar.vue | 145 + src/.vuepress/theme/components/Page.vue | 31 + src/.vuepress/theme/components/PageEdit.vue | 155 + src/.vuepress/theme/components/PageNav.vue | 163 + src/.vuepress/theme/components/Sidebar.vue | 61 + .../theme/components/SidebarButton.vue | 40 + .../theme/components/SidebarGroup.vue | 141 + .../theme/components/SidebarLink.vue | 133 + .../theme/components/SidebarLinks.vue | 106 + .../theme/global-components/Badge.vue | 44 + .../theme/global-components/CodeBlock.vue | 41 + .../theme/global-components/CodeGroup.vue | 120 + src/.vuepress/theme/index.js | 71 + src/.vuepress/theme/layouts/404.vue | 30 + src/.vuepress/theme/layouts/Layout.vue | 119 + src/.vuepress/theme/noopModule.js | 1 + src/.vuepress/theme/styles/arrow.styl | 22 + src/.vuepress/theme/styles/code.styl | 137 + src/.vuepress/theme/styles/config.styl | 1 + src/.vuepress/theme/styles/custom-blocks.styl | 44 + src/.vuepress/theme/styles/index.styl | 207 + src/.vuepress/theme/styles/mobile.styl | 37 + src/.vuepress/theme/styles/palette.styl | 1 + src/.vuepress/theme/styles/toc.styl | 3 + src/.vuepress/theme/styles/wrapper.styl | 9 + src/.vuepress/theme/util/index.js | 241 + src/.vuepress/utility/sidebarHelper.js | 33 + src/en/features-and-api/0_symbols_as_id.md | 54 + .../features-and-api/10_provider_injection.md | 307 + .../features-and-api/11_activation_handler.md | 67 + .../12_deactivation_handler.md | 90 + src/en/features-and-api/13_post_construct.md | 66 + src/en/features-and-api/14_middleware.md | 179 + src/en/features-and-api/15_multi_injection.md | 94 + src/en/features-and-api/16_tagged_bindings.md | 48 + .../17_custom_tag_decorators.md | 18 + src/en/features-and-api/18_named_bindings.md | 48 + src/en/features-and-api/19_default_targets.md | 104 + src/en/features-and-api/1_container_api.md | 811 ++ src/en/features-and-api/20_hierarchical_di.md | 30 + .../21_contextual_bindings.md | 105 + .../features-and-api/22_property_injection.md | 128 + .../23_circular_dependencies.md | 21 + src/en/features-and-api/24_inheritance.md | 260 + .../25_transitive_bindings.md | 62 + src/en/features-and-api/26_pre_destroy.md | 23 + .../features-and-api/2_container_modules.md | 65 + .../features-and-api/3_container_snapshots.md | 53 + src/en/features-and-api/4_scope.md | 104 + .../5_optional_dependencies.md | 87 + src/en/features-and-api/6_value_injection.md | 19 + .../7_constructor_injection.md | 54 + .../features-and-api/8_factory_injection.md | 79 + src/en/features-and-api/9_auto_factory.md | 32 + src/en/features-and-api/README.md | 168 + src/en/getting-started/README.md | 142 + src/en/index.md | 91 + src/en/introduction/README.md | 55 + src/en/why-inversifyjs/README.md | 129 + src/es/features-and-api/0_symbols_as_id.md | 54 + .../features-and-api/10_provider_injection.md | 307 + .../features-and-api/11_activation_handler.md | 67 + .../12_deactivation_handler.md | 90 + src/es/features-and-api/13_post_construct.md | 66 + src/es/features-and-api/14_middleware.md | 179 + src/es/features-and-api/15_multi_injection.md | 94 + src/es/features-and-api/16_tagged_bindings.md | 48 + .../17_custom_tag_decorators.md | 18 + src/es/features-and-api/18_named_bindings.md | 48 + src/es/features-and-api/19_default_targets.md | 104 + src/es/features-and-api/1_container_api.md | 811 ++ src/es/features-and-api/20_hierarchical_di.md | 30 + .../21_contextual_bindings.md | 105 + .../features-and-api/22_property_injection.md | 128 + .../23_circular_dependencies.md | 21 + src/es/features-and-api/24_inheritance.md | 260 + .../25_transitive_bindings.md | 62 + src/es/features-and-api/26_pre_destroy.md | 23 + .../features-and-api/2_container_modules.md | 65 + .../features-and-api/3_container_snapshots.md | 53 + src/es/features-and-api/4_scope.md | 104 + .../5_optional_dependencies.md | 87 + src/es/features-and-api/6_value_injection.md | 19 + .../7_constructor_injection.md | 54 + .../features-and-api/8_factory_injection.md | 79 + src/es/features-and-api/9_auto_factory.md | 32 + src/es/features-and-api/README.md | 168 + src/es/getting-started/README.md | 142 + src/es/index.md | 91 + src/es/introduction/README.md | 55 + src/es/why-inversifyjs/README.md | 129 + src/index.md | 91 + src/language.md | 21 + src/main.js | 42 - src/ro/features-and-api/0_symbols_as_id.md | 54 + .../features-and-api/10_provider_injection.md | 307 + .../features-and-api/11_activation_handler.md | 67 + .../12_deactivation_handler.md | 90 + src/ro/features-and-api/13_post_construct.md | 66 + src/ro/features-and-api/14_middleware.md | 179 + src/ro/features-and-api/15_multi_injection.md | 94 + src/ro/features-and-api/16_tagged_bindings.md | 48 + .../17_custom_tag_decorators.md | 18 + src/ro/features-and-api/18_named_bindings.md | 48 + src/ro/features-and-api/19_default_targets.md | 104 + src/ro/features-and-api/1_container_api.md | 811 ++ src/ro/features-and-api/20_hierarchical_di.md | 30 + .../21_contextual_bindings.md | 105 + .../features-and-api/22_property_injection.md | 128 + .../23_circular_dependencies.md | 21 + src/ro/features-and-api/24_inheritance.md | 260 + .../25_transitive_bindings.md | 62 + src/ro/features-and-api/26_pre_destroy.md | 23 + .../features-and-api/2_container_modules.md | 65 + .../features-and-api/3_container_snapshots.md | 53 + src/ro/features-and-api/4_scope.md | 104 + .../5_optional_dependencies.md | 87 + src/ro/features-and-api/6_value_injection.md | 19 + .../7_constructor_injection.md | 54 + .../features-and-api/8_factory_injection.md | 79 + src/ro/features-and-api/9_auto_factory.md | 32 + src/ro/features-and-api/README.md | 168 + src/ro/getting-started/README.md | 142 + src/ro/index.md | 91 + src/ro/introduction/README.md | 55 + src/ro/why-inversifyjs/README.md | 129 + yarn.lock | 8261 +++++++++++++++++ 207 files changed, 22602 insertions(+), 954 deletions(-) create mode 100644 .prettierrc delete mode 100644 .travis.yml delete mode 100644 CNAME delete mode 100644 ISSUE_TEMPLATE.md delete mode 100644 css/site.css delete mode 100644 gulpfile.js delete mode 100644 index.html delete mode 100644 pages/community.html delete mode 100644 pages/docs.html delete mode 100644 pages/home.html delete mode 100644 pages/support.html create mode 100644 src/.vuepress/config.js create mode 100644 src/.vuepress/defaults/navbar.js create mode 100644 src/.vuepress/enhanceApp.js create mode 100644 src/.vuepress/locales/en.js create mode 100644 src/.vuepress/locales/es.js create mode 100644 src/.vuepress/locales/ro.js rename {img => src/.vuepress/public}/angular.png (100%) rename {img => src/.vuepress/public}/basics.png (100%) rename {img => src/.vuepress/public}/bg.jpg (100%) rename {img => src/.vuepress/public}/browserify.png (100%) rename {img => src/.vuepress/public}/coming-soon-ribbon.png (100%) rename {img => src/.vuepress/public}/cover.jpg (100%) rename {img => src/.vuepress/public}/devtools1.png (100%) rename {img => src/.vuepress/public}/devtools2.png (100%) rename {img => src/.vuepress/public}/devtools3.png (100%) rename {img => src/.vuepress/public}/ember.png (100%) rename {img => src/.vuepress/public}/favicon/Thumbs.db (100%) rename {img => src/.vuepress/public}/favicon/android-icon-144x144.png (100%) rename {img => src/.vuepress/public}/favicon/android-icon-192x192.png (100%) rename {img => src/.vuepress/public}/favicon/android-icon-36x36.png (100%) rename {img => src/.vuepress/public}/favicon/android-icon-48x48.png (100%) rename {img => src/.vuepress/public}/favicon/android-icon-72x72.png (100%) rename {img => src/.vuepress/public}/favicon/android-icon-96x96.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-114x114.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-120x120.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-144x144.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-152x152.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-180x180.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-57x57.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-60x60.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-72x72.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-76x76.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon-precomposed.png (100%) rename {img => src/.vuepress/public}/favicon/apple-icon.png (100%) rename {img => src/.vuepress/public}/favicon/browserconfig.xml (100%) rename {img => src/.vuepress/public}/favicon/favicon-16x16.png (100%) rename {img => src/.vuepress/public}/favicon/favicon-32x32.png (100%) rename {img => src/.vuepress/public}/favicon/favicon-96x96.png (100%) rename {img => src/.vuepress/public}/favicon/favicon.ico (100%) rename {img => src/.vuepress/public}/favicon/manifest.json (100%) rename {img => src/.vuepress/public}/favicon/ms-icon-144x144.png (100%) rename {img => src/.vuepress/public}/favicon/ms-icon-150x150.png (100%) rename {img => src/.vuepress/public}/favicon/ms-icon-310x310.png (100%) rename {img => src/.vuepress/public}/favicon/ms-icon-70x70.png (100%) rename {img => src/.vuepress/public}/forkme.png (100%) rename {img => src/.vuepress/public}/header-1.jpg (100%) rename {img => src/.vuepress/public}/logo.png (100%) rename {img => src/.vuepress/public}/logo_inverse.png (100%) rename {img => src/.vuepress/public}/logo_transparent.svg (100%) rename {img => src/.vuepress/public}/marionette.png (100%) rename {img => src/.vuepress/public}/node.png (100%) rename {img => src/.vuepress/public}/plug.jpg (100%) rename {img => src/.vuepress/public}/require.png (100%) rename {img => src/.vuepress/public}/so.png (100%) rename {img => src/.vuepress/public}/ts.png (100%) rename {img => src/.vuepress/public}/twitter-ribbon.png (100%) rename {img => src/.vuepress/public}/universal.png (100%) create mode 100644 src/.vuepress/seo/default.js create mode 100644 src/.vuepress/styles/palette.styl create mode 100644 src/.vuepress/theme/components/AlgoliaSearchBox.vue create mode 100644 src/.vuepress/theme/components/DropdownLink.vue create mode 100644 src/.vuepress/theme/components/DropdownTransition.vue create mode 100644 src/.vuepress/theme/components/Home.vue create mode 100644 src/.vuepress/theme/components/NavLink.vue create mode 100644 src/.vuepress/theme/components/NavLinks.vue create mode 100644 src/.vuepress/theme/components/Navbar.vue create mode 100644 src/.vuepress/theme/components/Page.vue create mode 100644 src/.vuepress/theme/components/PageEdit.vue create mode 100644 src/.vuepress/theme/components/PageNav.vue create mode 100644 src/.vuepress/theme/components/Sidebar.vue create mode 100644 src/.vuepress/theme/components/SidebarButton.vue create mode 100644 src/.vuepress/theme/components/SidebarGroup.vue create mode 100644 src/.vuepress/theme/components/SidebarLink.vue create mode 100644 src/.vuepress/theme/components/SidebarLinks.vue create mode 100644 src/.vuepress/theme/global-components/Badge.vue create mode 100644 src/.vuepress/theme/global-components/CodeBlock.vue create mode 100644 src/.vuepress/theme/global-components/CodeGroup.vue create mode 100644 src/.vuepress/theme/index.js create mode 100644 src/.vuepress/theme/layouts/404.vue create mode 100644 src/.vuepress/theme/layouts/Layout.vue create mode 100644 src/.vuepress/theme/noopModule.js create mode 100644 src/.vuepress/theme/styles/arrow.styl create mode 100644 src/.vuepress/theme/styles/code.styl create mode 100644 src/.vuepress/theme/styles/config.styl create mode 100644 src/.vuepress/theme/styles/custom-blocks.styl create mode 100644 src/.vuepress/theme/styles/index.styl create mode 100644 src/.vuepress/theme/styles/mobile.styl create mode 100644 src/.vuepress/theme/styles/palette.styl create mode 100644 src/.vuepress/theme/styles/toc.styl create mode 100644 src/.vuepress/theme/styles/wrapper.styl create mode 100644 src/.vuepress/theme/util/index.js create mode 100644 src/.vuepress/utility/sidebarHelper.js create mode 100644 src/en/features-and-api/0_symbols_as_id.md create mode 100644 src/en/features-and-api/10_provider_injection.md create mode 100644 src/en/features-and-api/11_activation_handler.md create mode 100644 src/en/features-and-api/12_deactivation_handler.md create mode 100644 src/en/features-and-api/13_post_construct.md create mode 100644 src/en/features-and-api/14_middleware.md create mode 100644 src/en/features-and-api/15_multi_injection.md create mode 100644 src/en/features-and-api/16_tagged_bindings.md create mode 100644 src/en/features-and-api/17_custom_tag_decorators.md create mode 100644 src/en/features-and-api/18_named_bindings.md create mode 100644 src/en/features-and-api/19_default_targets.md create mode 100644 src/en/features-and-api/1_container_api.md create mode 100644 src/en/features-and-api/20_hierarchical_di.md create mode 100644 src/en/features-and-api/21_contextual_bindings.md create mode 100644 src/en/features-and-api/22_property_injection.md create mode 100644 src/en/features-and-api/23_circular_dependencies.md create mode 100644 src/en/features-and-api/24_inheritance.md create mode 100644 src/en/features-and-api/25_transitive_bindings.md create mode 100644 src/en/features-and-api/26_pre_destroy.md create mode 100644 src/en/features-and-api/2_container_modules.md create mode 100644 src/en/features-and-api/3_container_snapshots.md create mode 100644 src/en/features-and-api/4_scope.md create mode 100644 src/en/features-and-api/5_optional_dependencies.md create mode 100644 src/en/features-and-api/6_value_injection.md create mode 100644 src/en/features-and-api/7_constructor_injection.md create mode 100644 src/en/features-and-api/8_factory_injection.md create mode 100644 src/en/features-and-api/9_auto_factory.md create mode 100644 src/en/features-and-api/README.md create mode 100644 src/en/getting-started/README.md create mode 100644 src/en/index.md create mode 100644 src/en/introduction/README.md create mode 100644 src/en/why-inversifyjs/README.md create mode 100644 src/es/features-and-api/0_symbols_as_id.md create mode 100644 src/es/features-and-api/10_provider_injection.md create mode 100644 src/es/features-and-api/11_activation_handler.md create mode 100644 src/es/features-and-api/12_deactivation_handler.md create mode 100644 src/es/features-and-api/13_post_construct.md create mode 100644 src/es/features-and-api/14_middleware.md create mode 100644 src/es/features-and-api/15_multi_injection.md create mode 100644 src/es/features-and-api/16_tagged_bindings.md create mode 100644 src/es/features-and-api/17_custom_tag_decorators.md create mode 100644 src/es/features-and-api/18_named_bindings.md create mode 100644 src/es/features-and-api/19_default_targets.md create mode 100644 src/es/features-and-api/1_container_api.md create mode 100644 src/es/features-and-api/20_hierarchical_di.md create mode 100644 src/es/features-and-api/21_contextual_bindings.md create mode 100644 src/es/features-and-api/22_property_injection.md create mode 100644 src/es/features-and-api/23_circular_dependencies.md create mode 100644 src/es/features-and-api/24_inheritance.md create mode 100644 src/es/features-and-api/25_transitive_bindings.md create mode 100644 src/es/features-and-api/26_pre_destroy.md create mode 100644 src/es/features-and-api/2_container_modules.md create mode 100644 src/es/features-and-api/3_container_snapshots.md create mode 100644 src/es/features-and-api/4_scope.md create mode 100644 src/es/features-and-api/5_optional_dependencies.md create mode 100644 src/es/features-and-api/6_value_injection.md create mode 100644 src/es/features-and-api/7_constructor_injection.md create mode 100644 src/es/features-and-api/8_factory_injection.md create mode 100644 src/es/features-and-api/9_auto_factory.md create mode 100644 src/es/features-and-api/README.md create mode 100644 src/es/getting-started/README.md create mode 100644 src/es/index.md create mode 100644 src/es/introduction/README.md create mode 100644 src/es/why-inversifyjs/README.md create mode 100644 src/index.md create mode 100644 src/language.md delete mode 100644 src/main.js create mode 100644 src/ro/features-and-api/0_symbols_as_id.md create mode 100644 src/ro/features-and-api/10_provider_injection.md create mode 100644 src/ro/features-and-api/11_activation_handler.md create mode 100644 src/ro/features-and-api/12_deactivation_handler.md create mode 100644 src/ro/features-and-api/13_post_construct.md create mode 100644 src/ro/features-and-api/14_middleware.md create mode 100644 src/ro/features-and-api/15_multi_injection.md create mode 100644 src/ro/features-and-api/16_tagged_bindings.md create mode 100644 src/ro/features-and-api/17_custom_tag_decorators.md create mode 100644 src/ro/features-and-api/18_named_bindings.md create mode 100644 src/ro/features-and-api/19_default_targets.md create mode 100644 src/ro/features-and-api/1_container_api.md create mode 100644 src/ro/features-and-api/20_hierarchical_di.md create mode 100644 src/ro/features-and-api/21_contextual_bindings.md create mode 100644 src/ro/features-and-api/22_property_injection.md create mode 100644 src/ro/features-and-api/23_circular_dependencies.md create mode 100644 src/ro/features-and-api/24_inheritance.md create mode 100644 src/ro/features-and-api/25_transitive_bindings.md create mode 100644 src/ro/features-and-api/26_pre_destroy.md create mode 100644 src/ro/features-and-api/2_container_modules.md create mode 100644 src/ro/features-and-api/3_container_snapshots.md create mode 100644 src/ro/features-and-api/4_scope.md create mode 100644 src/ro/features-and-api/5_optional_dependencies.md create mode 100644 src/ro/features-and-api/6_value_injection.md create mode 100644 src/ro/features-and-api/7_constructor_injection.md create mode 100644 src/ro/features-and-api/8_factory_injection.md create mode 100644 src/ro/features-and-api/9_auto_factory.md create mode 100644 src/ro/features-and-api/README.md create mode 100644 src/ro/getting-started/README.md create mode 100644 src/ro/index.md create mode 100644 src/ro/introduction/README.md create mode 100644 src/ro/why-inversifyjs/README.md create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 123ae94..595e215 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,12 @@ -# Logs -logs -*.log - -# Runtime data pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directory -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +logs node_modules +npm-debug.log +coverage/ +run +dist +.DS_Store +.nyc_output +.basement +config.local.js +basement_dist diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..db31e3b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,22 @@ +{ + "$schema": "http://json.schemastore.org/prettierrc", + "endOfLine": "lf", + "quoteProps": "as-needed", + "semi": true, + "singleQuote": true, + "tabWidth": 4, + "trailingComma": "none", + "useTabs": true, + "arrowParens": "always", + "bracketSpacing": true, + "printWidth": 120, + "overrides": [ + { + "files": ["*.yml"], + "options": { + "tabWidth": 2, + "useTabs": false + } + } + ] +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index aba67a1..0000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -node_js: -- stable -- 5.4.1 -- 5.4.0 -- 5.3.0 -- 5.2.0 -- 5.1.1 -- 4.4.6 diff --git a/CNAME b/CNAME deleted file mode 100644 index a7faa91..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -inversify.io diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index c7b708f..0000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -PLEASE DO NOT REPORT THE ISSUE HERE! - -PLEASE USE THE INVERSIFYJS REPO INSTEAD YOU CAN FIND THE REPO AT: - -https://github.com/inversify/InversifyJS/issues - -YOU CAN ALSO FIND US ON GITTER AT: - -https://gitter.im/inversify/InversifyJS - -THANKS! diff --git a/LICENSE b/LICENSE index 8193b5c..660f3a5 100644 --- a/LICENSE +++ b/LICENSE @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 3f52738..a348432 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,29 @@ -# inversify.github.io +## Development / Testing -[![Join the chat at https://gitter.im/inversify/InversifyJS](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/inversify/InversifyJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/inversify/inversify.github.io.svg?branch=master)](https://travis-ci.org/inversify/inversify.github.io) +```sh +$ yarn install +``` -The InversifyJS official website +```sh +$ yarn dev +``` + +## Creating Translations + +We recommend that each individual file you update has its own commit. + +This keeps the history for commits clean and easy to track backwards. + +### Creating a New Locale / Translation + +It's a pretty short process but requires some work. + +0. Fork the Repository +1. Copy `en.js` from `src/.vuepress/locales/en.js`. +1. Rename it to your two letter [ISO-639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). +1. Edit the titles and translate them. Follow instructions in the copied code. We left comments for you. +1. Copy the folder `en` from the `src` directory. +1. Rename it to your ISO-639-1 Code for your Country / Language. +1. Begin converting documents from English to your language. +1. Test locally! It's very important! +1. Make a pull request. diff --git a/css/site.css b/css/site.css deleted file mode 100644 index 3a7e585..0000000 --- a/css/site.css +++ /dev/null @@ -1,177 +0,0 @@ -body{ - padding-top: 50px; - font-family: 'Ubuntu', sans-serif; - background-color: #333333; -} - -.forkme { - position: absolute; - top: -5px; - right: 16px; - border: 0; - width: 75px; - z-index: 9999; -} - -.custom-header{ - background: linear-gradient(0deg, rgba(0, 116, 193,0.7), rgba(0, 116, 193,0.7)), url(/img/header-1.jpg); - background-size: cover; - padding-top: 40px; - padding-bottom: 90px; - text-align: center; -} -.custom-header img{ - width: 30%; -} - -.custom-header h1 { - padding-top: 0px; - margin-top: 0px; - font-size: 60px; - color: #ffffff; -} -.custom-header h2 { - font-size: 24px; - color: #ffffff; -} - -pre { - width: 100%; - line-height: 1.6; - background-color: #fffdae; - padding: 1em 1em 1em 1em !important; - margin-right: -1em; - overflow-x: auto; - font-size: 14px; - font-weight: bold; - font-family: consolas; - border: none; - border-radius: 0px; - border: none !important; - border-left: solid 3px #0074c1 !important; -} - -.btn-primary { - background-color: #0074c1; - border-color: #0074c1; -} - -.well{ - background-color: #ffffff; - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); - border: none; - border-radius: 0px; - margin-top: -50px; - padding: 5%; - margin-bottom: 70px; - padding-top: 0.5%; -} - -.well h3 { - border-bottom: 2px solid #eeeeee; - padding-bottom: 5px; - padding-top: 20px; -} - -.nav-tabs { - border-bottom: none; -} - -.tab-content { - background-color: #f3f3f3; - padding: 2%; -} - -.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover { - color: #555; - background-color: #f3f3f3; - border: none; - border-bottom: none; - border-radius: 0px; -} - -.nav-tabs>li>a, .nav-tabs>li>a:hover{ - border: none; - border-bottom: none; - border-radius: 0px; -} - -.nav-tabs>li>a:hover{ - background-color: #f3f3f3; -} - - -.nav-tabs>li { - margin-bottom: -3px; -} - -.framewroks { - text-align: center; -} - -.framewroks .well { - margin-top: 0px; - min-height: 200px; - border-radius: 0px; - margin-top: 5px; - margin-bottom: 35px; -} - -.framewroks .well p{ - margin-top: 20px; -} - -.framewroks .well .btn{ - width: 100%; - border-radius: 0px; -} - -.framewroks img{ - margin-top: 30px; - height: 100px; -} - -.ribbon { - position: absolute; - left: 6px; - top: -31px; -} - -h4 { - margin-top: 25px; -} - -blockquote { - background-color: #eee; -} - -.link { - cursor: pointer -} - -.mainfeatures img { - width: 100px; - margin: 15px; -} - -.mainfeatures .item { - text-align: center; -} - -.mainfeatures p { - text-align: left; -} - -.mainfeatures h3 { - text-align: left; -} - -.devtools { - text-align: center; -} - -.devtools img { - width: 80%; - margin-bottom: 15px; - margin-top: 15px; -} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index a457c6a..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; - -var gulp = require('gulp'), - runSequence = require('run-sequence'), - browserSync = require('browser-sync'), - reload = browserSync.reload; - -gulp.task('serve', function(cb) { - browserSync({ - port: 8080, - server: { - baseDir: "./" - } - }); - - gulp.watch([ - "./bower_components/**/*.css", - "./bower_components/**/*.js", - "./css/**/*.css", - "./img/**/*.css", - "./index.html" - ], browserSync.reload, cb); -}); - -gulp.task('default', function (cb) { - runSequence('serve', cb); -}); diff --git a/index.html b/index.html deleted file mode 100644 index 9964662..0000000 --- a/index.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - InversifyJS a powerful IoC container for JavaScript apps powered by TypeScript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - diff --git a/package.json b/package.json index 24c8497..f1b6034 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,24 @@ { - "name": "inversify.io", - "version": "1.0.0", - "description": "InversifyJS official website", - "main": "index.html", - "scripts": { - "test": "echo 'nothing to test'" - }, - "repository": { - "type": "git", - "url": "https://github.com/inversify/inversify.github.io.git" - }, - "keywords": [ - "IoC", - "inversify", - "inversion", - "control", - "typescript", - "javascript", - "dependency", - "injection" - ], - "author": "remojansen ", - "license": "MIT", - "bugs": { - "url": "https://github.com/inversify/inversify.github.io/issues" - }, - "homepage": "inversify.io", - "devDependencies": { - "browser-sync": "^2.23.5", - "gulp": "^4.0.0", - "run-sequence": "^2.0.0" - } + "name": "inversify.github.io", + "version": "0.0.1", + "description": "", + "main": "index.js", + "authors": { + "name": "", + "email": "" + }, + "repository": "/inversify.github.io", + "scripts": { + "dev": "vuepress dev src", + "build": "vuepress build src" + }, + "license": "MIT", + "devDependencies": { + "@vuepress/plugin-back-to-top": "^1.8.2", + "@vuepress/plugin-medium-zoom": "^1.8.2", + "glob": "^7.1.6", + "vuepress": "^1.5.3", + "vuepress-plugin-robots": "^1.0.1", + "vuepress-plugin-seo": "^0.1.4" + } } diff --git a/pages/community.html b/pages/community.html deleted file mode 100644 index f2acaca..0000000 --- a/pages/community.html +++ /dev/null @@ -1,37 +0,0 @@ -
-
-
-
-
-
- -
-
-
\ No newline at end of file diff --git a/pages/docs.html b/pages/docs.html deleted file mode 100644 index 9a6d5ff..0000000 --- a/pages/docs.html +++ /dev/null @@ -1,42 +0,0 @@ -
-
-
- \ No newline at end of file diff --git a/pages/home.html b/pages/home.html deleted file mode 100644 index 6a3988b..0000000 --- a/pages/home.html +++ /dev/null @@ -1,406 +0,0 @@ -
-
-
-
- -

InversifyJS

-

A powerful and lightweight inversion of control container
for JavaScript & Node.js apps powered by TypeScript.

-
- - - - - -
-
-
-
-
-
-
- - -
-
-

About

-

- InversifyJS is a lightweight (4KB) inversion of control (IoC) container for TypeScript and JavaScript apps. - A IoC container uses a class constructor to identify and inject its dependencies. -

-

- InversifyJS has a friendly API and encourage the usage of the best OOP and IoC practices. -

-
-
-

Motivation

-

JavaScript now supports object oriented (OO) programming with class based inheritance. These features are great but the truth is that they are also - dangerous.

-

We need a good OO design to protect ourselves from these threats. The problem is that OO design is difficult and that is exactly why we created InversifyJS.

-

InversifyJS is a tool that helps JavaScript developers to write code with a good OO design.

-
-
-

Philosophy

-

InversifyJS has been developed with 4 main goals:

-
    -
  1. -

    Allow JavaScript developers to write code that adheres to the SOLID principles.

    -
  2. -
  3. -

    Facilitate and encourage the adherence to the best OOP and IoC practices.

    -
  4. -
  5. -

    Add as little runtime overhead as possible.

    -
  6. -
  7. -

    Provide a state of the art development experience.

    -
  8. -
-
- - -

Status

-Build Status - -npm version -Package Quality -Dependencies -img -Known Vulnerabilities

- -

- - -

- -

Testimonies

-

Nate Kohari - Author of Ninject

-
-

"Nice work! I've taken a couple shots at creating DI frameworks for JavaScript and TypeScript, but the lack of RTTI really hinders things. -The ES7 metadata gets us part of the way there (as you've discovered). Keep up the great work!"

-
-

Michel Weststrat - Author of MobX

-
-

"Dependency injection like InversifyJS works nicely"

-
- - - -

The Basics

-
- -
- -
- -

Installation

- -

You can get the latest release and the type definitions using npm:

-
npm install inversify reflect-metadata --save
-
-

The InversifyJS type definitions are included in the inversify npm package. -InversifyJS requires TypeScript 2.0 and the experimentalDecorators, emitDecoratorMetadata, types and lib -compilation options in your tsconfig.json file:

-
{
-    "compilerOptions": {
-        "target": "es5",
-        "lib": ["es6", "dom"],
-        "types": ["reflect-metadata"],
-        "module": "commonjs",
-        "moduleResolution": "node",
-        "experimentalDecorators": true,
-        "emitDecoratorMetadata": true
-    }
-}
-
-

InversifyJS requires a modern JavaScript engine with support for:

- -

The reflect-metadata polyfill should be imported only once in your entire application because the Reflect object is mean to be a global singleton. More details about this can be found here.

-

If your environment don't support one of these you will need to import a shim or polyfill.

-

Check out the Environment support and polyfills -page in the wiki and the Basic example to learn more.

- - -
- - - - - - - - - - - - - - - - - - -
-
- - - - - -
-
-

Strongly Typed

- -

- InversifyJS is powered by TypeScript. TypeScript enable - JavaScript developers to use highly-productive - development tools and practices when developing JavaScript applications. -

-

-
-
-

Universal

- -

- InversifyJS compiles to clean, simple JavaScript code which runs on any browser, - in Node.js, or in any JavaScript engine that supports ECMAScript 5 (or newer). -

-
-
-

Pluggable

- -

- Inversifyjs is framework-agnostic and has been designed to in a way that makes - possible its integration with popular frameworks and libraries like hapi, express, - react or backbone. -

-
-
- - - - -

Features and API

- -

InversifyJS is powerful IoC container and supports the following features:

- - -

Please refer to the wiki for additional details.

- - - -

Ecosystem

-

In order to provide a state of the art development experience we are also working on:

- -For example, we have been working on the official InversifyjS development tools browser extension: -
- - -
-

Please refer to the ecosystem wiki page to learn more.

- - - -

Support

-

- If you are experience any kind of issues we will be happy to help. - You can report an issue using the issues page - or the chat. - You can also ask questions at Stack overflow - using the inversifyjs tag. -

-

- If you want to share your thoughts with the development team or join us you will be able to do - so using the Gitter chat. - You can check out the wiki - to learn more about InversifyJS internals. -

- - - -

Acknowledgements

-

Thanks a lot to all the contributors, all the developers out there using InversifyJS and all those that help us to spread the word by sharing content about InversifyJS online. Without your feedback and support this project would not be possible.

- - - -

License

-

License under the MIT License (MIT)

-

Copyright © 2015 - 2017 Remo H. Jansen

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

-

IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

- -
- - -
-
-
diff --git a/pages/support.html b/pages/support.html deleted file mode 100644 index c638ac5..0000000 --- a/pages/support.html +++ /dev/null @@ -1,42 +0,0 @@ -
-
-
-
-
-
- -
-
-
\ No newline at end of file diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js new file mode 100644 index 0000000..e3db0fb --- /dev/null +++ b/src/.vuepress/config.js @@ -0,0 +1,99 @@ +const { defaultSEO } = require('./seo/default'); +const { defaultNavbar } = require('./defaults/navbar'); + +// Locale Imports +const { enLocale, enMenus } = require('./locales/en'); + +const BASE_URL = 'https://inversify.leonard.sh/'; + +const title = 'InversifyJS a powerful IoC container for JavaScript apps powered by TypeScript'; +const desc = 'InversifyJS is a lightweight inversion of control (IoC) container for TypeScript and JavaScript apps.'; +const card = BASE_URL + 'logo_inverse.png'; + +const meta = [ + ['meta', { name: 'theme-color', content: '#ffffff' }], + ['meta', { name: 'msapplication-TileColor', content: '#ffffff' }], + ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }], + ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }], + ['meta', { name: 'description', content: desc }], + + // Favicons + ['link', { rel: 'apple-touch-icon', sizes: '57x57', href: '/favicon/apple-icon-57x57.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '60x60', href: '/favicon/apple-icon-60x60.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '72x72', href: '/favicon/apple-icon-72x72.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '76x76', href: '/favicon/apple-icon-76x76.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '114x114', href: '/favicon/apple-icon-114x114.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '120x120', href: '/favicon/apple-icon-120x120.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '144x144', href: '/favicon/apple-icon-144x144.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '152x152', href: '/favicon/apple-icon-152x152.png' }], + ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/favicon/apple-icon-180x180.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '192x192', href: '/favicon/android-icon-192x192.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon/favicon-32x32.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '96x96', href: '/favicon/favicon-96x96.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon/favicon-16x16.png' }], + ['link', { rel: 'manifest', href: '/site.webmanifest' }], + ['link', { rel: 'manifest', href: '/favicon/manifest.json' }], + ['meta', { name: 'msapplication-TileImage', content: '/favicon/ms-icon-144x144.png' }], + + // SEO + ['meta', { name: 'description', content: desc }], + [ + 'meta', + { + name: 'keywords', + content: 'dependency, inversion, javascript, typescript, nodejs, ioc, container, inversion, control' + } + ], + ['meta', { name: 'author', content: 'Remo H. Jansen' }], + + // Twitter Crawler + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:site', content: '@OweR_ReLoaDeD' }], + ['meta', { name: 'twitter:creator', content: '@OweR_ReLoaDeD' }], + ['meta', { name: 'twitter:title', content: 'InversifyJS' }], + ['meta', { name: 'twitter:description', content: desc }], + ['meta', { name: 'twitter:image:src', content: card }], + + // Facebook Crawler + ['meta', { property: 'og:url', content: BASE_URL }], + ['meta', { property: 'og:title', content: 'InversifyJS' }], + ['meta', { property: 'og:description', content: desc }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:image', content: card }], + ['meta', { property: 'og:locale', content: 'en_US' }], + ['meta', { property: 'og:site_name', content: BASE_URL }], + + // Fonts + ['link', { href: 'https://fonts.gstatic.com', rel: 'preconnect' }], + [ + 'link', + { + href: + 'https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap', + rel: 'stylesheet' + } + ] +]; + +module.exports = { + base: '/', + title: title, + description: desc, + locales: { + ...enLocale + }, + head: meta, + themeConfig: { + editLinks: false, + docsDir: '', + editLinkText: '', + lastUpdated: true, + smoothScroll: true, + logo: '/logo.png', + locales: { + ...enMenus + }, + nav: [...defaultNavbar] + }, + plugins: ['@vuepress/plugin-back-to-top', '@vuepress/plugin-medium-zoom', ...defaultSEO] +}; diff --git a/src/.vuepress/defaults/navbar.js b/src/.vuepress/defaults/navbar.js new file mode 100644 index 0000000..03d120a --- /dev/null +++ b/src/.vuepress/defaults/navbar.js @@ -0,0 +1,19 @@ +const defaultNavbar = [ + { + text: 'Languages', + ariaLabel: 'Language Menu', + items: [ + { text: 'English', link: '/en/' }, + { text: 'Română', link: '/ro/' }, + { text: 'Español', link: '/es/' } + ] + }, + { + text: 'Discord', + link: 'https://discord.gg/jXcMagAPnm' + } +]; + +module.exports = { + defaultNavbar +}; diff --git a/src/.vuepress/enhanceApp.js b/src/.vuepress/enhanceApp.js new file mode 100644 index 0000000..25693ec --- /dev/null +++ b/src/.vuepress/enhanceApp.js @@ -0,0 +1,14 @@ +/** + * Client app enhancement file. + * + * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements + */ + +export default ({ + Vue, // the version of Vue being used in the VuePress app + options, // the options for the root Vue instance + router, // the router instance for the app + siteData // site metadata +}) => { + // ...apply enhancements for the site. +}; diff --git a/src/.vuepress/locales/en.js b/src/.vuepress/locales/en.js new file mode 100644 index 0000000..85c825b --- /dev/null +++ b/src/.vuepress/locales/en.js @@ -0,0 +1,56 @@ +const { defaultNavbar } = require('../defaults/navbar'); +const { buildSidebar } = require('../utility/sidebarHelper'); + +const language = 'en'; +const languageUpper = 'US'; +const languageName = 'English'; + +const enLocale = { + [`/${language}/`]: { + lang: `${language}-${languageUpper}`, + title: `Documentation | ${languageName}` + } +}; + +const sidebar = [ + { + title: 'Guide', + collapsable: false, + children: [ + { + collapsable: false, + children: buildSidebar(`/${language}/why-inversifyjs/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/introduction/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/getting-started/`) + }, + { + title: 'Features and API', + collapsable: false, + children: buildSidebar(`/${language}/features-and-api/`) + } + ] + } +]; + +const enMenus = { + [`/${language}/`]: { + label: languageName, + nav: [...defaultNavbar], + sidebar: { + collapsable: false, + [`/${language}/`]: sidebar + }, + sidebarDepth: 3 + } +}; + +module.exports = { + enLocale, + enMenus +}; diff --git a/src/.vuepress/locales/es.js b/src/.vuepress/locales/es.js new file mode 100644 index 0000000..1eef947 --- /dev/null +++ b/src/.vuepress/locales/es.js @@ -0,0 +1,56 @@ +const { defaultNavbar } = require('../defaults/navbar'); +const { buildSidebar } = require('../utility/sidebarHelper'); + +const language = 'es'; +const languageUpper = 'ES'; +const languageName = 'Español'; + +const enLocale = { + [`/${language}/`]: { + lang: `${language}-${languageUpper}`, + title: `Documentación | ${languageName}` + } +}; + +const sidebar = [ + { + title: 'Guía', + collapsable: false, + children: [ + { + collapsable: false, + children: buildSidebar(`/${language}/why-inversifyjs/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/introduction/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/getting-started/`) + }, + { + title: 'Features and API', + collapsable: false, + children: buildSidebar(`/${language}/features-and-api/`) + } + ] + } +]; + +const enMenus = { + [`/${language}/`]: { + label: languageName, + nav: [...defaultNavbar], + sidebar: { + collapsable: false, + [`/${language}/`]: sidebar + }, + sidebarDepth: 3 + } +}; + +module.exports = { + enLocale, + enMenus +}; diff --git a/src/.vuepress/locales/ro.js b/src/.vuepress/locales/ro.js new file mode 100644 index 0000000..18ad39e --- /dev/null +++ b/src/.vuepress/locales/ro.js @@ -0,0 +1,56 @@ +const { defaultNavbar } = require('../defaults/navbar'); +const { buildSidebar } = require('../utility/sidebarHelper'); + +const language = 'ro'; +const languageUpper = 'ro'; +const languageName = 'Română'; + +const enLocale = { + [`/${language}/`]: { + lang: `${language}-${languageUpper}`, + title: `Documentație | ${languageName}` + } +}; + +const sidebar = [ + { + title: 'Ghid', + collapsable: false, + children: [ + { + collapsable: false, + children: buildSidebar(`/${language}/why-inversifyjs/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/introduction/`) + }, + { + collapsable: false, + children: buildSidebar(`/${language}/getting-started/`) + }, + { + title: 'Features and API', + collapsable: false, + children: buildSidebar(`/${language}/features-and-api/`) + } + ] + } +]; + +const enMenus = { + [`/${language}/`]: { + label: languageName, + nav: [...defaultNavbar], + sidebar: { + collapsable: false, + [`/${language}/`]: sidebar + }, + sidebarDepth: 3 + } +}; + +module.exports = { + enLocale, + enMenus +}; diff --git a/img/angular.png b/src/.vuepress/public/angular.png similarity index 100% rename from img/angular.png rename to src/.vuepress/public/angular.png diff --git a/img/basics.png b/src/.vuepress/public/basics.png similarity index 100% rename from img/basics.png rename to src/.vuepress/public/basics.png diff --git a/img/bg.jpg b/src/.vuepress/public/bg.jpg similarity index 100% rename from img/bg.jpg rename to src/.vuepress/public/bg.jpg diff --git a/img/browserify.png b/src/.vuepress/public/browserify.png similarity index 100% rename from img/browserify.png rename to src/.vuepress/public/browserify.png diff --git a/img/coming-soon-ribbon.png b/src/.vuepress/public/coming-soon-ribbon.png similarity index 100% rename from img/coming-soon-ribbon.png rename to src/.vuepress/public/coming-soon-ribbon.png diff --git a/img/cover.jpg b/src/.vuepress/public/cover.jpg similarity index 100% rename from img/cover.jpg rename to src/.vuepress/public/cover.jpg diff --git a/img/devtools1.png b/src/.vuepress/public/devtools1.png similarity index 100% rename from img/devtools1.png rename to src/.vuepress/public/devtools1.png diff --git a/img/devtools2.png b/src/.vuepress/public/devtools2.png similarity index 100% rename from img/devtools2.png rename to src/.vuepress/public/devtools2.png diff --git a/img/devtools3.png b/src/.vuepress/public/devtools3.png similarity index 100% rename from img/devtools3.png rename to src/.vuepress/public/devtools3.png diff --git a/img/ember.png b/src/.vuepress/public/ember.png similarity index 100% rename from img/ember.png rename to src/.vuepress/public/ember.png diff --git a/img/favicon/Thumbs.db b/src/.vuepress/public/favicon/Thumbs.db similarity index 100% rename from img/favicon/Thumbs.db rename to src/.vuepress/public/favicon/Thumbs.db diff --git a/img/favicon/android-icon-144x144.png b/src/.vuepress/public/favicon/android-icon-144x144.png similarity index 100% rename from img/favicon/android-icon-144x144.png rename to src/.vuepress/public/favicon/android-icon-144x144.png diff --git a/img/favicon/android-icon-192x192.png b/src/.vuepress/public/favicon/android-icon-192x192.png similarity index 100% rename from img/favicon/android-icon-192x192.png rename to src/.vuepress/public/favicon/android-icon-192x192.png diff --git a/img/favicon/android-icon-36x36.png b/src/.vuepress/public/favicon/android-icon-36x36.png similarity index 100% rename from img/favicon/android-icon-36x36.png rename to src/.vuepress/public/favicon/android-icon-36x36.png diff --git a/img/favicon/android-icon-48x48.png b/src/.vuepress/public/favicon/android-icon-48x48.png similarity index 100% rename from img/favicon/android-icon-48x48.png rename to src/.vuepress/public/favicon/android-icon-48x48.png diff --git a/img/favicon/android-icon-72x72.png b/src/.vuepress/public/favicon/android-icon-72x72.png similarity index 100% rename from img/favicon/android-icon-72x72.png rename to src/.vuepress/public/favicon/android-icon-72x72.png diff --git a/img/favicon/android-icon-96x96.png b/src/.vuepress/public/favicon/android-icon-96x96.png similarity index 100% rename from img/favicon/android-icon-96x96.png rename to src/.vuepress/public/favicon/android-icon-96x96.png diff --git a/img/favicon/apple-icon-114x114.png b/src/.vuepress/public/favicon/apple-icon-114x114.png similarity index 100% rename from img/favicon/apple-icon-114x114.png rename to src/.vuepress/public/favicon/apple-icon-114x114.png diff --git a/img/favicon/apple-icon-120x120.png b/src/.vuepress/public/favicon/apple-icon-120x120.png similarity index 100% rename from img/favicon/apple-icon-120x120.png rename to src/.vuepress/public/favicon/apple-icon-120x120.png diff --git a/img/favicon/apple-icon-144x144.png b/src/.vuepress/public/favicon/apple-icon-144x144.png similarity index 100% rename from img/favicon/apple-icon-144x144.png rename to src/.vuepress/public/favicon/apple-icon-144x144.png diff --git a/img/favicon/apple-icon-152x152.png b/src/.vuepress/public/favicon/apple-icon-152x152.png similarity index 100% rename from img/favicon/apple-icon-152x152.png rename to src/.vuepress/public/favicon/apple-icon-152x152.png diff --git a/img/favicon/apple-icon-180x180.png b/src/.vuepress/public/favicon/apple-icon-180x180.png similarity index 100% rename from img/favicon/apple-icon-180x180.png rename to src/.vuepress/public/favicon/apple-icon-180x180.png diff --git a/img/favicon/apple-icon-57x57.png b/src/.vuepress/public/favicon/apple-icon-57x57.png similarity index 100% rename from img/favicon/apple-icon-57x57.png rename to src/.vuepress/public/favicon/apple-icon-57x57.png diff --git a/img/favicon/apple-icon-60x60.png b/src/.vuepress/public/favicon/apple-icon-60x60.png similarity index 100% rename from img/favicon/apple-icon-60x60.png rename to src/.vuepress/public/favicon/apple-icon-60x60.png diff --git a/img/favicon/apple-icon-72x72.png b/src/.vuepress/public/favicon/apple-icon-72x72.png similarity index 100% rename from img/favicon/apple-icon-72x72.png rename to src/.vuepress/public/favicon/apple-icon-72x72.png diff --git a/img/favicon/apple-icon-76x76.png b/src/.vuepress/public/favicon/apple-icon-76x76.png similarity index 100% rename from img/favicon/apple-icon-76x76.png rename to src/.vuepress/public/favicon/apple-icon-76x76.png diff --git a/img/favicon/apple-icon-precomposed.png b/src/.vuepress/public/favicon/apple-icon-precomposed.png similarity index 100% rename from img/favicon/apple-icon-precomposed.png rename to src/.vuepress/public/favicon/apple-icon-precomposed.png diff --git a/img/favicon/apple-icon.png b/src/.vuepress/public/favicon/apple-icon.png similarity index 100% rename from img/favicon/apple-icon.png rename to src/.vuepress/public/favicon/apple-icon.png diff --git a/img/favicon/browserconfig.xml b/src/.vuepress/public/favicon/browserconfig.xml similarity index 100% rename from img/favicon/browserconfig.xml rename to src/.vuepress/public/favicon/browserconfig.xml diff --git a/img/favicon/favicon-16x16.png b/src/.vuepress/public/favicon/favicon-16x16.png similarity index 100% rename from img/favicon/favicon-16x16.png rename to src/.vuepress/public/favicon/favicon-16x16.png diff --git a/img/favicon/favicon-32x32.png b/src/.vuepress/public/favicon/favicon-32x32.png similarity index 100% rename from img/favicon/favicon-32x32.png rename to src/.vuepress/public/favicon/favicon-32x32.png diff --git a/img/favicon/favicon-96x96.png b/src/.vuepress/public/favicon/favicon-96x96.png similarity index 100% rename from img/favicon/favicon-96x96.png rename to src/.vuepress/public/favicon/favicon-96x96.png diff --git a/img/favicon/favicon.ico b/src/.vuepress/public/favicon/favicon.ico similarity index 100% rename from img/favicon/favicon.ico rename to src/.vuepress/public/favicon/favicon.ico diff --git a/img/favicon/manifest.json b/src/.vuepress/public/favicon/manifest.json similarity index 100% rename from img/favicon/manifest.json rename to src/.vuepress/public/favicon/manifest.json diff --git a/img/favicon/ms-icon-144x144.png b/src/.vuepress/public/favicon/ms-icon-144x144.png similarity index 100% rename from img/favicon/ms-icon-144x144.png rename to src/.vuepress/public/favicon/ms-icon-144x144.png diff --git a/img/favicon/ms-icon-150x150.png b/src/.vuepress/public/favicon/ms-icon-150x150.png similarity index 100% rename from img/favicon/ms-icon-150x150.png rename to src/.vuepress/public/favicon/ms-icon-150x150.png diff --git a/img/favicon/ms-icon-310x310.png b/src/.vuepress/public/favicon/ms-icon-310x310.png similarity index 100% rename from img/favicon/ms-icon-310x310.png rename to src/.vuepress/public/favicon/ms-icon-310x310.png diff --git a/img/favicon/ms-icon-70x70.png b/src/.vuepress/public/favicon/ms-icon-70x70.png similarity index 100% rename from img/favicon/ms-icon-70x70.png rename to src/.vuepress/public/favicon/ms-icon-70x70.png diff --git a/img/forkme.png b/src/.vuepress/public/forkme.png similarity index 100% rename from img/forkme.png rename to src/.vuepress/public/forkme.png diff --git a/img/header-1.jpg b/src/.vuepress/public/header-1.jpg similarity index 100% rename from img/header-1.jpg rename to src/.vuepress/public/header-1.jpg diff --git a/img/logo.png b/src/.vuepress/public/logo.png similarity index 100% rename from img/logo.png rename to src/.vuepress/public/logo.png diff --git a/img/logo_inverse.png b/src/.vuepress/public/logo_inverse.png similarity index 100% rename from img/logo_inverse.png rename to src/.vuepress/public/logo_inverse.png diff --git a/img/logo_transparent.svg b/src/.vuepress/public/logo_transparent.svg similarity index 100% rename from img/logo_transparent.svg rename to src/.vuepress/public/logo_transparent.svg diff --git a/img/marionette.png b/src/.vuepress/public/marionette.png similarity index 100% rename from img/marionette.png rename to src/.vuepress/public/marionette.png diff --git a/img/node.png b/src/.vuepress/public/node.png similarity index 100% rename from img/node.png rename to src/.vuepress/public/node.png diff --git a/img/plug.jpg b/src/.vuepress/public/plug.jpg similarity index 100% rename from img/plug.jpg rename to src/.vuepress/public/plug.jpg diff --git a/img/require.png b/src/.vuepress/public/require.png similarity index 100% rename from img/require.png rename to src/.vuepress/public/require.png diff --git a/img/so.png b/src/.vuepress/public/so.png similarity index 100% rename from img/so.png rename to src/.vuepress/public/so.png diff --git a/img/ts.png b/src/.vuepress/public/ts.png similarity index 100% rename from img/ts.png rename to src/.vuepress/public/ts.png diff --git a/img/twitter-ribbon.png b/src/.vuepress/public/twitter-ribbon.png similarity index 100% rename from img/twitter-ribbon.png rename to src/.vuepress/public/twitter-ribbon.png diff --git a/img/universal.png b/src/.vuepress/public/universal.png similarity index 100% rename from img/universal.png rename to src/.vuepress/public/universal.png diff --git a/src/.vuepress/seo/default.js b/src/.vuepress/seo/default.js new file mode 100644 index 0000000..3040008 --- /dev/null +++ b/src/.vuepress/seo/default.js @@ -0,0 +1,21 @@ +const defaultSEO = [ + [ + 'seo', + { + publishedAt: () => new Date(Date.now()).toISOString(), + modifiedAt: () => new Date(Date.now()).toISOString() + } + ], + [ + 'robots', + { + host: 'https://inversify.leonard.sh/', + allowAll: true, + sitemap: '/sitemap.xml' + } + ] +]; + +module.exports = { + defaultSEO +}; diff --git a/src/.vuepress/styles/palette.styl b/src/.vuepress/styles/palette.styl new file mode 100644 index 0000000..6c3f3b8 --- /dev/null +++ b/src/.vuepress/styles/palette.styl @@ -0,0 +1 @@ +$blueColor = '#23527c' \ No newline at end of file diff --git a/src/.vuepress/theme/components/AlgoliaSearchBox.vue b/src/.vuepress/theme/components/AlgoliaSearchBox.vue new file mode 100644 index 0000000..7071fb8 --- /dev/null +++ b/src/.vuepress/theme/components/AlgoliaSearchBox.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/src/.vuepress/theme/components/DropdownLink.vue b/src/.vuepress/theme/components/DropdownLink.vue new file mode 100644 index 0000000..be6563f --- /dev/null +++ b/src/.vuepress/theme/components/DropdownLink.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/src/.vuepress/theme/components/DropdownTransition.vue b/src/.vuepress/theme/components/DropdownTransition.vue new file mode 100644 index 0000000..eeaf12b --- /dev/null +++ b/src/.vuepress/theme/components/DropdownTransition.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/src/.vuepress/theme/components/Home.vue b/src/.vuepress/theme/components/Home.vue new file mode 100644 index 0000000..9e2b225 --- /dev/null +++ b/src/.vuepress/theme/components/Home.vue @@ -0,0 +1,207 @@ + + + + + diff --git a/src/.vuepress/theme/components/NavLink.vue b/src/.vuepress/theme/components/NavLink.vue new file mode 100644 index 0000000..f7e65a4 --- /dev/null +++ b/src/.vuepress/theme/components/NavLink.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/.vuepress/theme/components/NavLinks.vue b/src/.vuepress/theme/components/NavLinks.vue new file mode 100644 index 0000000..2656ae2 --- /dev/null +++ b/src/.vuepress/theme/components/NavLinks.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/.vuepress/theme/components/Navbar.vue b/src/.vuepress/theme/components/Navbar.vue new file mode 100644 index 0000000..080e8ce --- /dev/null +++ b/src/.vuepress/theme/components/Navbar.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/.vuepress/theme/components/Page.vue b/src/.vuepress/theme/components/Page.vue new file mode 100644 index 0000000..04ec7cb --- /dev/null +++ b/src/.vuepress/theme/components/Page.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/src/.vuepress/theme/components/PageEdit.vue b/src/.vuepress/theme/components/PageEdit.vue new file mode 100644 index 0000000..cf9b2d2 --- /dev/null +++ b/src/.vuepress/theme/components/PageEdit.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/src/.vuepress/theme/components/PageNav.vue b/src/.vuepress/theme/components/PageNav.vue new file mode 100644 index 0000000..4c19aae --- /dev/null +++ b/src/.vuepress/theme/components/PageNav.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/.vuepress/theme/components/Sidebar.vue b/src/.vuepress/theme/components/Sidebar.vue new file mode 100644 index 0000000..90094ae --- /dev/null +++ b/src/.vuepress/theme/components/Sidebar.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/.vuepress/theme/components/SidebarButton.vue b/src/.vuepress/theme/components/SidebarButton.vue new file mode 100644 index 0000000..3f54afd --- /dev/null +++ b/src/.vuepress/theme/components/SidebarButton.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/.vuepress/theme/components/SidebarGroup.vue b/src/.vuepress/theme/components/SidebarGroup.vue new file mode 100644 index 0000000..d7f1929 --- /dev/null +++ b/src/.vuepress/theme/components/SidebarGroup.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/.vuepress/theme/components/SidebarLink.vue b/src/.vuepress/theme/components/SidebarLink.vue new file mode 100644 index 0000000..4cd7665 --- /dev/null +++ b/src/.vuepress/theme/components/SidebarLink.vue @@ -0,0 +1,133 @@ + + + diff --git a/src/.vuepress/theme/components/SidebarLinks.vue b/src/.vuepress/theme/components/SidebarLinks.vue new file mode 100644 index 0000000..55e6288 --- /dev/null +++ b/src/.vuepress/theme/components/SidebarLinks.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/.vuepress/theme/global-components/Badge.vue b/src/.vuepress/theme/global-components/Badge.vue new file mode 100644 index 0000000..53951f9 --- /dev/null +++ b/src/.vuepress/theme/global-components/Badge.vue @@ -0,0 +1,44 @@ + + + diff --git a/src/.vuepress/theme/global-components/CodeBlock.vue b/src/.vuepress/theme/global-components/CodeBlock.vue new file mode 100644 index 0000000..d59d85b --- /dev/null +++ b/src/.vuepress/theme/global-components/CodeBlock.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/.vuepress/theme/global-components/CodeGroup.vue b/src/.vuepress/theme/global-components/CodeGroup.vue new file mode 100644 index 0000000..ac6ec55 --- /dev/null +++ b/src/.vuepress/theme/global-components/CodeGroup.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/.vuepress/theme/index.js b/src/.vuepress/theme/index.js new file mode 100644 index 0000000..8a89a06 --- /dev/null +++ b/src/.vuepress/theme/index.js @@ -0,0 +1,71 @@ +const path = require('path'); + +// Theme API. +module.exports = (options, ctx) => { + const { themeConfig, siteConfig } = ctx; + + // resolve algolia + const isAlgoliaSearch = + themeConfig.algolia || + Object.keys((siteConfig.locales && themeConfig.locales) || {}).some( + (base) => themeConfig.locales[base].algolia + ); + + const enableSmoothScroll = themeConfig.smoothScroll === true; + + return { + alias() { + return { + '@AlgoliaSearchBox': isAlgoliaSearch + ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue') + : path.resolve(__dirname, 'noopModule.js') + }; + }, + + plugins: [ + ['@vuepress/active-header-links', options.activeHeaderLinks], + '@vuepress/search', + '@vuepress/plugin-nprogress', + [ + 'container', + { + type: 'tip', + defaultTitle: { + '/': 'TIP', + '/zh/': '提示' + } + } + ], + [ + 'container', + { + type: 'warning', + defaultTitle: { + '/': 'WARNING', + '/zh/': '注意' + } + } + ], + [ + 'container', + { + type: 'danger', + defaultTitle: { + '/': 'WARNING', + '/zh/': '警告' + } + } + ], + [ + 'container', + { + type: 'details', + before: (info) => + `
${info ? `${info}` : ''}\n`, + after: () => '
\n' + } + ], + ['smooth-scroll', enableSmoothScroll] + ] + }; +}; diff --git a/src/.vuepress/theme/layouts/404.vue b/src/.vuepress/theme/layouts/404.vue new file mode 100644 index 0000000..e73531c --- /dev/null +++ b/src/.vuepress/theme/layouts/404.vue @@ -0,0 +1,30 @@ + + + diff --git a/src/.vuepress/theme/layouts/Layout.vue b/src/.vuepress/theme/layouts/Layout.vue new file mode 100644 index 0000000..020d09a --- /dev/null +++ b/src/.vuepress/theme/layouts/Layout.vue @@ -0,0 +1,119 @@ + + + diff --git a/src/.vuepress/theme/noopModule.js b/src/.vuepress/theme/noopModule.js new file mode 100644 index 0000000..b1c6ea4 --- /dev/null +++ b/src/.vuepress/theme/noopModule.js @@ -0,0 +1 @@ +export default {} diff --git a/src/.vuepress/theme/styles/arrow.styl b/src/.vuepress/theme/styles/arrow.styl new file mode 100644 index 0000000..20bffc0 --- /dev/null +++ b/src/.vuepress/theme/styles/arrow.styl @@ -0,0 +1,22 @@ +@require './config' + +.arrow + display inline-block + width 0 + height 0 + &.up + border-left 4px solid transparent + border-right 4px solid transparent + border-bottom 6px solid $arrowBgColor + &.down + border-left 4px solid transparent + border-right 4px solid transparent + border-top 6px solid $arrowBgColor + &.right + border-top 4px solid transparent + border-bottom 4px solid transparent + border-left 6px solid $arrowBgColor + &.left + border-top 4px solid transparent + border-bottom 4px solid transparent + border-right 6px solid $arrowBgColor diff --git a/src/.vuepress/theme/styles/code.styl b/src/.vuepress/theme/styles/code.styl new file mode 100644 index 0000000..79a6054 --- /dev/null +++ b/src/.vuepress/theme/styles/code.styl @@ -0,0 +1,137 @@ +{$contentClass} + code + color lighten(#c7254e, 20%) + padding 0.25rem 0.5rem + margin 0 + font-size 0.85em + background-color #f9f2f4 + border-radius 3px + .token + &.deleted + color #EC5975 + &.inserted + color $accentColor + +{$contentClass} + pre, pre[class*="language-"] + line-height 1.4 + padding 1.25rem 1.5rem + margin 0.85rem 0 + background-color $codeBgColor + border-radius 6px + overflow auto + code + color #fff + padding 0 + background-color transparent + border-radius 0 + +div[class*="language-"] + position relative + background-color $codeBgColor + border-radius 6px + .highlight-lines + user-select none + padding-top 1.3rem + position absolute + top 0 + left 0 + width 100% + line-height 1.4 + .highlighted + background-color rgba(0, 0, 0, 66%) + pre, pre[class*="language-"] + background transparent + position relative + z-index 1 + &::before + position absolute + z-index 3 + top 0.8em + right 1em + font-size 0.75rem + color rgba(255, 255, 255, 0.4) + &:not(.line-numbers-mode) + .line-numbers-wrapper + display none + &.line-numbers-mode + .highlight-lines .highlighted + position relative + &:before + content ' ' + position absolute + z-index 3 + left 0 + top 0 + display block + width $lineNumbersWrapperWidth + height 100% + background-color rgba(0, 0, 0, 66%) + pre + padding-left $lineNumbersWrapperWidth + 1 rem + vertical-align middle + .line-numbers-wrapper + position absolute + top 0 + width $lineNumbersWrapperWidth + text-align center + color rgba(255, 255, 255, 0.3) + padding 1.25rem 0 + line-height 1.4 + br + user-select none + .line-number + position relative + z-index 4 + user-select none + font-size 0.85em + &::after + content '' + position absolute + z-index 2 + top 0 + left 0 + width $lineNumbersWrapperWidth + height 100% + border-radius 6px 0 0 6px + border-right 1px solid rgba(0, 0, 0, 66%) + background-color $codeBgColor + + +for lang in $codeLang + div{'[class~="language-' + lang + '"]'} + &:before + content ('' + lang) + +div[class~="language-javascript"] + &:before + content "js" + +div[class~="language-typescript"] + &:before + content "ts" + +div[class~="language-markup"] + &:before + content "html" + +div[class~="language-markdown"] + &:before + content "md" + +div[class~="language-json"]:before + content "json" + +div[class~="language-ruby"]:before + content "rb" + +div[class~="language-python"]:before + content "py" + +div[class~="language-bash"]:before + content "sh" + +div[class~="language-php"]:before + content "php" + +@import '~prismjs/themes/prism-tomorrow.css' diff --git a/src/.vuepress/theme/styles/config.styl b/src/.vuepress/theme/styles/config.styl new file mode 100644 index 0000000..b64f746 --- /dev/null +++ b/src/.vuepress/theme/styles/config.styl @@ -0,0 +1 @@ +$contentClass = '.theme-default-content' \ No newline at end of file diff --git a/src/.vuepress/theme/styles/custom-blocks.styl b/src/.vuepress/theme/styles/custom-blocks.styl new file mode 100644 index 0000000..5b86816 --- /dev/null +++ b/src/.vuepress/theme/styles/custom-blocks.styl @@ -0,0 +1,44 @@ +.custom-block + .custom-block-title + font-weight 600 + margin-bottom -0.4rem + &.tip, &.warning, &.danger + padding .1rem 1.5rem + border-left-width .5rem + border-left-style solid + margin 1rem 0 + &.tip + background-color #f3f5f7 + border-color #42b983 + &.warning + background-color rgba(255,229,100,.3) + border-color darken(#ffe564, 35%) + color darken(#ffe564, 70%) + .custom-block-title + color darken(#ffe564, 50%) + a + color $textColor + &.danger + background-color #ffe6e6 + border-color darken(red, 20%) + color darken(red, 70%) + .custom-block-title + color darken(red, 40%) + a + color $textColor + &.details + display block + position relative + border-radius 2px + margin 1.6em 0 + padding 1.6em + background-color #eee + h4 + margin-top 0 + figure, p + &:last-child + margin-bottom 0 + padding-bottom 0 + summary + outline none + cursor pointer diff --git a/src/.vuepress/theme/styles/index.styl b/src/.vuepress/theme/styles/index.styl new file mode 100644 index 0000000..a917824 --- /dev/null +++ b/src/.vuepress/theme/styles/index.styl @@ -0,0 +1,207 @@ +@require './config' +@require './code' +@require './custom-blocks' +@require './arrow' +@require './wrapper' +@require './toc' + +html, body + padding 0 + margin 0 + +body + font-family -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif + -webkit-font-smoothing antialiased + -moz-osx-font-smoothing grayscale + font-size 16px + color $textColor + +.theme-default-content:not(.custom) { + max-width: 69%; + margin: 0 auto; + padding: 2rem 2.5rem; +} + +.page + padding-left $sidebarWidth + +.navbar + position fixed + z-index 20 + top 0 + left 0 + right 0 + height $navbarHeight + background-color #fff + box-sizing border-box + border-bottom 1px solid $borderColor + +.sidebar-mask + position fixed + z-index 9 + top 0 + left 0 + width 100vw + height 100vh + display none + +.sidebar + font-size 16px + background-color #fff + width $sidebarWidth + position fixed + z-index 10 + margin 0 + top $navbarHeight + left 0 + bottom 0 + box-sizing border-box + border-right 1px solid $borderColor + overflow-y auto + +{$contentClass}:not(.custom) + @extend $wrapper + > *:first-child + margin-top $navbarHeight + + a:hover + text-decoration underline + + p.demo + padding 1rem 1.5rem + border 1px solid #ddd + border-radius 4px + + img + max-width 100% + +{$contentClass}.custom + padding 0 + margin 0 + + img + max-width 100% + +a + font-weight 500 + color $accentColor + text-decoration none + +p a code + font-weight 400 + color $accentColor + +kbd + background #eee + border solid 0.15rem #ddd + border-bottom solid 0.25rem #ddd + border-radius 0.15rem + padding 0 0.15em + +blockquote + font-size 1rem + color #999; + border-left .2rem solid #dfe2e5 + margin 1rem 0 + padding .25rem 0 .25rem 1rem + + & > p + margin 0 + +ul, ol + padding-left 1.2em + +strong + font-weight 600 + +h1, h2, h3, h4, h5, h6 + font-weight 600 + line-height 1.25 + + {$contentClass}:not(.custom) > & + margin-top (0.5rem - $navbarHeight) + padding-top ($navbarHeight + 1rem) + margin-bottom 0 + + &:first-child + margin-top -1.5rem + margin-bottom 1rem + + + p, + pre, + .custom-block + margin-top 2rem + + &:focus .header-anchor, + &:hover .header-anchor + opacity: 1 + +h1 + font-size 2.2rem + +h2 + font-size 1.65rem + padding-bottom .3rem + border-bottom 1px solid $borderColor + +h3 + font-size 1.35rem + +a.header-anchor + font-size 0.85em + float left + margin-left -0.87em + padding-right 0.23em + margin-top 0.125em + opacity 0 + + &:focus, + &:hover + text-decoration none + +code, kbd, .line-number + font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace + +p, ul, ol + line-height 1.7 + +hr + border 0 + border-top 1px solid $borderColor + +table + border-collapse collapse + margin 1rem 0 + display: block + overflow-x: auto + +tr + border-top 1px solid #dfe2e5 + + &:nth-child(2n) + background-color #f6f8fa + +th, td + border 1px solid #dfe2e5 + padding .6em 1em + +.theme-container + &.sidebar-open + .sidebar-mask + display: block + + &.no-navbar + {$contentClass}:not(.custom) > h1, h2, h3, h4, h5, h6 + margin-top 1.5rem + padding-top 0 + + .sidebar + top 0 + +@media (min-width: ($MQMobile + 1px)) + .theme-container.no-sidebar + .sidebar + display none + + .page + padding-left 0 + +@require 'mobile.styl' diff --git a/src/.vuepress/theme/styles/mobile.styl b/src/.vuepress/theme/styles/mobile.styl new file mode 100644 index 0000000..f5bd327 --- /dev/null +++ b/src/.vuepress/theme/styles/mobile.styl @@ -0,0 +1,37 @@ +@require './config' + +$mobileSidebarWidth = $sidebarWidth * 0.82 + +// narrow desktop / iPad +@media (max-width: $MQNarrow) + .sidebar + font-size 15px + width $mobileSidebarWidth + .page + padding-left $mobileSidebarWidth + +// wide mobile +@media (max-width: $MQMobile) + .sidebar + top 0 + padding-top $navbarHeight + transform translateX(-100%) + transition transform .2s ease + .page + padding-left 0 + .theme-container + &.sidebar-open + .sidebar + transform translateX(0) + &.no-navbar + .sidebar + padding-top: 0 + +// narrow mobile +@media (max-width: $MQMobileNarrow) + h1 + font-size 1.9rem + {$contentClass} + div[class*="language-"] + margin 0.85rem -1.5rem + border-radius 0 diff --git a/src/.vuepress/theme/styles/palette.styl b/src/.vuepress/theme/styles/palette.styl new file mode 100644 index 0000000..75b9ee2 --- /dev/null +++ b/src/.vuepress/theme/styles/palette.styl @@ -0,0 +1 @@ +$accentColor = #0074c1 \ No newline at end of file diff --git a/src/.vuepress/theme/styles/toc.styl b/src/.vuepress/theme/styles/toc.styl new file mode 100644 index 0000000..d3e7106 --- /dev/null +++ b/src/.vuepress/theme/styles/toc.styl @@ -0,0 +1,3 @@ +.table-of-contents + .badge + vertical-align middle diff --git a/src/.vuepress/theme/styles/wrapper.styl b/src/.vuepress/theme/styles/wrapper.styl new file mode 100644 index 0000000..a99262c --- /dev/null +++ b/src/.vuepress/theme/styles/wrapper.styl @@ -0,0 +1,9 @@ +$wrapper + max-width $contentWidth + margin 0 auto + padding 2rem 2.5rem + @media (max-width: $MQNarrow) + padding 2rem + @media (max-width: $MQMobileNarrow) + padding 1.5rem + diff --git a/src/.vuepress/theme/util/index.js b/src/.vuepress/theme/util/index.js new file mode 100644 index 0000000..d4164ee --- /dev/null +++ b/src/.vuepress/theme/util/index.js @@ -0,0 +1,241 @@ +export const hashRE = /#.*$/; +export const extRE = /\.(md|html)$/; +export const endingSlashRE = /\/$/; +export const outboundRE = /^[a-z]+:/i; + +export function normalize(path) { + return decodeURI(path) + .replace(hashRE, '') + .replace(extRE, ''); +} + +export function getHash(path) { + const match = path.match(hashRE); + if (match) { + return match[0]; + } +} + +export function isExternal(path) { + return outboundRE.test(path); +} + +export function isMailto(path) { + return /^mailto:/.test(path); +} + +export function isTel(path) { + return /^tel:/.test(path); +} + +export function ensureExt(path) { + if (isExternal(path)) { + return path; + } + const hashMatch = path.match(hashRE); + const hash = hashMatch ? hashMatch[0] : ''; + const normalized = normalize(path); + + if (endingSlashRE.test(normalized)) { + return path; + } + return normalized + '.html' + hash; +} + +export function isActive(route, path) { + const routeHash = decodeURIComponent(route.hash); + const linkHash = getHash(path); + if (linkHash && routeHash !== linkHash) { + return false; + } + const routePath = normalize(route.path); + const pagePath = normalize(path); + return routePath === pagePath; +} + +export function resolvePage(pages, rawPath, base) { + if (isExternal(rawPath)) { + return { + type: 'external', + path: rawPath + }; + } + if (base) { + rawPath = resolvePath(rawPath, base); + } + const path = normalize(rawPath); + for (let i = 0; i < pages.length; i++) { + if (normalize(pages[i].regularPath) === path) { + return Object.assign({}, pages[i], { + type: 'page', + path: ensureExt(pages[i].path) + }); + } + } + console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`); + return {}; +} + +function resolvePath(relative, base, append) { + const firstChar = relative.charAt(0); + if (firstChar === '/') { + return relative; + } + + if (firstChar === '?' || firstChar === '#') { + return base + relative; + } + + const stack = base.split('/'); + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop(); + } + + // resolve relative path + const segments = relative.replace(/^\//, '').split('/'); + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + if (segment === '..') { + stack.pop(); + } else if (segment !== '.') { + stack.push(segment); + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift(''); + } + + return stack.join('/'); +} + +/** + * @param { Page } page + * @param { string } regularPath + * @param { SiteData } site + * @param { string } localePath + * @returns { SidebarGroup } + */ +export function resolveSidebarItems(page, regularPath, site, localePath) { + const { pages, themeConfig } = site; + + const localeConfig = + localePath && themeConfig.locales ? themeConfig.locales[localePath] || themeConfig : themeConfig; + + const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar; + if (pageSidebarConfig === 'auto') { + return resolveHeaders(page); + } + + const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar; + if (!sidebarConfig) { + return []; + } else { + const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig); + if (config === 'auto') { + return resolveHeaders(page); + } + return config ? config.map((item) => resolveItem(item, pages, base)) : []; + } +} + +/** + * @param { Page } page + * @returns { SidebarGroup } + */ +function resolveHeaders(page) { + const headers = groupHeaders(page.headers || []); + return [ + { + type: 'group', + collapsable: false, + title: page.title, + path: null, + children: headers.map((h) => ({ + type: 'auto', + title: h.title, + basePath: page.path, + path: page.path + '#' + h.slug, + children: h.children || [] + })) + } + ]; +} + +export function groupHeaders(headers) { + // group h3s under h2 + headers = headers.map((h) => Object.assign({}, h)); + let lastH2; + headers.forEach((h) => { + if (h.level === 2) { + lastH2 = h; + } else if (lastH2) { + (lastH2.children || (lastH2.children = [])).push(h); + } + }); + return headers.filter((h) => h.level === 2); +} + +export function resolveNavLinkItem(linkItem) { + return Object.assign(linkItem, { + type: linkItem.items && linkItem.items.length ? 'links' : 'link' + }); +} + +/** + * @param { Route } route + * @param { Array | Array | [link: string]: SidebarConfig } config + * @returns { base: string, config: SidebarConfig } + */ +export function resolveMatchingConfig(regularPath, config) { + if (Array.isArray(config)) { + return { + base: '/', + config: config + }; + } + for (const base in config) { + if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) { + return { + base, + config: config[base] + }; + } + } + return {}; +} + +function ensureEndingSlash(path) { + return /(\.html|\/)$/.test(path) ? path : path + '/'; +} + +function resolveItem(item, pages, base, groupDepth = 1) { + if (typeof item === 'string') { + return resolvePage(pages, item, base); + } else if (Array.isArray(item)) { + return Object.assign(resolvePage(pages, item[0], base), { + title: item[1] + }); + } else { + const children = item.children || []; + if (children.length === 0 && item.path) { + return Object.assign(resolvePage(pages, item.path, base), { + title: item.title + }); + } + return { + type: 'group', + path: item.path, + title: item.title, + sidebarDepth: item.sidebarDepth, + initialOpenGroupIndex: item.initialOpenGroupIndex, + children: children.map((child) => resolveItem(child, pages, base, groupDepth + 1)), + collapsable: item.collapsable !== false + }; + } +} diff --git a/src/.vuepress/utility/sidebarHelper.js b/src/.vuepress/utility/sidebarHelper.js new file mode 100644 index 0000000..71c5f1c --- /dev/null +++ b/src/.vuepress/utility/sidebarHelper.js @@ -0,0 +1,33 @@ +const glob = require('glob'); +const path = require('path'); + +const workingPath = path.join(process.cwd(), '/src/'); // ./src/ + +/** + * @param {} targetDirectory /en/introduction/ + * @param {} callback + */ +function buildSidebar(targetDirectory) { + const fullPath = path.join(workingPath, targetDirectory); + const files = glob.sync(fullPath + '/**/*.md'); + + for (let i = 0; i < files.length; i++) { + let fileName = files[i]; + fileName = fileName.replace(/.*src/gi, ''); + fileName = fileName.replace('.md', ''); + files[i] = fileName; + } + + // Make Readme First + if (files.length >= 1) { + const index = files.findIndex((file) => file.includes('README')); + files.splice(index, 1); + files.unshift(targetDirectory); + } + + return files; +} + +module.exports = { + buildSidebar +}; diff --git a/src/en/features-and-api/0_symbols_as_id.md b/src/en/features-and-api/0_symbols_as_id.md new file mode 100644 index 0000000..66b50eb --- /dev/null +++ b/src/en/features-and-api/0_symbols_as_id.md @@ -0,0 +1,54 @@ +# Support for Symbols + +In very large applications using strings as the identifiers of the types to be injected by the InversifyJS can lead to naming collisions. InversifyJS supports and recommends the usage of [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) instead of string literals. + +::: tip +A symbol is a unique and immutable data type and may be used as an identifier for object properties. The symbol object is an implicit object wrapper for the symbol primitive data type. +::: + +```ts +import { Container, injectable, inject } from 'inversify'; + +let Symbols = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +@injectable() +class Katana implements Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(Symbols.Katana) katana: Katana, @inject(Symbols.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Symbols.Ninja).to(Ninja); +container.bind(Symbols.Katana).to(Katana); +container.bind(Symbols.Shuriken).to(Shuriken); +``` diff --git a/src/en/features-and-api/10_provider_injection.md b/src/en/features-and-api/10_provider_injection.md new file mode 100644 index 0000000..0e3c818 --- /dev/null +++ b/src/en/features-and-api/10_provider_injection.md @@ -0,0 +1,307 @@ +# Injecting a Provider (asynchronous Factory) + +Binds an abstraction to a Provider. A provider is an asynchronous factory, this +is useful when dealing with asynchronous I/O operations. + +```ts +type KatanaProvider = () => Promise; + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public shuriken: Shuriken; + public katanaProvider: KatanaProvider; + + public constructor( + @inject('KatanaProvider') katanaProvider: KatanaProvider, + @inject('Shuriken') shuriken: Shuriken + ) { + this.katanaProvider = katanaProvider; + this.katana = null; + this.shuriken = shuriken; + } + + public fight() { + return this.katana.hit(); + } + public sneak() { + return this.shuriken.throw(); + } +} +``` + +```ts +container.bind('KatanaProvider').toProvider((context) => { + return () => { + return new Promise((resolve) => { + let katana = context.container.get('Katana'); + resolve(katana); + }); + }; +}); + +var ninja = container.get('Ninja'); + +ninja + .katanaProvider() + .then((katana) => { + ninja.katana = katana; + }) + .catch((e) => { + console.log(e); + }); +``` + +## Provider custom arguments + +The `toProvider` binding expects a `ProviderCreator` as its only argument: + +```ts +interface ProviderCreator extends Function { + (context: Context): Provider; +} +``` + +The signature of a provider look as follows: + +```ts +interface Provider extends Function { + (...args: any[]): ((...args: any[]) => Promise) | Promise; +} +``` + +These type signatures allow as to pass custom arguments to a provider: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string, damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string, damage: number) => { + // Custom args! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; +}); + +let katanaProvider = container.get('SwordProvider'); + +katanaProvider('gold', 100).then((powerfulGoldKatana) => { + // Apply all custom args + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +katanaProvider('gold', 10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider partial application + +We can also pass the arguments using partial application: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string) => (damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string) => { + // Custom arg 1! + return (damage: number) => { + // Custom arg 2! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; + }; +}); + +let katanaProvider = container.get('SwordProvider'); +let goldKatanaProvider = katanaProvider('gold'); // Apply the first custom arg! + +goldKatanaProvider(100).then((powerfulGoldKatana) => { + // Apply the second custom args! + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +goldKatanaProvider(10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider as a singleton + +A Provider is always injected as a singleton but you can control if the value returned by the +Provider is uses singleton or transient scope: + +```ts +let container = new Container(); + +interface Warrior { + level: number; +} + +@injectable() +class Ninja implements Warrior { + public level: number; + public constructor() { + this.level = 0; + } +} + +type WarriorProvider = (level: number) => Promise; + +container + .bind('Warrior') + .to(Ninja) + .inSingletonScope(); // Value is singleton! + +container.bind('WarriorProvider').toProvider((context) => { + return (increaseLevel: number) => { + return new Promise((resolve) => { + setTimeout(() => { + let warrior = context.container.get('Warrior'); // Get singleton! + warrior.level += increaseLevel; + resolve(warrior); + }, 100); + }); + }; +}); + +let warriorProvider = container.get('WarriorProvider'); + +warriorProvider(10).then((warrior) => { + expect(warrior.level).to.eql(10); +}); + +warriorProvider(10).then((warrior2) => { + expect(warrior.level).to.eql(20); +}); +``` + +## Provider defaults + +The following function can be used as a helper to provide a default value when a provider is rejected: + +```ts +function valueOrDefault(provider: () => Promise, defaultValue: T) { + return new Promise((resolve, reject) => { + provider() + .then((value) => { + resolve(value); + }) + .catch(() => { + resolve(defaultValue); + }); + }); +} +``` + +The following example showcases how to apply the `valueOrDefault` helper: + +```ts +@injectable() +class Ninja { + public level: number; + public rank: string; + public constructor() { + this.level = 0; + this.rank = 'Ninja'; + } + public train(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + this.level += 10; + resolve(this.level); + }, 100); + }); + } +} + +@injectable() +class NinjaMaster { + public rank: string; + public constructor() { + this.rank = 'NinjaMaster'; + } +} + +type NinjaMasterProvider = () => Promise; + +let container = new Container(); + +container + .bind('Ninja') + .to(Ninja) + .inSingletonScope(); +container.bind('NinjaMasterProvider').toProvider((context) => { + return () => { + return new Promise((resolve, reject) => { + let ninja = context.container.get('Ninja'); + ninja.train().then((level) => { + if (level >= 20) { + resolve(new NinjaMaster()); + } else { + reject('Not enough training'); + } + }); + }); + }; +}); + +let ninjaMasterProvider = container.get('NinjaMasterProvider'); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // Using default here because the provider was rejected (the ninja has a level below 20) + expect(ninjaMaster.rank).to.eql('DefaultNinjaMaster'); +}); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // A NinjaMaster was provided because the the ninja has a level above 20 + expect(ninjaMaster.rank).to.eql('NinjaMaster'); + done(); +}); +``` diff --git a/src/en/features-and-api/11_activation_handler.md b/src/en/features-and-api/11_activation_handler.md new file mode 100644 index 0000000..6be77d2 --- /dev/null +++ b/src/en/features-and-api/11_activation_handler.md @@ -0,0 +1,67 @@ +# Activation handler + +It is possible to add an activation handler for a type. The activation handler is invoked after a dependency has been resolved and before it is added to a cache (if singleton or request singleton - [see scope](../features-and-api/4_scope)) and injected. The activation handler will not be invoked if the dependency is taken from a cache. The activation handler can be synchronous or asynchronous. + +Activation handlers are useful to keep our dependencies agnostic of the implementation of crosscutting concerns like caching or logging. + +The following example uses a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to intercept one of the methods (`use`) of a dependency (`Katana`). + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + public use() { + console.log('Used Katana!'); + } +} + +interface Ninja { + katana: Katana; +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(@inject('Katana') katana: Katana) { + this.katana = katana; + } +} +``` + +```ts +container.bind('Ninja').to(Ninja); + +container + .bind('Katana') + .to(Katana) + .onActivation((context, katana) => { + let handler = { + apply: function(target, thisArgument, argumentsList) { + console.log(`Starting: ${new Date().getTime()}`); + let result = target.apply(thisArgument, argumentsList); + console.log(`Finished: ${new Date().getTime()}`); + return result; + } + }; + katana.use = new Proxy(katana.use, handler); + return katana; + }); +``` + +```ts +let ninja = container.get(); +ninja.katana.use(); +> Starting: 1457895135761 +> Used Katana! +> Finished: 1457895135762 +``` + +There are multiple ways to provide an activation handler + +- Adding the handler to the container +- Adding the handler to the binding + +When multiple activation handlers are binded to a service identifier, the binding handler is called before any others. Then the container handlers are called, starting at the root container and descending the descendant containers stopping at the container with the binding. diff --git a/src/en/features-and-api/12_deactivation_handler.md b/src/en/features-and-api/12_deactivation_handler.md new file mode 100644 index 0000000..9f7bd92 --- /dev/null +++ b/src/en/features-and-api/12_deactivation_handler.md @@ -0,0 +1,90 @@ +# Deactivation handler + +It is possible to add a deactivation handler for a type binded in singleton scope. The handler can be synchronous or asynchronous. The deactivation handler is invoked before the type is unbinded from the container: + +```ts +@injectable() +class Destroyable {} + +const container = new Container(); +container + .bind('Destroyable') + .toDynamicValue(() => Promise.resolve(new Destroyable())) + .inSingletonScope() + .onDeactivation((destroyable: Destroyable) => { + console.log('Destroyable service is about to be unbinded'); + }); + +await container.get('Destroyable'); + +await container.unbind('Destroyable'); +``` + +It's possible to add a deactivation handler in multiple ways + +- Adding the handler to the container. +- Adding the handler to a binding. +- Adding the handler to the class through the [preDestroy decorator](../features-and-api/26_pre_destroy). + +Handlers added to the container are the first ones to be resolved. Any handler added to a child container is called before the ones added to their parent. Relevant bindings from the container are called next and finally the `preDestroy` method is called. In the example above, relevant bindings are those bindings bound to the unbinded "Destroyable" service identifer. + +The example below demonstrates call order. + +```ts +let roll = 1; +let binding = null; +let klass = null; +let parent = null; +let child = null; + +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + return new Promise((presolve) => { + klass = roll; + roll += 1; + presolve({}); + }); + } +} + +const container = new Container(); +container.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + parent = roll; + roll += 1; + presolve(); + }); +}); + +const childContainer = container.createChild(); +childContainer + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope() + .onDeactivation( + () => + new Promise((presolve) => { + binding = roll; + roll += 1; + presolve(); + }) + ); +childContainer.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + child = roll; + roll += 1; + presolve(); + }); +}); + +childContainer.get('Destroyable'); +await childContainer.unbindAsync('Destroyable'); + +expect(roll).eql(5); +expect(child).eql(1); +expect(parent).eql(2); +expect(binding).eql(3); +expect(klass).eql(4); +``` diff --git a/src/en/features-and-api/13_post_construct.md b/src/en/features-and-api/13_post_construct.md new file mode 100644 index 0000000..ee71af7 --- /dev/null +++ b/src/en/features-and-api/13_post_construct.md @@ -0,0 +1,66 @@ +# Post Construct Decorator + +It is possible to add a **@postConstruct** decorator for a class method. This decorator +will run after an object is instantiated and before any activation handlers. This +is useful in situations when the constructor has been called but the component has not +yet initialized or in cases you want to perform an initialization logic after the constructor call. + +Its some other cases it gives you a contract that guarantees +that this method will be invoked only once in the lifetime +of the object when used in singleton scope. See the following examples for usage. + +The method can be synchronous or asynchronous. + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + constructor() { + console.log('Katana is born'); + } + + public use() { + return 'Used Katana!'; + } + + @postConstruct() + public testMethod() { + console.log('Used Katana!'); + } +} +``` + +```ts +container.bind('Katana').to(Katana); +``` + +```ts +let catana = container.get(); +> Katana is born +> Used Katana! +``` + +Note that you cannot use more than one @postConstruct decorators +on the same class. It will throw an error. + +```ts +class Katana { + @postConstruct() + public testMethod1() {/* ... */} + + @postConstruct() + public testMethod2() {/* ... */} + } + +Katana.toString(); +> Error("Cannot apply @postConstruct decorator multiple times in the same class") +``` + +Usage in basic Javascript + +```js +inversify.decorate(inversify.postConstruct(), Katana.prototype, 'testMethod'); +``` diff --git a/src/en/features-and-api/14_middleware.md b/src/en/features-and-api/14_middleware.md new file mode 100644 index 0000000..603f664 --- /dev/null +++ b/src/en/features-and-api/14_middleware.md @@ -0,0 +1,179 @@ +# Middleware + +InversifyJS performs 3 mandatory operations before resolving a dependency: + +- Annotation +- Planning +- Resolution + +In some cases there will be some additional operations: + +- Activation +- Middleware + +If we have configured some Middleware it will be executed at some point before or after the planning, +resolution and activation phases. + +Middleware can be used to implement powerful development tools. This kind of tools will help developers +to identify problems during the development process. + +## Basic middleware + +```ts +import { interfaces, Container } from 'inversify'; + +function logger(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let start = new Date().getTime(); + let result = planAndResolve(args); + let end = new Date().getTime(); + console.log(`wooooo ${end - start}`); + return result; + }; +} + +let container = new Container(); +container.applyMiddleware(logger); +``` + +Now that we have declared a middleware we can create a new Container and use its applyMiddleware +method to apply it: + +```ts +interface Ninja {} + +@injectable() +class Ninja implements Ninja {} + +let container = new Container(); +container.bind('Ninja').to(Ninja); + +container.applyMiddleware(logger); +``` + +The logger middleware will log in console the execution time: + +```ts +let ninja = container.get("Ninja"); + +> 21 +``` + +## Multiple middleware functions + +When multiple middleware functions are applied: + +```ts +container.applyMiddleware(middleware1, middleware2); +``` + +The middleware will be invoked from right to left. +This means that `middleware2` is invoked before `middleware1`. + +## Context interceptor + +In some cases you may want to intercept the resolution plan. + +The default `contextInterceptor` is passed to the middleware as an property of `args`. + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + // args.nextContextInterceptor + // ... + }; +} +``` + +You can extend the default `contextInterceptor` using a function: + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let nextContextInterceptor = args.contextInterceptor; + args.contextInterceptor = (context: interfaces.Context) => { + console.log(context); + return nextContextInterceptor(context); + }; + return planAndResolve(args); + }; +} +``` + +## Custom metadata reader + +::: warning +Please note that it is not recommended to create your own custom +metadata reader. We have included this feature to allow library / framework creators +to have a higher level of customization but the average user should not use a custom +metadata reader. In general, a custom metadata reader should only be used when +developing a framework in order to provide users with an annotation APIs +less explicit than the default annotation API. + +If you are developing a framework or library and you create a custom metadata reader, +Please remember to provide your framework with support for an alternative for all the +decorators in the default API: ` @injectable, ``@inject `, `@multiInject`, `@tagged`, +`@named`, `@optional`, `@targetName` & `@unmanaged`. +::: + +Middleware allows you to intercept a plan and resolve it but you are not allowed to change the way the annotation phase behaves. + +There is a second extension point that allows you to decide what kind of annotation +system you would like to use. The default annotation system is powered by decorators and +reflect-metadata: + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Katana') katana: Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +You can use a custom metadata reader to implement a custom annotation system. + +For example, you could implement an annotation system based on static properties: + +```ts +class Ninja implements Ninja { + public static constructorInjections = ['Katana', 'Shuriken']; + + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +A custom metadata reader must implement the `interfaces.MetadataReader` interface. + +A full example [can be found in our unit tests](https://github.com/inversify/InversifyJS/blob/master/test/features/metadata_reader.test.ts). + +Once you have a custom metadata reader you will be ready to apply it: + +```ts +let container = new Container(); +container.applyCustomMetadataReader(new StaticPropsMetadataReader()); +``` diff --git a/src/en/features-and-api/15_multi_injection.md b/src/en/features-and-api/15_multi_injection.md new file mode 100644 index 0000000..2d0798a --- /dev/null +++ b/src/en/features-and-api/15_multi_injection.md @@ -0,0 +1,94 @@ +# Multi-injection + +We can use multi-injection When two or more concretions have been bound to the an abstraction. +Notice how an array of `Weapon` is injected into the `Ninja` class via its constructor thanks to the usage of the `@multiInject` decorator: + +```ts +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name = 'Katana'; +} + +@injectable() +class Shuriken implements Weapon { + public name = 'Shuriken'; +} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@multiInject('Weapon') weapons: Weapon[]) { + this.katana = weapons[0]; + this.shuriken = weapons[1]; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon`: + +```ts +container.bind('Ninja').to(Ninja); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); +``` + +## About the spread `...` operator + +In early releases of InversifyJS the spread operator used to fail without throwing any errors. +That was not acceptable and we implemented a fix that allows you to inject arrays using the +spread operator. However it is not recommended because it turns out to be a bit useless. + +You can inject using `@multiInject` and `...` as follows: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) ...args: Bar[][]) { + // args will always contain one unique item the value of that item is a Bar[] + this.bar = args[0]; + } +} +``` + +The main problem is that this requires the type of `args` to be `Bar[][]` +because multiInject will wrap the injections using an array and the spread +operator will do the same. As a result the injection is wrapped by an array +two times. + +We tried to solve this problem but the only way was to generate some additional +metadata using a `@spread()` decorator. + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) @spread() ...args: Bar[]) { + this.bar = args[0]; + } +} +``` + +We discarded this idea because it is better to use decorators when there is not +other way to achieve something. In this case there is a much simpler way to +achieve the desired result. We just need to **use `@multiInject` and avoid using `...`**: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) args: Bar[]) { + this.bar = args; + } +} +``` diff --git a/src/en/features-and-api/16_tagged_bindings.md b/src/en/features-and-api/16_tagged_bindings.md new file mode 100644 index 0000000..bf39534 --- /dev/null +++ b/src/en/features-and-api/16_tagged_bindings.md @@ -0,0 +1,48 @@ +# Tagged bindings + +We can use tagged bindings to fix `AMBIGUOUS_MATCH` errors when two or more +concretions have been bound to an abstraction. Notice how the constructor +arguments of the `Ninja` class have been annotated using the `@tagged` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @tagged('canThrow', false) katana: Weapon, + @inject('Weapon') @tagged('canThrow', true) shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetTagged` +constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); +container + .bind(weaponId) + .to(Katana) + .whenTargetTagged('canThrow', false); +container + .bind(weaponId) + .to(Shuriken) + .whenTargetTagged('canThrow', true); +``` diff --git a/src/en/features-and-api/17_custom_tag_decorators.md b/src/en/features-and-api/17_custom_tag_decorators.md new file mode 100644 index 0000000..60e4af4 --- /dev/null +++ b/src/en/features-and-api/17_custom_tag_decorators.md @@ -0,0 +1,18 @@ +# Create your own tag decorators + +Creating your own decorators is really simple: + +```ts +let throwable = tagged('canThrow', true); +let notThrowable = tagged('canThrow', false); + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@inject('Weapon') @notThrowable katana: Weapon, @inject('Weapon') @throwable shuriken: Weapon) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/en/features-and-api/18_named_bindings.md b/src/en/features-and-api/18_named_bindings.md new file mode 100644 index 0000000..f64595d --- /dev/null +++ b/src/en/features-and-api/18_named_bindings.md @@ -0,0 +1,48 @@ +# Named bindings + +We can use named bindings to fix `AMBIGUOUS_MATCH` errors when two or more concretions have +been bound to the an abstraction. Notice how the constructor arguments of the `Ninja` class +have been annotated using the `@named` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @named('strong') katana: Weapon, + @inject('Weapon') @named('weak') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetNamed` constraint is +added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind('Ninja').to(Ninja); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` diff --git a/src/en/features-and-api/19_default_targets.md b/src/en/features-and-api/19_default_targets.md new file mode 100644 index 0000000..48b43b1 --- /dev/null +++ b/src/en/features-and-api/19_default_targets.md @@ -0,0 +1,104 @@ +# whenTargetIsDefault + +When multiple bindings are available for a given service identifier, we can use +one of the following features to resolve the potential `AMBIGUOUS_MATCH` exception: + +- [Named bindings](../features-and-api/18_named_bindings) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Contextual bindings](../features-and-api/21_contextual_bindings) +- Default targets + +In this section we will explain how to use default targets. + +We can resolve an `AMBIGUOUS_MATCH` exception using a named constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` + +Or a tagged constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('strong', true); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('strong', false); +``` + +The problem with this solution is that we will have to annotate using +the `@named("strong")`/`@named("weak")` or `@tagged("strong", true)`/`@tagged("strong", false)` +every single injection. + +A better solution is to use a default target: + +```ts +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); +``` + +We can use the `whenTargetIsDefault` to indicate which binding should be used as default +to resolve an `AMBIGUOUS_MATCH` exception when no `@named` or `@tagged` annotations +are available. + +```ts +let TYPES = { + Weapon: 'Weapon' +}; + +let TAG = { + throwable: 'throwable' +}; + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken implements Weapon { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +let container = new Container(); +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); + +let defaultWeapon = container.get(TYPES.Weapon); +let throwableWeapon = container.getNamed(TYPES.Weapon, TAG.throwable); + +expect(defaultWeapon.name).eql('Katana'); +expect(throwableWeapon.name).eql('Shuriken'); +``` diff --git a/src/en/features-and-api/1_container_api.md b/src/en/features-and-api/1_container_api.md new file mode 100644 index 0000000..281b540 --- /dev/null +++ b/src/en/features-and-api/1_container_api.md @@ -0,0 +1,811 @@ +# The Container API + +The InversifyJS container is where dependencies are first configured through bind and, possibly later, reconfigured and removed. The container can be worked on directly in this regard or container modules can be utilized. +You can query the configuration and resolve configured dependencies with resolved and the 'get' methods. +You can react to resolutions with container activation handlers and unbinding with container deactivation handlers. +You can create container hierarchies where container ascendants can supply the dependencies for descendants. +For testing, state can be saved as a snapshot on a stack and later restored. +For advanced control you can apply middleware to intercept the resolution request and the resolved dependency. +You can even provide your own annotation solution. + +## Container Options + +Container options can be passed to the Container constructor and defaults will be provided if you do not or if you do but omit an option. +Options can be changed after construction and will be shared by child containers created from the Container if you do not provide options for them. + +### defaultScope + +The default scope is `transient` when binding to/toSelf/toDynamicValue/toService. +The other types of bindings are `singleton`. + +You can use container options to change the default scope for the bindings that default to `transient` at application level: + +```ts +let container = new Container({ defaultScope: 'Singleton' }); +``` + +For all types of bindings you can change the scope when declaring: + +```ts +container + .bind(TYPES.Warrior) + .to(Ninja) + .inSingletonScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inTransientScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inRequestScope(); +``` + +### autoBindInjectable + +You can use this to activate automatic binding for `@injectable()` decorated classes: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.isBound(Ninja); // returns false +container.get(Ninja); // returns a Ninja +container.isBound(Ninja); // returns true +``` + +Manually defined bindings will take precedence: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.bind(Ninja).to(Samurai); +container.get(Ninja); // returns a Samurai +``` + +### skipBaseClassChecks + +You can use this to skip checking base classes for the @injectable property, which is +especially useful if any of your @injectable classes extend classes that you don't control +(third party classes). By default, this value is `false`. + +```ts +let container = new Container({ skipBaseClassChecks: true }); +``` + +### merge + +```ts +container.merge(a: interfaces.Container, b: interfaces.Container, ...containers: interfaces.Container[]): interfaces.Container +``` + +Creates a new Container containing the bindings ( cloned bindings ) of two or more containers: + +```ts +@injectable() +class Ninja { + public name = 'Ninja'; +} + +@injectable() +class Shuriken { + public name = 'Shuriken'; +} + +let CHINA_EXPANSION_TYPES = { + Ninja: 'Ninja', + Shuriken: 'Shuriken' +}; + +let chinaExpansionContainer = new Container(); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Ninja).to(Ninja); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Shuriken).to(Shuriken); + +@injectable() +class Samurai { + public name = 'Samurai'; +} + +@injectable() +class Katana { + public name = 'Katana'; +} + +let JAPAN_EXPANSION_TYPES = { + Katana: 'Katana', + Samurai: 'Samurai' +}; + +let japanExpansionContainer = new Container(); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Samurai).to(Samurai); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Katana).to(Katana); + +let gameContainer = Container.merge(chinaExpansionContainer, japanExpansionContainer); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Ninja).name).to.eql('Ninja'); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Shuriken).name).to.eql('Shuriken'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Samurai).name).to.eql('Samurai'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Katana).name).to.eql('Katana'); +``` + +### applyCustomMetadataReader + +```ts +container.applyCustomMetadataReader(metadataReader: interfaces.MetadataReader): void +``` + +An advanced feature.... See [middleware](../features-and-api/14_middleware). + +### applyMiddleware + +```ts +container.applyMiddleware(...middleware: interfaces.Middleware[]): void +``` + +An advanced feature that can be used for cross cutting concerns. See [middleware](../features-and-api/14_middleware). + +### bind + +```ts +container.bind\(serviceIdentifier: interfaces.ServiceIdentifier\): interfaces.BindingToSyntax\ +``` + +### createChild + +```ts +container.createChild(containerOptions?: interfaces.ContainerOptions): Container; +``` + +Create a [container hierarchy ](../features-and-api/20_hierarchical_di). If you do not provide options the child receives the options of the parent. + +### get + +```ts +container.get\(serviceIdentifier: interfaces.ServiceIdentifier\): T +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); + +let katana = container.get('Weapon'); +``` + +### getAsync + +```ts +container.getAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +async function buildLevel1(): Level1 { + return new Level1(); +} + +let container = new Container(); +container.bind('Level1').toDynamicValue(() => buildLevel1()); + +let level1 = await container.getAsync('Level1'); // Returns Promise +``` + +### getNamed + +```ts +container.getNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('chinese'); + +let katana = container.getNamed('Weapon', 'japanese'); +let shuriken = container.getNamed('Weapon', 'chinese'); +``` + +### getNamedAsync + +```ts +container.getNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetNamed('chinese'); + +let katana = await container.getNamedAsync('Weapon', 'japanese'); +let shuriken = await container.getNamedAsync('Weapon', 'chinese'); +``` + +### getTagged + +```ts +container.getTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('faction', 'ninja'); + +let katana = container.getTagged('Weapon', 'faction', 'samurai'); +let shuriken = container.getTagged('Weapon', 'faction', 'ninja'); +``` + +### getTaggedAsync + +```ts +container.getTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetTagged('faction', 'ninja'); + +let katana = await container.getTaggedAsync('Weapon', 'faction', 'samurai'); +let shuriken = await container.getTaggedAsync('Weapon', 'faction', 'ninja'); +``` + +### getAll + +```ts +container.getAll\(serviceIdentifier: interfaces.ServiceIdentifier\): T[] +``` + +Get all available bindings for a given identifier. All the bindings must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); + +let weapons = container.getAll('Weapon'); // returns Weapon[] +``` + +### getAllAsync + +```ts +container.getAllAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Get all available bindings for a given identifier: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').toDynamicValue(async () => new Shuriken()); + +let weapons = await container.getAllAsync('Weapon'); // returns Promise +``` + +### getAllNamed + +```ts +container.getAllNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetNamed('es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetNamed('es'); + +let fr = container.getAllNamed('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllNamed('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllNamedAsync + +```ts +container.getAllNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetNamed('es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetNamed('es'); + +let fr = await container.getAllNamedAsync('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllNamedAsync('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTagged + +```ts +container.getAllTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetTagged('lang', 'es'); + +let fr = container.getAllTagged('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllTagged('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTaggedAsync + +```ts +container.getAllTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetTagged('lang', 'es'); + +let fr = await container.getAllTaggedAsync('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllTaggedAsync('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### isBound + +```ts +container.isBound(serviceIdentifier: interfaces.ServiceIdentifier\): boolean +``` + +You can use the `isBound` method to check if there are registered bindings for a given service identifier. + +```ts +interface Warrior {} +let warriorId = 'Warrior'; +let warriorSymbol = Symbol.for('Warrior'); + +@injectable() +class Ninja implements Warrior {} + +interface Katana {} +let katanaId = 'Katana'; +let katanaSymbol = Symbol.for('Katana'); + +@injectable() +class Katana implements Katana {} + +let container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(warriorId).to(Ninja); +container.bind(warriorSymbol).to(Ninja); + +expect(container.isBound(Ninja)).to.eql(true); +expect(container.isBound(warriorId)).to.eql(true); +expect(container.isBound(warriorSymbol)).to.eql(true); +expect(container.isBound(Katana)).to.eql(false); +expect(container.isBound(katanaId)).to.eql(false); +expect(container.isBound(katanaSymbol)).to.eql(false); +``` + +### isBoundNamed + +```ts +container.isBoundNamed(serviceIdentifier: interfaces.ServiceIdentifier\, named: string): boolean +``` + +You can use the `isBoundNamed` method to check if there are registered bindings for a given service identifier with a given named constraint. + +```ts +const zero = 'Zero'; +const invalidDivisor = 'InvalidDivisor'; +const validDivisor = 'ValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetNamed(invalidDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetNamed(validDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(true); +``` + +### isBoundTagged + +```ts +container.isBoundTagged(serviceIdentifier: interfaces.ServiceIdentifier\, key: string, value: any): boolean +``` + +You can use the `isBoundTagged` method to check if there are registered bindings for a given service identifier with a given tagged constraint. + +```ts +const zero = 'Zero'; +const isValidDivisor = 'IsValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetTagged(isValidDivisor, false); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetTagged(isValidDivisor, true); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(true); +``` + +### load + +```ts +container.load(...modules: interfaces.ContainerModule[]): void +``` + +Calls the registration method of each module. See [container modules](../features-and-api/2_container_modules) + +### loadAsync + +```ts +container.loadAsync(...modules: interfaces.AsyncContainerModule[]): Promise\ +``` + +As per load but for asynchronous registration. + +### rebind + +```ts +container.rebind\(serviceIdentifier: interfaces.ServiceIdentifier\): : interfaces.BindingToSyntax\ +``` + +You can use the `rebind` method to replace all the existing bindings for a given `serviceIdentifier`. +The function returns an instance of `BindingToSyntax` which allows to create the replacement binding. + +```ts +let TYPES = { + someType: 'someType' +}; + +let container = new Container(); +container.bind(TYPES.someType).toConstantValue(1); +container.bind(TYPES.someType).toConstantValue(2); + +let values1 = container.getAll(TYPES.someType); +expect(values1[0]).to.eq(1); +expect(values1[1]).to.eq(2); + +container.rebind(TYPES.someType).toConstantValue(3); +let values2 = container.getAll(TYPES.someType); +expect(values2[0]).to.eq(3); +expect(values2[1]).to.eq(undefined); +``` + +### rebindAsync + +```ts +container.rebindAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\> +``` + +This is an asynchronous version of rebind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### resolve + +```ts +container.resolve\(constructor: interfaces.Newable\): T +``` + +Resolve is like `container.get(serviceIdentifier: ServiceIdentifier)` but it allows users to create an instance even if no bindings have been declared: + +```ts +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(katana: Katana) { + this.katana = katana; + } + public fight() { + return this.katana.hit(); + } +} + +const container = new Container(); +container.bind(Katana).toSelf(); + +const tryGet = () => container.get(Ninja); +expect(tryGet).to.throw('No matching bindings found for serviceIdentifier: Ninja'); + +const ninja = container.resolve(Ninja); +expect(ninja.fight()).to.eql('cut!'); +``` + +Please note that it only allows to skip declaring a binding for the root element in the dependency graph (composition root). All the sub-dependencies (e.g. `Katana` in the preceding example) will require a binding to be declared. + +### onActivation + +```ts +container.onActivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onActivation: interfaces.BindingActivation\): void +``` + +Adds an activation handler for all dependencies registered with the specified identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onActivation('Weapon', (context: interfaces.Context, katana: Katana): Katana | Promise => { + console.log('katana instance activation!'); + return katana; +}); + +let katana = container.get('Weapon'); +``` + +### onDeactivation + +```ts +container.onDeactivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onDeactivation: interfaces.BindingDeactivation\): void +``` + +Adds a deactivation handler for the dependencie's identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onDeactivation('Weapon', (katana: Katana): void | Promise => { + console.log('katana instance deactivation!'); +}); + +container.unbind('Weapon'); +``` + +### restore + +```ts +container.restore(): void; +``` + +Restore container state to last snapshot. + +### snapshot + +```ts +container.snapshot(): void +``` + +Save the state of the container to be later restored with the restore method. + +### unbind + +```ts +container.unbind(serviceIdentifier: interfaces.ServiceIdentifier\): void +``` + +Remove all bindings binded in this container to the service identifer. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAsync + +```ts +container.unbindAsync(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +This is the asynchronous version of unbind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unbindAll + +```ts +container.unbindAll(): void +``` + +Remove all bindings binded in this container. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAllAsync + +```ts +container.unbindAllAsync(): Promise\ +``` + +This is the asynchronous version of unbindAll. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unload + +```ts +container.unload(...modules: interfaces.ContainerModuleBase[]): void +``` + +Removes bindings and handlers added by the modules. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). +See [container modules](../features-and-api/2_container_modules) + +### unloadAsync + +```ts +container.unloadAsync(...modules: interfaces.ContainerModuleBase[]): Promise\ +``` + +Asynchronous version of unload. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### parent + +```ts +container.parent: Container | null; +``` + +Access the container hierarchy. + +### id + +```ts +container.id: number +``` + +An identifier auto generated to be unique. diff --git a/src/en/features-and-api/20_hierarchical_di.md b/src/en/features-and-api/20_hierarchical_di.md new file mode 100644 index 0000000..84a1bcc --- /dev/null +++ b/src/en/features-and-api/20_hierarchical_di.md @@ -0,0 +1,30 @@ +# Support for hierarchical DI systems + +Some applications use a hierarchical dependency injection (DI) system. +For example, Angular 2.0 applications use its own +[hierarchical DI system](https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html). + +In a hierarchical DI system, a container can have a parent container and multiple containers +can be used in one application. The containers form a hierarchical structure. + +When a container at the bottom of the hierarchical structure requests a dependency, +the container tries to satisfy that dependency with it's own bindings. If the container +lacks bindings, it passes the request up to its parent container. If that container can't +satisfy the request, it passes it along to its parent container. The requests keep +bubbling up until we find an container that can handle the request or run out of container +ancestors. + +```ts +let weaponIdentifier = 'Weapon'; + +@injectable() +class Katana {} + +let parentContainer = new Container(); +parentContainer.bind(weaponIdentifier).to(Katana); + +let childContainer = new Container(); +childContainer.parent = parentContainer; + +expect(childContainer.get(weaponIdentifier)).to.be.instanceOf(Katana); // true +``` diff --git a/src/en/features-and-api/21_contextual_bindings.md b/src/en/features-and-api/21_contextual_bindings.md new file mode 100644 index 0000000..f8b9da2 --- /dev/null +++ b/src/en/features-and-api/21_contextual_bindings.md @@ -0,0 +1,105 @@ +# Contextual bindings & @targetName + +The `@targetName` decorator is used to access the names of the constructor arguments from a +contextual constraint even when the code is compressed. The `constructor(katana, shuriken) { ...` +becomes `constructor(a, b) { ...` after compression but thanks to `@targetName` we can still +refer to the design-time names `katana` and `shuriken` at runtime. + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @targetName('katana') katana: Weapon, + @inject('Weapon') @targetName('shuriken') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a custom `when` constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); + +container + .bind('Weapon') + .to(Katana) + .when((request: interfaces.Request) => { + return request.target.name.equals('katana'); + }); + +container + .bind('Weapon') + .to(Shuriken) + .when((request: interfaces.Request) => { + return request.target.name.equals('shuriken'); + }); +``` + +The target fields implement the `IQueryableString` interface to help you to create your custom constraints: + +```ts +interface QueryableString { + startsWith(searchString: string): boolean; + endsWith(searchString: string): boolean; + contains(searchString: string): boolean; + equals(compareString: string): boolean; + value(): string; +} +``` + +We have included some helpers to facilitate the creation of custom constraints: + +```ts +import { Container, traverseAncerstors, taggedConstraint, namedConstraint, typeConstraint } from 'inversify'; + +let whenParentNamedCanThrowConstraint = (request: interfaces.Request) => { + return namedConstraint('canThrow')(request.parentRequest); +}; + +let whenAnyAncestorIsConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, typeConstraint(Ninja)); +}; + +let whenAnyAncestorTaggedConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, taggedConstraint('canThrow')(true)); +}; +``` + +The InversifyJS fluent syntax for bindings includes some already implemented common contextual constraints: + +```ts +interface BindingWhenSyntax { + when(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenTargetNamed(name: string): interfaces.BindingOnSyntax; + whenTargetTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenInjectedInto(parent: Function | string): interfaces.BindingOnSyntax; + whenParentNamed(name: string): interfaces.BindingOnSyntax; + whenParentTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenNoAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenAnyAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenAnyAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenNoAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenNoAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenNoAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; +} +``` diff --git a/src/en/features-and-api/22_property_injection.md b/src/en/features-and-api/22_property_injection.md new file mode 100644 index 0000000..46989c0 --- /dev/null +++ b/src/en/features-and-api/22_property_injection.md @@ -0,0 +1,128 @@ +# Property injection + +InversifyJS supports property injection because sometimes constructor injection is not the best kind of injection pattern. However, you should try to avoid using property injection and prefer constructor injection in most cases. + +> If the class cannot do its job without the dependency, then add it to the constructor. The class needs the new dependency, so you want your change to break things. Also, creating a class that is not fully initialized ("two-step construction") is an anti-pattern (IMHO). If the class can work without the dependency, a setter is fine. + +Source: [http://stackoverflow.com/](http://stackoverflow.com/questions/1503584/dependency-injection-through-constructors-or-property-setters) + +There are two cases in which you may want to use property injection. + +- When we CAN use InversifyJS to create an instance of a class. +- When we CANNOT use InversifyJS to create an instance of a class. + +These cases are quite different an require different implementations of property injection. + +## When we CAN use InversifyJS to create an instance of a class + +If you are working with a library or framework that allows InversifyJS +to create instances of the classes in the application, then you can inject into +a property using the `@inject` decorator: + +```ts +import { injectable, inject, container } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +@injectable() +class Summary { + // ... +} + +@injectable() +class Author { + // ... +} + +@injectable() +class Book { + private _author: Author; + private _summary: Summary; + + @inject('PrintService') + private _printService: PrintService; + + public constructor(@inject('Author') author: Author, @inject('Summary') summary: Summary) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +container.bind('Author').to(Author); +container.bind('Summary').to(Summary); +container.bind('Book').to(Book); + +// Book instance is created by InversifyJS +let book = container.get('Book'); +book.print(); +``` + +Please refer to our [unit tests](https://github.com/inversify/InversifyJS/blob/master/test/annotation/inject.test.ts) for additional examples. + +## When we CANNOT use InversifyJS to create an instance of a class + +InversifyJS has been designed in a way that facilitates its integration with as many +libraries and frameworks as possible. However, many of its features require being able to +create the instances of the classes in an application. + +The problem is that some frameworks take the control over the creation of instances. +For example, React takes control over the creation of instances of a given Component. + +We have developed an utility that allows you to inject into a property even when +InversifyJS has not created its instances: + +```ts +import getDecorators from 'inversify-inject-decorators'; +import { Container, injectable } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +let { lazyInject } = getDecorators(container); + +class Book { + private _author: string; + private _summary: string; + + @lazyInject('PrintService') + private _printService: PrintService; + + public constructor(author: string, summary: string) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +// Book instance is NOT created by InversifyJS +let book = new Book('Title', 'Summary'); +book.print(); +``` + +The utility module is called `inversify-inject-decorators` +and provides the following decorators: + +- `@lazyInject` for the injection of a property without metadata +- `@lazyInjectNamed` for the injection of a property without named metadata. +- `@lazyInjectTagged` for the injection of a property without tagged metadata. +- `@lazyMultiInject` for multi-injections. + +Please visit the module +[project on GitHub](https://github.com/inversify/inversify-inject-decorators) +to learn more. diff --git a/src/en/features-and-api/23_circular_dependencies.md b/src/en/features-and-api/23_circular_dependencies.md new file mode 100644 index 0000000..8164de1 --- /dev/null +++ b/src/en/features-and-api/23_circular_dependencies.md @@ -0,0 +1,21 @@ +# Circular dependencies + +## Circular dependencies in your modules (ES6, CommonJS, etc.) + +If you have a circular dependency between two modules and you use the `@inject(SomeClass)` annotation. At runtime, one module will be parsed before the other and the decorator could be invoked with `@inject(SomeClass /* SomeClass = undefined*/)`. InversifyJS will throw the following exception: + +> @inject called with undefined this could mean that the class \${name} has a circular dependency problem. You can use a LazyServiceIdentifer to overcome this limitation. + +There are two ways to overcome this limitation: + +- Use a `LazyServiceIdentifer`. The lazy identifier doesn't delay the injection of the dependencies and all dependencies are injected when the class instance is created. However, it does delay the access to the property identifier (solving the module issue). An example of this can be found in [our unit tests](https://github.com/krzkaczor/InversifyJS/blob/a53bf2cbee65803b197998c1df496c3be84731d9/test/inversify.test.ts#L236-L300). + +- Use the `@lazyInject` decorator. This decorator is part of the [`inversify-inject-decorators`](https://github.com/inversify/inversify-inject-decorators) module. The `@lazyInject` decorator delays the injection of the dependencies until they are actually used, this takes place after a class instance has been created. + +## Circular dependencies in the dependency graph (classes) + +InversifyJS is able to identify circular dependencies and will throw an exception to help you to identify the location of the problem if a circular dependency is detected: + +```ts +Error: Circular dependency found: Ninja -> A -> B -> C -> D -> A +``` diff --git a/src/en/features-and-api/24_inheritance.md b/src/en/features-and-api/24_inheritance.md new file mode 100644 index 0000000..4a8e908 --- /dev/null +++ b/src/en/features-and-api/24_inheritance.md @@ -0,0 +1,260 @@ +# Inheritance + +We try to provide developers with useful error feedback like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +This works fine in most cases but it causes some problem when using inheritance. + +For example, the following code snippet throws a misleading error: + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +```ts +@injectable() +class Warrior { + public rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super('master'); + } +} +``` + +In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: + +> A derived class must explicitly declare its constructor. + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +If you don't follow this rule an exception will be thrown: + +> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. + +The users have a few ways to overcome this limitation available: + +## Use the @unmanaged decorator + +The `@unmanaged()` decorator allow users to flag that an argument will +be manually injected into a base class. We use the word "unmanaged" +because InversifyJS does not have control under user provided values +and it doesn't manage their injection. + +The following code snippet showcases how to apply this decorator: + +```ts +import { Container, injectable, unmanaged } from '../src/inversify'; + +const BaseId = 'Base'; + +@injectable() +class Base { + public prop: string; + public constructor(@unmanaged() arg: string) { + this.prop = arg; + } +} + +@injectable() +class Derived extends Base { + public constructor() { + super('unmanaged-injected-value'); + } +} + +container.bind(BaseId).to(Derived); +let derived = container.get(BaseId); + +derived instanceof Derived2; // true +derived.prop; // "unmanaged-injected-value" +``` + +## Property setter + +You can use the `public`, `protected` or `private` access modifier and a +property setter to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() { + // args count = 0 + this.rank = null; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super(); + this.rank = 'master'; + } +} +``` + +## Property injection + +We can also use property injection to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() {} // args count = 0 +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + @injectNamed(TYPES.Rank, 'master') + @named('master') + protected rank: string; + + public constructor() { + // args count = 0 + super(); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Inject into the derived class + +If we don't want to avoid injecting into the base class we can +inject into the derived class and then into the base class using +its constructor (super). + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + public constructor( + @inject(TYPES.Rank) @named('master') rank: string // args count = 1 + ) { + super(rank); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +The following should also work: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +let TYPES = { + Rank: 'Rank', + Weapon: 'Weapon' +}; + +@injectable() +class SamuraiMaster extends Warrior { + public weapon: Weapon; + public constructor( + @inject(TYPES.Rank) @named('master') rank: string, // args count = 2 + @inject(TYPES.Weapon) weapon: Weapon + ) { + super(rank); + this.weapon = weapon; + } +} + +container.bind(TYPES.Weapon).to(Katana); + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Skip Base class `@injectable` checks + +Setting the `skipBaseClassChecks` option to `true` for the container will disable all checking of base classes. This means it will be completely up to the developer to ensure that the `super()` constructor is called with the correct arguments and at the correct time. + +```ts +// Not injectable +class UnmanagedBase { + public constructor(public unmanagedDependency: string) {} +} + +@injectable() +class InjectableDerived extends UnmanagedBase { + public constructor() // Any arguments defined here will be injected like normal + { + super("Don't forget me..."); + } +} + +const container = new Container({ skipBaseClassChecks: true }); +container.bind(InjectableDerived).toSelf(); +``` + +This will work, and you'll be able to use your `InjectableDerived` class just like normal, including injecting dependencies from elsewhere in the container through the constructor. The one caveat is that you must make sure your `UnmanagedBase` receives the correct arguments. + +## What can I do when my base class is provided by a third party module? + +In some cases, you may get errors about missing annotations in classes +provided by a third party module like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +You can overcome this problem using the `decorate` function: + +```ts +import { decorate, injectable } from 'inversify'; +import SomeClass from 'some-module'; + +decorate(injectable(), SomeClass); +return SomeClass; +``` + +Check out the [JS example](https://github.com/inversify/InversifyJS/blob/master/wiki/basic_js_example.md) +page on the wiki for more info. diff --git a/src/en/features-and-api/25_transitive_bindings.md b/src/en/features-and-api/25_transitive_bindings.md new file mode 100644 index 0000000..69e2db1 --- /dev/null +++ b/src/en/features-and-api/25_transitive_bindings.md @@ -0,0 +1,62 @@ +# Transitive bindings + +A transitive type binding allows as to declare a type binding that is resolved by a previously declared type binding. + +A transitive binding can be declared using the `toService` method: + +```ts +@injectable() +class MySqlDatabaseTransactionLog { + public time: number; + public name: string; + public constructor() { + this.time = new Date().getTime(); + this.name = 'MySqlDatabaseTransactionLog'; + } +} + +@injectable() +class DatabaseTransactionLog { + public time: number; + public name: string; +} + +@injectable() +class TransactionLog { + public time: number; + public name: string; +} + +const container = new Container(); +container + .bind(MySqlDatabaseTransactionLog) + .toSelf() + .inSingletonScope(); +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); + +const mySqlDatabaseTransactionLog = container.get(MySqlDatabaseTransactionLog); +const databaseTransactionLog = container.get(DatabaseTransactionLog); +const transactionLog = container.get(TransactionLog); + +expect(mySqlDatabaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(databaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(transactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(mySqlDatabaseTransactionLog.time).to.eq(databaseTransactionLog.time); +expect(databaseTransactionLog.time).to.eq(transactionLog.time); +``` + +There is also an utility function named `multiBindToService` which allows us to declare multiple transitive bindings in one go. + +For example, instead of writing the following: + +```ts +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); +``` + +We can use `multiBindToService` to write the following: + +```ts +multiBindToService(container)(MySqlDatabaseTransactionLog)(DatabaseTransactionLog, TransactionLog); +``` diff --git a/src/en/features-and-api/26_pre_destroy.md b/src/en/features-and-api/26_pre_destroy.md new file mode 100644 index 0000000..1a6879e --- /dev/null +++ b/src/en/features-and-api/26_pre_destroy.md @@ -0,0 +1,23 @@ +# Pre Destroy Decorator + +It is possible to add a **@preDestroy** decorator for a class method. This decorator will run before a service is unbinded for any cached instance. For this reason, only bindings in singleton scope can contain a method with this decorator. + +```ts +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + console.log('Destroyable is about to be unbinded!'); + } +} + +const container = new Container(); +container + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope(); + +container.get('Destroyable'); + +container.unbindAll(); +``` diff --git a/src/en/features-and-api/2_container_modules.md b/src/en/features-and-api/2_container_modules.md new file mode 100644 index 0000000..c5ee011 --- /dev/null +++ b/src/en/features-and-api/2_container_modules.md @@ -0,0 +1,65 @@ +# Declaring container modules + +Container modules can help you to manage the complexity of your bindings in very large applications. + +The constructor argument for ContainerModule and AsyncContainerModule is a registration callback that is passed functions that behave the same as the methods of the Container class. The registration callback for the AsyncContainerModule is asynchronous. + +When a container module is loaded into a Container the registration callback is invoked. This is the opportunity for the container module to register bindings and handlers. Use the Container load method for ContainerModule instances and the Container loadAsync method for AsyncContainerModule instances. + +When a container module is unloaded from a Container the bindings added by that container will be removed and the [deactivation process](../features-and-api/12_deactivation_handler) will occur for each of them. Container deactivation and [activation handlers](../features-and-api/11_activation_handler) will also be removed. +Use the unloadAsync method to unload when there will be an async deactivation handler or async [pre destroy](../features-and-api/26_pre_destroy) + +## Synchronous container modules + +```ts +let warriors = new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind) => { + bind('Ninja').to(Ninja); +}); + +let weapons = new ContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +container.load(warriors, weapons); +container.unload(warriors); +``` + +## Asynchronous container modules + +```ts +let warriors = new AsyncContainerModule(async (bind: interfaces.Bind, unbind: interfaces.Unbind) => { + const ninja = await getNinja(); + bind('Ninja').toConstantValue(ninja); +}); + +let weapons = new AsyncContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +await container.loadAsync(warriors, weapons); +container.unload(warriors); +``` diff --git a/src/en/features-and-api/3_container_snapshots.md b/src/en/features-and-api/3_container_snapshots.md new file mode 100644 index 0000000..8125b41 --- /dev/null +++ b/src/en/features-and-api/3_container_snapshots.md @@ -0,0 +1,53 @@ +# Container snapshots + +Declaring container snapshots is a feature that helps you to write unit tests with ease: + +```ts +import { expect } from 'chai'; +import * as sinon from 'sinon'; + +// application container is shared by all unit tests +import container from '../../src/ioc/container'; + +describe('Ninja', () => { + beforeEach(() => { + // create a snapshot so each unit test can modify + // it without breaking other unit tests + container.snapshot(); + }); + + afterEach(() => { + // Restore to last snapshot so each unit test + // takes a clean copy of the application container + container.restore(); + }); + + // each test is executed with a snapshot of the container + + it('Ninja can fight', () => { + let katanaMock = { + hit: () => { + return 'hit with mock'; + } + }; + + container.unbind('Katana'); + container.bind('Katana').toConstantValue(katanaMock); + let ninja = container.get('Ninja'); + expect(ninja.fight()).eql('hit with mock'); + }); + + it('Ninja can sneak', () => { + let shurikenMock = { + throw: () => { + return 'hit with mock'; + } + }; + + container.unbind('Shuriken'); + container.bind('Shuriken').toConstantValue(shurikenMock); + let ninja = container.get('Shuriken'); + expect(ninja.sneak()).eql('hit with mock'); + }); +}); +``` diff --git a/src/en/features-and-api/4_scope.md b/src/en/features-and-api/4_scope.md new file mode 100644 index 0000000..2716beb --- /dev/null +++ b/src/en/features-and-api/4_scope.md @@ -0,0 +1,104 @@ +# Controlling the scope of the dependencies + +InversifyJS uses transient scope by default but you can also use singleton and request scope: + +```ts +container + .bind('Shuriken') + .to(Shuriken) + .inTransientScope(); // Default +container + .bind('Shuriken') + .to(Shuriken) + .inSingletonScope(); +container + .bind('Shuriken') + .to(Shuriken) + .inRequestScope(); +``` + +## About `inSingletonScope` + +There are many available kinds of bindings: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingWhenOnSyntax; + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +In terms of how scope behaves we can group these types of bindings in two main groups: + +- Bindings that will inject an `object` +- Bindings that will inject a `function` + +### Bindings that will inject an `object` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingInWhenOnSyntax; +} +``` + +The `inTransientScope` is used by default and we can select the scope of this types of binding, except for `toConstantValue` which will always use `inSingletonScope`. + +When we invoke `container.get` for the first time and we are using `to`, `toSelf` or `toDynamicValue` the InversifyJS container will try to generate an object instance or value using a constructor or the dynamic value factory. If the scope has been set to `inSingletonScope` the value is cached. The second time we invoke `container.get` for the same resource ID, and if `inSingletonScope` has been selected, InversifyJS will try to get the value from the cache. + +Note that a class can have some dependencies and a dynamic value can access other types via the current context. These dependencies may or may not be a singleton independently of the selected scope of their parent object in their respective composition tree, + +### Bindings that will inject a `function` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +We cannot select the scope of this types of binding because the value to be injected (a factory `function`) is always a singleton. However, the factory internal implementation may or may not return a singleton. + +For example, the following binding will inject a factory which will always be a singleton. + +```ts +container.bind>('Factory').toAutoFactory('Katana'); +``` + +However, the value returned by the factory may or may not be a singleton: + +```ts +container + .bind('Katana') + .to(Katana) + .inTransientScope(); +// or +container + .bind('Katana') + .to(Katana) + .inSingletonScope(); +``` + +## About `inRequestScope` + +When we use inRequestScope we are using a special kind of singleton. + +- The `inSingletonScope` creates a singleton that will last for the entire life cycle of a type binding. This means that the `inSingletonScope` can be cleared up from memory when we unbind a type binding using `container.unbind`. + +- The `inRequestScope` creates a singleton that will last for the entire life cycle of one call to the `container.get`, `container.getTagged` or `container.getNamed` methods. Each call to one of this methods will resolve a root dependency and all its sub-dependencies. Internally, a dependency graph known as the "resolution plan" is created by InversifyJS. The `inRequestScope` scope will use one single instance for objects that appear multiple times in the resolution plan. This reduces the number of required resolutions and it can be used as a performance optimization in some cases. diff --git a/src/en/features-and-api/5_optional_dependencies.md b/src/en/features-and-api/5_optional_dependencies.md new file mode 100644 index 0000000..0304d25 --- /dev/null +++ b/src/en/features-and-api/5_optional_dependencies.md @@ -0,0 +1,87 @@ +# Optional dependencies + +We can declare an optional dependency using the `@optional()` decorator: + +```ts +@injectable() +class Katana { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken // Optional! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} + +let container = new Container(); + +container.bind('Katana').to(Katana); +container.bind('Ninja').to(Ninja); + +let ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken).to.eql(undefined); + +container.bind('Shuriken').to(Shuriken); + +ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken.name).to.eql('Shuriken'); +``` + +In the example we can see how the first time we resolve `Ninja`, its +property `shuriken` is undefined because no bindings have been declared +for `Shuriken` and the property is annotated with the `@optional()` decorator. + +After declaring a binding for `Shuriken`: + +```ts +container.bind('Shuriken').to(Shuriken); +``` + +All the resolved instances of `Ninja` will contain an instance of `Shuriken`. + +## Default values + +If a dependency is decorated with the `@optional()` decorator, we will be able to to declare +a default value just like you can do in any other TypeScript application: + +```ts +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken = { name: 'DefaultShuriken' } // Default value! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/en/features-and-api/6_value_injection.md b/src/en/features-and-api/6_value_injection.md new file mode 100644 index 0000000..764b696 --- /dev/null +++ b/src/en/features-and-api/6_value_injection.md @@ -0,0 +1,19 @@ +# Injecting a constant or dynamic value + +Binds an abstraction to a constant value: + +```ts +container.bind('Katana').toConstantValue(new Katana()); +``` + +Binds an abstraction to a dynamic value: + +```ts +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return new Katana(); +}); +// a dynamic value can return a promise that will resolve to the value +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return Promise.resolve(new Katana()); +}); +``` diff --git a/src/en/features-and-api/7_constructor_injection.md b/src/en/features-and-api/7_constructor_injection.md new file mode 100644 index 0000000..8f2ef9b --- /dev/null +++ b/src/en/features-and-api/7_constructor_injection.md @@ -0,0 +1,54 @@ +# Injecting a class constructor + +InversifyJS supports constructor injection to allow passing abstractions or instances of concrete classes +during the creation of the injectable object. + +In case of abstractions (interfaces) you need to use the @inject decorator. This is required because +the metadata of the abstractions are not available during runtime : + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Newable') Katana: interfaces.Newable, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = new Katana(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Newable').toConstructor(Katana); +``` + +In case of concrete injections, you can simply define your constructor parameters as usual without using the @inject decorator. + +InversifyJS also supports TypeScript's constructor assignments so you can have private or protected access modifiers in your parameters +and the container will have no trouble injecting the dependencies : + +```ts +@injectable() +class Ninja implements Ninja { + public constructor(private _dagger: Dagger) {} + + public throwDagger() { + this._dagger.throw(); + } +} +``` + +```ts +container.bind(Dagger).toSelf(); +``` diff --git a/src/en/features-and-api/8_factory_injection.md b/src/en/features-and-api/8_factory_injection.md new file mode 100644 index 0000000..da1e16f --- /dev/null +++ b/src/en/features-and-api/8_factory_injection.md @@ -0,0 +1,79 @@ +# Injecting a Factory + +Binds an abstraction to a user defined Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Factory') katanaFactory: () => Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return () => { + return context.container.get('Katana'); + }; +}); +``` + +You can also define a Factory with args: + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return (throwable: boolean) => { + if (throwable) { + return context.container.getTagged('Weapon', 'throwable', true); + } else { + return context.container.getTagged('Weapon', 'throwable', false); + } + }; +}); +``` + +Sometimes you might need to pass arguments to a factory in different moments during the execution: + +```ts +container + .bind('Engine') + .to(PetrolEngine) + .whenTargetNamed('petrol'); +container + .bind('Engine') + .to(DieselEngine) + .whenTargetNamed('diesel'); + +container.bind>('Factory').toFactory((context) => { + return (named: string) => (displacement: number) => { + let engine = context.container.getNamed('Engine', named); + engine.displacement = displacement; + return engine; + }; +}); + +@injectable() +class DieselCarFactory implements CarFactory { + private _dieselFactory: (displacement: number) => Engine; + constructor( + @inject('Factory') factory: (category: string) => (displacement: number) => Engine // Injecting an engine factory + ) { + this._dieselFactory = factory('diesel'); // Creating a diesel engine factory + } + public createEngine(displacement: number): Engine { + return this._dieselFactory(displacement); // Creating a concrete diesel engine + } +} +``` diff --git a/src/en/features-and-api/9_auto_factory.md b/src/en/features-and-api/9_auto_factory.md new file mode 100644 index 0000000..e152a64 --- /dev/null +++ b/src/en/features-and-api/9_auto_factory.md @@ -0,0 +1,32 @@ +# Auto factory + +Binds an abstraction to an auto-generated Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Factory') katanaFactory: interfaces.Factory, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind('Katana').to(Katana); + +container.bind>('Factory').toAutoFactory('Katana'); +``` diff --git a/src/en/features-and-api/README.md b/src/en/features-and-api/README.md new file mode 100644 index 0000000..8bd8303 --- /dev/null +++ b/src/en/features-and-api/README.md @@ -0,0 +1,168 @@ +# Support for classes + +InversifyJS allows your classes to have a direct dependency on other classes. When doing so you will need to use the `@injectable` decorator but you will not be required to use the `@inject` decorator. + +The `@inject` decorator is not required when you use classes. The annotation is not required because the typescript compiler generates the metadata for us. However, this won't happen if you forget one of the following things: + +- Import `reflect-metadata` +- Set `emitDecoratorMetadata` to `true` in `tsconfig.json`. + +```ts +import { Container, injectable, inject } from 'inversify'; + +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrion { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(Katana).to(Katana); +container.bind(Shuriken).to(Shuriken); +``` + +## Self-binding of concrete types + +If the type you’re resolving is a concrete type the registration of a binding can feel a repetitive and verbose: + +```ts +container.bind(Samurai).to(Samurai); +``` + +A better solution is to use the `toSelf` method: + +```ts +container.bind(Samurai).toSelf(); +``` + +## Known Limitation: Classes as identifiers and circular dependencies + +An exception: + +::: danger +Error: Missing required @Inject or @multiinject annotation in: argument 0 in class Dom. +::: + +Will be thrown if we use classes as identifiers in circular dependencies. For example: + +```ts +import 'reflect-metadata'; +import { Container, injectable } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +let container = new Container(); +let { lazyInject } = getDecorators(container); + +@injectable() +class Dom { + public domUi: DomUi; + constructor(domUi: DomUi) { + this.domUi = domUi; + } +} + +@injectable() +class DomUi { + @lazyInject(Dom) public dom: Dom; +} + +@injectable() +class Test { + constructor(dom: Dom) { + console.log(dom); + } +} + +container + .bind(Dom) + .toSelf() + .inSingletonScope(); +container + .bind(DomUi) + .toSelf() + .inSingletonScope(); +const dom = container.resolve(Test); // Error! +``` + +This error may seem a bit misleading because when using classes as service identifiers `@inject` annotations should not be required and if we do add an annotation like `@inject(Dom)` or `@inject(DomUi)` we will still get the same exception. This happens because, at the point in time in which the decorator is invoked, the class has not been declared so the decorator is invoked as `@inject(undefined)`. This trigger InversifyJS to think that the annotation was never added. + +The solution is to use symbols like `Symbol.for("Dom")` as service identifiers instead of the classes like `Dom`: + +```ts +import 'reflect-metadata'; +import { Container, injectable, inject } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +const container = new Container(); +const { lazyInject } = getDecorators(container); + +const TYPE = { + Dom: Symbol.for('Dom'), + DomUi: Symbol.for('DomUi') +}; + +@injectable() +class DomUi { + public dom: Dom; + public name: string; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + this.name = 'DomUi'; + } +} + +@injectable() +class Dom { + public name: string; + @lazyInject(TYPE.DomUi) public domUi: DomUi; + public constructor() { + this.name = 'Dom'; + } +} + +@injectable() +class Test { + public dom: Dom; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + } +} + +container + .bind(TYPE.Dom) + .to(Dom) + .inSingletonScope(); +container + .bind(TYPE.DomUi) + .to(DomUi) + .inSingletonScope(); + +const test = container.resolve(Test); // Works! +``` diff --git a/src/en/getting-started/README.md b/src/en/getting-started/README.md new file mode 100644 index 0000000..0a2a05d --- /dev/null +++ b/src/en/getting-started/README.md @@ -0,0 +1,142 @@ +# Getting Started + +## Installation + +You can get the latest release and the type definitions using npm: + +```sh +npm install inversify@5.1.1 reflect-metadata --save +``` + +Or using yarn: + +```sh +yarn add inversify@5.1.1 reflect-metadata +``` + +The InversifyJS type definitions are included in the inversify npm package. InversifyJS requires the `experimentalDecorators`, `emitDecoratorMetadata`and `lib` compilation options in your `tsconfig.json` file. + +```js +{ + "compilerOptions": { + "target": "es5", + "lib": ["es6"], + "types": ["reflect-metadata"], + "module": "commonjs", + "moduleResolution": "node", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +InversifyJS requires a modern JavaScript engine with support for: + +- [Reflect metadata](https://github.com/rbuckton/ReflectDecorators/blob/master/spec/metadata.md) +- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) (Only required if using [provider injection](../features-and-api/10_provider_injection)) +- [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) (Only required if using [activation handlers](../features-and-api/11_activation_handler)) + +If your environment don't support one of these you will need to import a shim or polyfill. + +**Check out the [Environment support and polyfills](https://github.com/inversify/InversifyJS/blob/master/wiki/environment.md) +page in the wiki to learn more.** + +## Declaring Interfaces + +Our goal is to write code that adheres to the [dependency inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle). This means that we should "depend upon Abstractions and do not depend upon concretions". Let's start by declaring some interfaces (abstractions). + +```ts +interface Warrior { + fight(): string; + sneak(): string; +} + +interface Weapon { + hit(): string; +} + +interface ThrowableWeapon { + throw(): string; +} +``` + +InversifyJS need to use the type as identifiers at runtime. We use symbols as identifiers but you can also use classes and or string literals. + +```ts +let TYPES = { + Warrior: Symbol('Warrior'), + Weapon: Symbol('Weapon'), + ThrowableWeapon: Symbol('ThrowableWeapon') +}; + +export default TYPES; +``` + +::: tip +**Note:** It is recommended to use Symbols but InversifyJS also support the usage of Classes and string literals (please refer to the features section to learn more). +::: + +## Declaring Classes and Dependencies + +Let's continue by declaring some classes (concretions). The classes are implementations of the interfaces that we just declared. All the classes must be annotated with the `@injectable` decorator. + +When a class has a dependency on an interface we also need to use the @inject decorator to define an identifier for the interface that will be available at runtime. In this case we will use the Symbols `Symbol("Weapon")` and `Symbol("ThrowableWeapon")` as runtime identifiers. + +```ts +import { injectable, inject } from 'inversify'; +import 'reflect-metadata'; +import TYPES from './types'; + +@injectable() +class Katana implements Weapon { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements ThrowableWeapon { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrior { + private _katana: Weapon; + private _shuriken: ThrowableWeapon; + + public constructor(@inject(TYPES.Weapon) katana: Weapon, @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} + +export { Ninja, Katana, Shuriken }; +``` + +If you prefer it you can use property injection instead of constructor injection so you don't have to declare the class constructor: + +```ts +@injectable() +class Ninja implements Warrior { + @inject(TYPES.Weapon) private _katana: Weapon; + @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon; + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} +``` diff --git a/src/en/index.md b/src/en/index.md new file mode 100644 index 0000000..1fb5cb1 --- /dev/null +++ b/src/en/index.md @@ -0,0 +1,91 @@ +--- +home: true +title: InversifyJS +heroImage: /logo_transparent.svg +heroText: InversifyJS +tagline: A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript. +actionText: Quick Start → +actionLink: /en/introduction/ +companies: + - link: https://opensource.microsoft.com/ + logo: https://avatars0.githubusercontent.com/u/6154722?s=200&v=4 + + - link: https://code.facebook.com/projects/1021334114569758/nuclide/ + logo: https://avatars2.githubusercontent.com/u/69631?s=200&v=4 + + - link: https://aws.github.io/aws-amplify/ + logo: https://avatars0.githubusercontent.com/u/2232217?s=200&v=4 + + - link: https://www.plainconcepts.com/ + logo: https://avatars0.githubusercontent.com/u/1520648?s=200&v=4 + + - link: https://api.slack.com/ + logo: https://avatars3.githubusercontent.com/u/6962987?s=200&v=4 + + - link: https://www.lonelyplanet.com/ + logo: https://avatars3.githubusercontent.com/u/114767?s=200&v=4 + + - link: https://jincor.com/ + logo: https://avatars0.githubusercontent.com/u/25283328?s=200&v=4 + + - link: https://www.web-computing.de/ + logo: https://avatars1.githubusercontent.com/u/1957282?s=200&v=4 + + - link: https://dcos.io/ + logo: https://avatars1.githubusercontent.com/u/17648048?s=200&v=4 + + - link: https://typefox.io/ + logo: https://avatars0.githubusercontent.com/u/16970371?s=200&v=4 + + - link: https://code4.ro/ + logo: https://avatars0.githubusercontent.com/u/18010308?s=200&v=4 + + - link: http://www.baidu.com/ + logo: https://user-images.githubusercontent.com/10656223/33888109-fae0852e-df43-11e7-97f6-9db543da0bde.png + + - link: https://www.imdada.cn/ + logo: https://avatars2.githubusercontent.com/u/8085382?s=200&v=4 + + - link: https://www.ato.gov.au/ + logo: https://avatars2.githubusercontent.com/u/17041151?s=200&v=4 + + - link: https://www.kaneoh.com/ + logo: https://avatars1.githubusercontent.com/u/14963540?s=200&v=4 + + - link: https://particl.io/ + logo: https://avatars0.githubusercontent.com/u/26021686?s=200&v=4 + + - link: https://slackmap.com/ + logo: https://avatars2.githubusercontent.com/u/24523195?s=200&v=4 + + - link: https://www.go1.com/ + logo: https://avatars3.githubusercontent.com/u/16556899?s=200&v=4 + + - link: http://www.stellwagengroup.com/stellwagen-technology/ + logo: https://avatars3.githubusercontent.com/u/23475730?s=200&v=4 + + - link: https://www.edrlab.org/ + logo: https://avatars1.githubusercontent.com/u/15262567?s=200&v=4 + + - link: https://www.goodgamestudios.com/ + logo: https://avatars1.githubusercontent.com/u/10072104?s=200&v=4 + + - link: https://freshfox.at/ + logo: https://avatars2.githubusercontent.com/u/13613760?s=200&v=4 + + - link: https://schubergphilis.com/ + logo: https://avatars1.githubusercontent.com/u/864482?s=200&v=4 + +features: + - title: Strongly Typed + details: InversifyJS is powered by TypeScript. TypeScript enable JavaScript developers to use highly-productive development tools and practices when developing JavaScript applications. + + - title: Universal + details: InversifyJS compiles to clean, simple JavaScript code which runs on any browser, in Node.js, or in any JavaScript engine that supports ECMAScript 5 (or newer). + + - title: Pluggable + details: Inversifyjs is framework-agnostic and has been designed to in a way that makes possible its integration with popular frameworks and libraries like hapi, express, react or backbone. + +footer: Released under the MIT License +copyright: Copyright © 2015 - present Remo H. Jansen +--- diff --git a/src/en/introduction/README.md b/src/en/introduction/README.md new file mode 100644 index 0000000..32c1f75 --- /dev/null +++ b/src/en/introduction/README.md @@ -0,0 +1,55 @@ +--- +title: Introduction +--- + +# Introduction + +InversifyJS is a lightweight (4KB) inversion of control (IoC) container for TypeScript and JavaScript apps. A IoC container uses a class constructor to identify and inject its dependencies. + +InversifyJS has a friendly API and encourage the usage of the best OOP and IoC practices. + +## Motivation + +JavaScript now supports object oriented (OO) programming with class based inheritance. These features are great but the truth is that they are also dangerous. + +We need a good OO design to protect ourselves from these threats. The problem is that OO design is difficult and that is exactly why we created InversifyJS. + +InversifyJS is a tool that helps JavaScript developers to write code with a good OO design. + +## Philosophy + +InversifyJS has been developed with 4 main goals: + +- Allow JavaScript developers to write code that adheres to the SOLID principles. +- Facilitate and encourage the adherence to the best OOP and IoC practices. +- Add as little runtime overhead as possible. +- Provide a state of the art development experience. + +## Features and API + +InversifyJS is powerful IoC container and supports the following features: + +- [Support for classes](../features-and-api) +- [Support for Symbols](../features-and-api/0_symbols_as_id) +- [Container API](../features-and-api/1_container_api) +- [Declaring container modules](../features-and-api/2_container_modules) +- [Container snapshots](../features-and-api/3_container_snapshots) +- [Controlling the scope of the dependencies](../features-and-api/4_scope) +- [Declaring optional dependencies](../features-and-api/5_optional_dependencies) +- [Injecting a constant or dynamic value](../features-and-api/6_value_injection) +- [Injecting a class constructor](../features-and-api/7_constructor_injection) +- [Injecting a Factory](../features-and-api/8_factory_injection) +- [Auto factory](../features-and-api/9_auto_factory) +- [Injecting a Provider (asynchronous Factory)](../features-and-api/10_provider_injection) +- [Activation handler](../features-and-api/11_activation_handler) +- [Middleware](../features-and-api/12_middleware) +- [Multi-injection](../features-and-api/15_multi_injection) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Create your own tag decorators](../features-and-api/17_custom_tag_decorators) +- [Named bindings](../features-and-api/18_named_bindings) +- [Default target](../features-and-api/19_default_targets) +- [Support for hierarchical DI systems](../features-and-api/20_hierarchical_di) +- [Contextual bindings & @targetName](../features-and-api/21_contextual_bindings) +- [Property injection](../features-and-api/22_property_injection) +- [Circular dependencies](../features-and-api/23_circular_dependencies) +- [Inheritance](../features-and-api/24_inheritance) diff --git a/src/en/why-inversifyjs/README.md b/src/en/why-inversifyjs/README.md new file mode 100644 index 0000000..20bec4d --- /dev/null +++ b/src/en/why-inversifyjs/README.md @@ -0,0 +1,129 @@ +# Why InversifyJS? + +There are many good reasons to use InversifyJS but we would like to highlight some of them: + +## 1. Real decoupling + +InversifyJS offers you real decoupling. Consider the following class: + +```ts +let TYPES = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +export { TYPES }; +``` + +```ts +import { TYPES } from './constants/types'; + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(TYPES.Katana) katana: Katana, @inject(TYPES.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +The `Ninja` class will never point to the `Katana` or `Shuriken` classes. However, +it will point to the interfaces (at design-time) or Symbols (at run-time) which is +admissible because these are abstractions and +[**depending upon abstractions**](https://en.wikipedia.org/wiki/Dependency_inversion_principle) +is what DI is all about. + +The InversifyJS container is the only element in the application aware of the life-cycle and dependencies. +We recommend to do this in a file named `inversify.config.ts` and store the file in the root folder +that contains the application source code: + +```ts +import { TYPES } from './constants/types'; +import { Katana } from './entitites/katana'; +import { Shuriken } from './entitites/shuriken'; +import { Ninja } from './entitites/ninja'; + +container.bind(TYPES.KATANA).to(Katana); +container.bind(TYPES.SHURIKEN).to(Shuriken); +container.bind(TYPES.NINJA).to(Ninja); +``` + +This means that all the coupling in your application takes place in one unique place: the `inversify.config.ts` file. +This is really important and we are going to prove it with an example. +Let's imagine that we are changing the difficulty in a game. +We just need to go to the `inversify.config.ts` and change the Katana binding: + +```ts +import { Katana } from './entitites/SharpKatana'; + +if (difficulty === 'hard') { + container.bind(TYPES.KATANA).to(SharpKatana); +} else { + container.bind(TYPES.KATANA).to(Katana); +} +``` + +You don't need to change the Ninja file! + +The price to pay is the usage of Symbols or string literals but this price can be mitigated if you declare all your +string literals in a file which contains constants +([like actions in Redux](https://github.com/reactjs/redux/blob/master/examples/todomvc/src/constants/ActionTypes.js)). +The good news is that in the future the symbols or string literals +[could end up being generated by the TS compiler](https://github.com/Microsoft/TypeScript/issues/2577), but +that is in the hands of the TC39 committee for the moment. + +## 2. Solves competitors issues + +Some "old" JavaScript IoC container like the angular 1.x `$injector` have some problems: + +![](http://i.imgur.com/Y2lRw4N.png) + +[Source](https://angular.io/docs/ts/latest/guide/dependency-injection.html) + +InversifyJS solves these problems: + +- There is support for transient and singleton scope. +- There are no namespace collisions thanks to tagged, named and contextual bindings. +- It is a stand alone library. + +## 3. All the features that you may need + +As far as I know it is the only IoC container for JavaScript that features complex dependency +resolution (e.g. contextual bindings), multiple scopes (transient, singleton) and many other features. +On top of that there is room for growth with features like interception or web worker scope. +We also have plans for the development of dev-tools like browser extensions and middleware (logging, caching...). + +## 4. Object composition is a pain + +You may think that you don't need an IoC container. + +![](https://raw.githubusercontent.com/inversify/inversify.github.io/master/img/so.png) + +If the [preceding argument](http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code) is not enough you may want to read the following: + +- [The current state of dependency inversion in JavaScript](http://blog.wolksoftware.com/the-current-state-of-dependency-inversion-in-javascript) +- [About object-oriented design and the “class” & “extends” keywords in TypeScript / ES6](http://blog.wolksoftware.com/about-classes-inheritance-and-object-oriented-design-in-typescript-and-es6) + +## 5. Type safety + +The library has been developed using TypeScript so type safety comes out of the box if you work +with TypeScript but it is nice to mention that if you try to inject a Katana into a class that +expects an implementation of `Shuriken` you will get a compilation error. + +## 6. Great development experience + +We are working hard to provide you with a great IoC container for your JavaScript apps but also a great development experience. +We have spend a lot of time trying to make the InversifyJS as user friendly as possible and are working on development tools for chrome and we have already developed a logger middleware to help you to debug in Node.js. + +![](http://inversify.io/img/devtools1.png) diff --git a/src/es/features-and-api/0_symbols_as_id.md b/src/es/features-and-api/0_symbols_as_id.md new file mode 100644 index 0000000..66b50eb --- /dev/null +++ b/src/es/features-and-api/0_symbols_as_id.md @@ -0,0 +1,54 @@ +# Support for Symbols + +In very large applications using strings as the identifiers of the types to be injected by the InversifyJS can lead to naming collisions. InversifyJS supports and recommends the usage of [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) instead of string literals. + +::: tip +A symbol is a unique and immutable data type and may be used as an identifier for object properties. The symbol object is an implicit object wrapper for the symbol primitive data type. +::: + +```ts +import { Container, injectable, inject } from 'inversify'; + +let Symbols = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +@injectable() +class Katana implements Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(Symbols.Katana) katana: Katana, @inject(Symbols.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Symbols.Ninja).to(Ninja); +container.bind(Symbols.Katana).to(Katana); +container.bind(Symbols.Shuriken).to(Shuriken); +``` diff --git a/src/es/features-and-api/10_provider_injection.md b/src/es/features-and-api/10_provider_injection.md new file mode 100644 index 0000000..0e3c818 --- /dev/null +++ b/src/es/features-and-api/10_provider_injection.md @@ -0,0 +1,307 @@ +# Injecting a Provider (asynchronous Factory) + +Binds an abstraction to a Provider. A provider is an asynchronous factory, this +is useful when dealing with asynchronous I/O operations. + +```ts +type KatanaProvider = () => Promise; + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public shuriken: Shuriken; + public katanaProvider: KatanaProvider; + + public constructor( + @inject('KatanaProvider') katanaProvider: KatanaProvider, + @inject('Shuriken') shuriken: Shuriken + ) { + this.katanaProvider = katanaProvider; + this.katana = null; + this.shuriken = shuriken; + } + + public fight() { + return this.katana.hit(); + } + public sneak() { + return this.shuriken.throw(); + } +} +``` + +```ts +container.bind('KatanaProvider').toProvider((context) => { + return () => { + return new Promise((resolve) => { + let katana = context.container.get('Katana'); + resolve(katana); + }); + }; +}); + +var ninja = container.get('Ninja'); + +ninja + .katanaProvider() + .then((katana) => { + ninja.katana = katana; + }) + .catch((e) => { + console.log(e); + }); +``` + +## Provider custom arguments + +The `toProvider` binding expects a `ProviderCreator` as its only argument: + +```ts +interface ProviderCreator extends Function { + (context: Context): Provider; +} +``` + +The signature of a provider look as follows: + +```ts +interface Provider extends Function { + (...args: any[]): ((...args: any[]) => Promise) | Promise; +} +``` + +These type signatures allow as to pass custom arguments to a provider: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string, damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string, damage: number) => { + // Custom args! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; +}); + +let katanaProvider = container.get('SwordProvider'); + +katanaProvider('gold', 100).then((powerfulGoldKatana) => { + // Apply all custom args + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +katanaProvider('gold', 10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider partial application + +We can also pass the arguments using partial application: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string) => (damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string) => { + // Custom arg 1! + return (damage: number) => { + // Custom arg 2! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; + }; +}); + +let katanaProvider = container.get('SwordProvider'); +let goldKatanaProvider = katanaProvider('gold'); // Apply the first custom arg! + +goldKatanaProvider(100).then((powerfulGoldKatana) => { + // Apply the second custom args! + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +goldKatanaProvider(10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider as a singleton + +A Provider is always injected as a singleton but you can control if the value returned by the +Provider is uses singleton or transient scope: + +```ts +let container = new Container(); + +interface Warrior { + level: number; +} + +@injectable() +class Ninja implements Warrior { + public level: number; + public constructor() { + this.level = 0; + } +} + +type WarriorProvider = (level: number) => Promise; + +container + .bind('Warrior') + .to(Ninja) + .inSingletonScope(); // Value is singleton! + +container.bind('WarriorProvider').toProvider((context) => { + return (increaseLevel: number) => { + return new Promise((resolve) => { + setTimeout(() => { + let warrior = context.container.get('Warrior'); // Get singleton! + warrior.level += increaseLevel; + resolve(warrior); + }, 100); + }); + }; +}); + +let warriorProvider = container.get('WarriorProvider'); + +warriorProvider(10).then((warrior) => { + expect(warrior.level).to.eql(10); +}); + +warriorProvider(10).then((warrior2) => { + expect(warrior.level).to.eql(20); +}); +``` + +## Provider defaults + +The following function can be used as a helper to provide a default value when a provider is rejected: + +```ts +function valueOrDefault(provider: () => Promise, defaultValue: T) { + return new Promise((resolve, reject) => { + provider() + .then((value) => { + resolve(value); + }) + .catch(() => { + resolve(defaultValue); + }); + }); +} +``` + +The following example showcases how to apply the `valueOrDefault` helper: + +```ts +@injectable() +class Ninja { + public level: number; + public rank: string; + public constructor() { + this.level = 0; + this.rank = 'Ninja'; + } + public train(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + this.level += 10; + resolve(this.level); + }, 100); + }); + } +} + +@injectable() +class NinjaMaster { + public rank: string; + public constructor() { + this.rank = 'NinjaMaster'; + } +} + +type NinjaMasterProvider = () => Promise; + +let container = new Container(); + +container + .bind('Ninja') + .to(Ninja) + .inSingletonScope(); +container.bind('NinjaMasterProvider').toProvider((context) => { + return () => { + return new Promise((resolve, reject) => { + let ninja = context.container.get('Ninja'); + ninja.train().then((level) => { + if (level >= 20) { + resolve(new NinjaMaster()); + } else { + reject('Not enough training'); + } + }); + }); + }; +}); + +let ninjaMasterProvider = container.get('NinjaMasterProvider'); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // Using default here because the provider was rejected (the ninja has a level below 20) + expect(ninjaMaster.rank).to.eql('DefaultNinjaMaster'); +}); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // A NinjaMaster was provided because the the ninja has a level above 20 + expect(ninjaMaster.rank).to.eql('NinjaMaster'); + done(); +}); +``` diff --git a/src/es/features-and-api/11_activation_handler.md b/src/es/features-and-api/11_activation_handler.md new file mode 100644 index 0000000..6be77d2 --- /dev/null +++ b/src/es/features-and-api/11_activation_handler.md @@ -0,0 +1,67 @@ +# Activation handler + +It is possible to add an activation handler for a type. The activation handler is invoked after a dependency has been resolved and before it is added to a cache (if singleton or request singleton - [see scope](../features-and-api/4_scope)) and injected. The activation handler will not be invoked if the dependency is taken from a cache. The activation handler can be synchronous or asynchronous. + +Activation handlers are useful to keep our dependencies agnostic of the implementation of crosscutting concerns like caching or logging. + +The following example uses a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to intercept one of the methods (`use`) of a dependency (`Katana`). + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + public use() { + console.log('Used Katana!'); + } +} + +interface Ninja { + katana: Katana; +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(@inject('Katana') katana: Katana) { + this.katana = katana; + } +} +``` + +```ts +container.bind('Ninja').to(Ninja); + +container + .bind('Katana') + .to(Katana) + .onActivation((context, katana) => { + let handler = { + apply: function(target, thisArgument, argumentsList) { + console.log(`Starting: ${new Date().getTime()}`); + let result = target.apply(thisArgument, argumentsList); + console.log(`Finished: ${new Date().getTime()}`); + return result; + } + }; + katana.use = new Proxy(katana.use, handler); + return katana; + }); +``` + +```ts +let ninja = container.get(); +ninja.katana.use(); +> Starting: 1457895135761 +> Used Katana! +> Finished: 1457895135762 +``` + +There are multiple ways to provide an activation handler + +- Adding the handler to the container +- Adding the handler to the binding + +When multiple activation handlers are binded to a service identifier, the binding handler is called before any others. Then the container handlers are called, starting at the root container and descending the descendant containers stopping at the container with the binding. diff --git a/src/es/features-and-api/12_deactivation_handler.md b/src/es/features-and-api/12_deactivation_handler.md new file mode 100644 index 0000000..9f7bd92 --- /dev/null +++ b/src/es/features-and-api/12_deactivation_handler.md @@ -0,0 +1,90 @@ +# Deactivation handler + +It is possible to add a deactivation handler for a type binded in singleton scope. The handler can be synchronous or asynchronous. The deactivation handler is invoked before the type is unbinded from the container: + +```ts +@injectable() +class Destroyable {} + +const container = new Container(); +container + .bind('Destroyable') + .toDynamicValue(() => Promise.resolve(new Destroyable())) + .inSingletonScope() + .onDeactivation((destroyable: Destroyable) => { + console.log('Destroyable service is about to be unbinded'); + }); + +await container.get('Destroyable'); + +await container.unbind('Destroyable'); +``` + +It's possible to add a deactivation handler in multiple ways + +- Adding the handler to the container. +- Adding the handler to a binding. +- Adding the handler to the class through the [preDestroy decorator](../features-and-api/26_pre_destroy). + +Handlers added to the container are the first ones to be resolved. Any handler added to a child container is called before the ones added to their parent. Relevant bindings from the container are called next and finally the `preDestroy` method is called. In the example above, relevant bindings are those bindings bound to the unbinded "Destroyable" service identifer. + +The example below demonstrates call order. + +```ts +let roll = 1; +let binding = null; +let klass = null; +let parent = null; +let child = null; + +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + return new Promise((presolve) => { + klass = roll; + roll += 1; + presolve({}); + }); + } +} + +const container = new Container(); +container.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + parent = roll; + roll += 1; + presolve(); + }); +}); + +const childContainer = container.createChild(); +childContainer + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope() + .onDeactivation( + () => + new Promise((presolve) => { + binding = roll; + roll += 1; + presolve(); + }) + ); +childContainer.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + child = roll; + roll += 1; + presolve(); + }); +}); + +childContainer.get('Destroyable'); +await childContainer.unbindAsync('Destroyable'); + +expect(roll).eql(5); +expect(child).eql(1); +expect(parent).eql(2); +expect(binding).eql(3); +expect(klass).eql(4); +``` diff --git a/src/es/features-and-api/13_post_construct.md b/src/es/features-and-api/13_post_construct.md new file mode 100644 index 0000000..ee71af7 --- /dev/null +++ b/src/es/features-and-api/13_post_construct.md @@ -0,0 +1,66 @@ +# Post Construct Decorator + +It is possible to add a **@postConstruct** decorator for a class method. This decorator +will run after an object is instantiated and before any activation handlers. This +is useful in situations when the constructor has been called but the component has not +yet initialized or in cases you want to perform an initialization logic after the constructor call. + +Its some other cases it gives you a contract that guarantees +that this method will be invoked only once in the lifetime +of the object when used in singleton scope. See the following examples for usage. + +The method can be synchronous or asynchronous. + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + constructor() { + console.log('Katana is born'); + } + + public use() { + return 'Used Katana!'; + } + + @postConstruct() + public testMethod() { + console.log('Used Katana!'); + } +} +``` + +```ts +container.bind('Katana').to(Katana); +``` + +```ts +let catana = container.get(); +> Katana is born +> Used Katana! +``` + +Note that you cannot use more than one @postConstruct decorators +on the same class. It will throw an error. + +```ts +class Katana { + @postConstruct() + public testMethod1() {/* ... */} + + @postConstruct() + public testMethod2() {/* ... */} + } + +Katana.toString(); +> Error("Cannot apply @postConstruct decorator multiple times in the same class") +``` + +Usage in basic Javascript + +```js +inversify.decorate(inversify.postConstruct(), Katana.prototype, 'testMethod'); +``` diff --git a/src/es/features-and-api/14_middleware.md b/src/es/features-and-api/14_middleware.md new file mode 100644 index 0000000..603f664 --- /dev/null +++ b/src/es/features-and-api/14_middleware.md @@ -0,0 +1,179 @@ +# Middleware + +InversifyJS performs 3 mandatory operations before resolving a dependency: + +- Annotation +- Planning +- Resolution + +In some cases there will be some additional operations: + +- Activation +- Middleware + +If we have configured some Middleware it will be executed at some point before or after the planning, +resolution and activation phases. + +Middleware can be used to implement powerful development tools. This kind of tools will help developers +to identify problems during the development process. + +## Basic middleware + +```ts +import { interfaces, Container } from 'inversify'; + +function logger(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let start = new Date().getTime(); + let result = planAndResolve(args); + let end = new Date().getTime(); + console.log(`wooooo ${end - start}`); + return result; + }; +} + +let container = new Container(); +container.applyMiddleware(logger); +``` + +Now that we have declared a middleware we can create a new Container and use its applyMiddleware +method to apply it: + +```ts +interface Ninja {} + +@injectable() +class Ninja implements Ninja {} + +let container = new Container(); +container.bind('Ninja').to(Ninja); + +container.applyMiddleware(logger); +``` + +The logger middleware will log in console the execution time: + +```ts +let ninja = container.get("Ninja"); + +> 21 +``` + +## Multiple middleware functions + +When multiple middleware functions are applied: + +```ts +container.applyMiddleware(middleware1, middleware2); +``` + +The middleware will be invoked from right to left. +This means that `middleware2` is invoked before `middleware1`. + +## Context interceptor + +In some cases you may want to intercept the resolution plan. + +The default `contextInterceptor` is passed to the middleware as an property of `args`. + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + // args.nextContextInterceptor + // ... + }; +} +``` + +You can extend the default `contextInterceptor` using a function: + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let nextContextInterceptor = args.contextInterceptor; + args.contextInterceptor = (context: interfaces.Context) => { + console.log(context); + return nextContextInterceptor(context); + }; + return planAndResolve(args); + }; +} +``` + +## Custom metadata reader + +::: warning +Please note that it is not recommended to create your own custom +metadata reader. We have included this feature to allow library / framework creators +to have a higher level of customization but the average user should not use a custom +metadata reader. In general, a custom metadata reader should only be used when +developing a framework in order to provide users with an annotation APIs +less explicit than the default annotation API. + +If you are developing a framework or library and you create a custom metadata reader, +Please remember to provide your framework with support for an alternative for all the +decorators in the default API: ` @injectable, ``@inject `, `@multiInject`, `@tagged`, +`@named`, `@optional`, `@targetName` & `@unmanaged`. +::: + +Middleware allows you to intercept a plan and resolve it but you are not allowed to change the way the annotation phase behaves. + +There is a second extension point that allows you to decide what kind of annotation +system you would like to use. The default annotation system is powered by decorators and +reflect-metadata: + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Katana') katana: Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +You can use a custom metadata reader to implement a custom annotation system. + +For example, you could implement an annotation system based on static properties: + +```ts +class Ninja implements Ninja { + public static constructorInjections = ['Katana', 'Shuriken']; + + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +A custom metadata reader must implement the `interfaces.MetadataReader` interface. + +A full example [can be found in our unit tests](https://github.com/inversify/InversifyJS/blob/master/test/features/metadata_reader.test.ts). + +Once you have a custom metadata reader you will be ready to apply it: + +```ts +let container = new Container(); +container.applyCustomMetadataReader(new StaticPropsMetadataReader()); +``` diff --git a/src/es/features-and-api/15_multi_injection.md b/src/es/features-and-api/15_multi_injection.md new file mode 100644 index 0000000..2d0798a --- /dev/null +++ b/src/es/features-and-api/15_multi_injection.md @@ -0,0 +1,94 @@ +# Multi-injection + +We can use multi-injection When two or more concretions have been bound to the an abstraction. +Notice how an array of `Weapon` is injected into the `Ninja` class via its constructor thanks to the usage of the `@multiInject` decorator: + +```ts +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name = 'Katana'; +} + +@injectable() +class Shuriken implements Weapon { + public name = 'Shuriken'; +} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@multiInject('Weapon') weapons: Weapon[]) { + this.katana = weapons[0]; + this.shuriken = weapons[1]; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon`: + +```ts +container.bind('Ninja').to(Ninja); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); +``` + +## About the spread `...` operator + +In early releases of InversifyJS the spread operator used to fail without throwing any errors. +That was not acceptable and we implemented a fix that allows you to inject arrays using the +spread operator. However it is not recommended because it turns out to be a bit useless. + +You can inject using `@multiInject` and `...` as follows: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) ...args: Bar[][]) { + // args will always contain one unique item the value of that item is a Bar[] + this.bar = args[0]; + } +} +``` + +The main problem is that this requires the type of `args` to be `Bar[][]` +because multiInject will wrap the injections using an array and the spread +operator will do the same. As a result the injection is wrapped by an array +two times. + +We tried to solve this problem but the only way was to generate some additional +metadata using a `@spread()` decorator. + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) @spread() ...args: Bar[]) { + this.bar = args[0]; + } +} +``` + +We discarded this idea because it is better to use decorators when there is not +other way to achieve something. In this case there is a much simpler way to +achieve the desired result. We just need to **use `@multiInject` and avoid using `...`**: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) args: Bar[]) { + this.bar = args; + } +} +``` diff --git a/src/es/features-and-api/16_tagged_bindings.md b/src/es/features-and-api/16_tagged_bindings.md new file mode 100644 index 0000000..bf39534 --- /dev/null +++ b/src/es/features-and-api/16_tagged_bindings.md @@ -0,0 +1,48 @@ +# Tagged bindings + +We can use tagged bindings to fix `AMBIGUOUS_MATCH` errors when two or more +concretions have been bound to an abstraction. Notice how the constructor +arguments of the `Ninja` class have been annotated using the `@tagged` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @tagged('canThrow', false) katana: Weapon, + @inject('Weapon') @tagged('canThrow', true) shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetTagged` +constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); +container + .bind(weaponId) + .to(Katana) + .whenTargetTagged('canThrow', false); +container + .bind(weaponId) + .to(Shuriken) + .whenTargetTagged('canThrow', true); +``` diff --git a/src/es/features-and-api/17_custom_tag_decorators.md b/src/es/features-and-api/17_custom_tag_decorators.md new file mode 100644 index 0000000..60e4af4 --- /dev/null +++ b/src/es/features-and-api/17_custom_tag_decorators.md @@ -0,0 +1,18 @@ +# Create your own tag decorators + +Creating your own decorators is really simple: + +```ts +let throwable = tagged('canThrow', true); +let notThrowable = tagged('canThrow', false); + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@inject('Weapon') @notThrowable katana: Weapon, @inject('Weapon') @throwable shuriken: Weapon) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/es/features-and-api/18_named_bindings.md b/src/es/features-and-api/18_named_bindings.md new file mode 100644 index 0000000..f64595d --- /dev/null +++ b/src/es/features-and-api/18_named_bindings.md @@ -0,0 +1,48 @@ +# Named bindings + +We can use named bindings to fix `AMBIGUOUS_MATCH` errors when two or more concretions have +been bound to the an abstraction. Notice how the constructor arguments of the `Ninja` class +have been annotated using the `@named` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @named('strong') katana: Weapon, + @inject('Weapon') @named('weak') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetNamed` constraint is +added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind('Ninja').to(Ninja); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` diff --git a/src/es/features-and-api/19_default_targets.md b/src/es/features-and-api/19_default_targets.md new file mode 100644 index 0000000..48b43b1 --- /dev/null +++ b/src/es/features-and-api/19_default_targets.md @@ -0,0 +1,104 @@ +# whenTargetIsDefault + +When multiple bindings are available for a given service identifier, we can use +one of the following features to resolve the potential `AMBIGUOUS_MATCH` exception: + +- [Named bindings](../features-and-api/18_named_bindings) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Contextual bindings](../features-and-api/21_contextual_bindings) +- Default targets + +In this section we will explain how to use default targets. + +We can resolve an `AMBIGUOUS_MATCH` exception using a named constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` + +Or a tagged constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('strong', true); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('strong', false); +``` + +The problem with this solution is that we will have to annotate using +the `@named("strong")`/`@named("weak")` or `@tagged("strong", true)`/`@tagged("strong", false)` +every single injection. + +A better solution is to use a default target: + +```ts +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); +``` + +We can use the `whenTargetIsDefault` to indicate which binding should be used as default +to resolve an `AMBIGUOUS_MATCH` exception when no `@named` or `@tagged` annotations +are available. + +```ts +let TYPES = { + Weapon: 'Weapon' +}; + +let TAG = { + throwable: 'throwable' +}; + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken implements Weapon { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +let container = new Container(); +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); + +let defaultWeapon = container.get(TYPES.Weapon); +let throwableWeapon = container.getNamed(TYPES.Weapon, TAG.throwable); + +expect(defaultWeapon.name).eql('Katana'); +expect(throwableWeapon.name).eql('Shuriken'); +``` diff --git a/src/es/features-and-api/1_container_api.md b/src/es/features-and-api/1_container_api.md new file mode 100644 index 0000000..281b540 --- /dev/null +++ b/src/es/features-and-api/1_container_api.md @@ -0,0 +1,811 @@ +# The Container API + +The InversifyJS container is where dependencies are first configured through bind and, possibly later, reconfigured and removed. The container can be worked on directly in this regard or container modules can be utilized. +You can query the configuration and resolve configured dependencies with resolved and the 'get' methods. +You can react to resolutions with container activation handlers and unbinding with container deactivation handlers. +You can create container hierarchies where container ascendants can supply the dependencies for descendants. +For testing, state can be saved as a snapshot on a stack and later restored. +For advanced control you can apply middleware to intercept the resolution request and the resolved dependency. +You can even provide your own annotation solution. + +## Container Options + +Container options can be passed to the Container constructor and defaults will be provided if you do not or if you do but omit an option. +Options can be changed after construction and will be shared by child containers created from the Container if you do not provide options for them. + +### defaultScope + +The default scope is `transient` when binding to/toSelf/toDynamicValue/toService. +The other types of bindings are `singleton`. + +You can use container options to change the default scope for the bindings that default to `transient` at application level: + +```ts +let container = new Container({ defaultScope: 'Singleton' }); +``` + +For all types of bindings you can change the scope when declaring: + +```ts +container + .bind(TYPES.Warrior) + .to(Ninja) + .inSingletonScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inTransientScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inRequestScope(); +``` + +### autoBindInjectable + +You can use this to activate automatic binding for `@injectable()` decorated classes: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.isBound(Ninja); // returns false +container.get(Ninja); // returns a Ninja +container.isBound(Ninja); // returns true +``` + +Manually defined bindings will take precedence: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.bind(Ninja).to(Samurai); +container.get(Ninja); // returns a Samurai +``` + +### skipBaseClassChecks + +You can use this to skip checking base classes for the @injectable property, which is +especially useful if any of your @injectable classes extend classes that you don't control +(third party classes). By default, this value is `false`. + +```ts +let container = new Container({ skipBaseClassChecks: true }); +``` + +### merge + +```ts +container.merge(a: interfaces.Container, b: interfaces.Container, ...containers: interfaces.Container[]): interfaces.Container +``` + +Creates a new Container containing the bindings ( cloned bindings ) of two or more containers: + +```ts +@injectable() +class Ninja { + public name = 'Ninja'; +} + +@injectable() +class Shuriken { + public name = 'Shuriken'; +} + +let CHINA_EXPANSION_TYPES = { + Ninja: 'Ninja', + Shuriken: 'Shuriken' +}; + +let chinaExpansionContainer = new Container(); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Ninja).to(Ninja); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Shuriken).to(Shuriken); + +@injectable() +class Samurai { + public name = 'Samurai'; +} + +@injectable() +class Katana { + public name = 'Katana'; +} + +let JAPAN_EXPANSION_TYPES = { + Katana: 'Katana', + Samurai: 'Samurai' +}; + +let japanExpansionContainer = new Container(); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Samurai).to(Samurai); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Katana).to(Katana); + +let gameContainer = Container.merge(chinaExpansionContainer, japanExpansionContainer); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Ninja).name).to.eql('Ninja'); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Shuriken).name).to.eql('Shuriken'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Samurai).name).to.eql('Samurai'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Katana).name).to.eql('Katana'); +``` + +### applyCustomMetadataReader + +```ts +container.applyCustomMetadataReader(metadataReader: interfaces.MetadataReader): void +``` + +An advanced feature.... See [middleware](../features-and-api/14_middleware). + +### applyMiddleware + +```ts +container.applyMiddleware(...middleware: interfaces.Middleware[]): void +``` + +An advanced feature that can be used for cross cutting concerns. See [middleware](../features-and-api/14_middleware). + +### bind + +```ts +container.bind\(serviceIdentifier: interfaces.ServiceIdentifier\): interfaces.BindingToSyntax\ +``` + +### createChild + +```ts +container.createChild(containerOptions?: interfaces.ContainerOptions): Container; +``` + +Create a [container hierarchy ](../features-and-api/20_hierarchical_di). If you do not provide options the child receives the options of the parent. + +### get + +```ts +container.get\(serviceIdentifier: interfaces.ServiceIdentifier\): T +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); + +let katana = container.get('Weapon'); +``` + +### getAsync + +```ts +container.getAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +async function buildLevel1(): Level1 { + return new Level1(); +} + +let container = new Container(); +container.bind('Level1').toDynamicValue(() => buildLevel1()); + +let level1 = await container.getAsync('Level1'); // Returns Promise +``` + +### getNamed + +```ts +container.getNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('chinese'); + +let katana = container.getNamed('Weapon', 'japanese'); +let shuriken = container.getNamed('Weapon', 'chinese'); +``` + +### getNamedAsync + +```ts +container.getNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetNamed('chinese'); + +let katana = await container.getNamedAsync('Weapon', 'japanese'); +let shuriken = await container.getNamedAsync('Weapon', 'chinese'); +``` + +### getTagged + +```ts +container.getTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('faction', 'ninja'); + +let katana = container.getTagged('Weapon', 'faction', 'samurai'); +let shuriken = container.getTagged('Weapon', 'faction', 'ninja'); +``` + +### getTaggedAsync + +```ts +container.getTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetTagged('faction', 'ninja'); + +let katana = await container.getTaggedAsync('Weapon', 'faction', 'samurai'); +let shuriken = await container.getTaggedAsync('Weapon', 'faction', 'ninja'); +``` + +### getAll + +```ts +container.getAll\(serviceIdentifier: interfaces.ServiceIdentifier\): T[] +``` + +Get all available bindings for a given identifier. All the bindings must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); + +let weapons = container.getAll('Weapon'); // returns Weapon[] +``` + +### getAllAsync + +```ts +container.getAllAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Get all available bindings for a given identifier: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').toDynamicValue(async () => new Shuriken()); + +let weapons = await container.getAllAsync('Weapon'); // returns Promise +``` + +### getAllNamed + +```ts +container.getAllNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetNamed('es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetNamed('es'); + +let fr = container.getAllNamed('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllNamed('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllNamedAsync + +```ts +container.getAllNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetNamed('es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetNamed('es'); + +let fr = await container.getAllNamedAsync('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllNamedAsync('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTagged + +```ts +container.getAllTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetTagged('lang', 'es'); + +let fr = container.getAllTagged('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllTagged('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTaggedAsync + +```ts +container.getAllTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetTagged('lang', 'es'); + +let fr = await container.getAllTaggedAsync('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllTaggedAsync('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### isBound + +```ts +container.isBound(serviceIdentifier: interfaces.ServiceIdentifier\): boolean +``` + +You can use the `isBound` method to check if there are registered bindings for a given service identifier. + +```ts +interface Warrior {} +let warriorId = 'Warrior'; +let warriorSymbol = Symbol.for('Warrior'); + +@injectable() +class Ninja implements Warrior {} + +interface Katana {} +let katanaId = 'Katana'; +let katanaSymbol = Symbol.for('Katana'); + +@injectable() +class Katana implements Katana {} + +let container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(warriorId).to(Ninja); +container.bind(warriorSymbol).to(Ninja); + +expect(container.isBound(Ninja)).to.eql(true); +expect(container.isBound(warriorId)).to.eql(true); +expect(container.isBound(warriorSymbol)).to.eql(true); +expect(container.isBound(Katana)).to.eql(false); +expect(container.isBound(katanaId)).to.eql(false); +expect(container.isBound(katanaSymbol)).to.eql(false); +``` + +### isBoundNamed + +```ts +container.isBoundNamed(serviceIdentifier: interfaces.ServiceIdentifier\, named: string): boolean +``` + +You can use the `isBoundNamed` method to check if there are registered bindings for a given service identifier with a given named constraint. + +```ts +const zero = 'Zero'; +const invalidDivisor = 'InvalidDivisor'; +const validDivisor = 'ValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetNamed(invalidDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetNamed(validDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(true); +``` + +### isBoundTagged + +```ts +container.isBoundTagged(serviceIdentifier: interfaces.ServiceIdentifier\, key: string, value: any): boolean +``` + +You can use the `isBoundTagged` method to check if there are registered bindings for a given service identifier with a given tagged constraint. + +```ts +const zero = 'Zero'; +const isValidDivisor = 'IsValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetTagged(isValidDivisor, false); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetTagged(isValidDivisor, true); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(true); +``` + +### load + +```ts +container.load(...modules: interfaces.ContainerModule[]): void +``` + +Calls the registration method of each module. See [container modules](../features-and-api/2_container_modules) + +### loadAsync + +```ts +container.loadAsync(...modules: interfaces.AsyncContainerModule[]): Promise\ +``` + +As per load but for asynchronous registration. + +### rebind + +```ts +container.rebind\(serviceIdentifier: interfaces.ServiceIdentifier\): : interfaces.BindingToSyntax\ +``` + +You can use the `rebind` method to replace all the existing bindings for a given `serviceIdentifier`. +The function returns an instance of `BindingToSyntax` which allows to create the replacement binding. + +```ts +let TYPES = { + someType: 'someType' +}; + +let container = new Container(); +container.bind(TYPES.someType).toConstantValue(1); +container.bind(TYPES.someType).toConstantValue(2); + +let values1 = container.getAll(TYPES.someType); +expect(values1[0]).to.eq(1); +expect(values1[1]).to.eq(2); + +container.rebind(TYPES.someType).toConstantValue(3); +let values2 = container.getAll(TYPES.someType); +expect(values2[0]).to.eq(3); +expect(values2[1]).to.eq(undefined); +``` + +### rebindAsync + +```ts +container.rebindAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\> +``` + +This is an asynchronous version of rebind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### resolve + +```ts +container.resolve\(constructor: interfaces.Newable\): T +``` + +Resolve is like `container.get(serviceIdentifier: ServiceIdentifier)` but it allows users to create an instance even if no bindings have been declared: + +```ts +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(katana: Katana) { + this.katana = katana; + } + public fight() { + return this.katana.hit(); + } +} + +const container = new Container(); +container.bind(Katana).toSelf(); + +const tryGet = () => container.get(Ninja); +expect(tryGet).to.throw('No matching bindings found for serviceIdentifier: Ninja'); + +const ninja = container.resolve(Ninja); +expect(ninja.fight()).to.eql('cut!'); +``` + +Please note that it only allows to skip declaring a binding for the root element in the dependency graph (composition root). All the sub-dependencies (e.g. `Katana` in the preceding example) will require a binding to be declared. + +### onActivation + +```ts +container.onActivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onActivation: interfaces.BindingActivation\): void +``` + +Adds an activation handler for all dependencies registered with the specified identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onActivation('Weapon', (context: interfaces.Context, katana: Katana): Katana | Promise => { + console.log('katana instance activation!'); + return katana; +}); + +let katana = container.get('Weapon'); +``` + +### onDeactivation + +```ts +container.onDeactivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onDeactivation: interfaces.BindingDeactivation\): void +``` + +Adds a deactivation handler for the dependencie's identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onDeactivation('Weapon', (katana: Katana): void | Promise => { + console.log('katana instance deactivation!'); +}); + +container.unbind('Weapon'); +``` + +### restore + +```ts +container.restore(): void; +``` + +Restore container state to last snapshot. + +### snapshot + +```ts +container.snapshot(): void +``` + +Save the state of the container to be later restored with the restore method. + +### unbind + +```ts +container.unbind(serviceIdentifier: interfaces.ServiceIdentifier\): void +``` + +Remove all bindings binded in this container to the service identifer. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAsync + +```ts +container.unbindAsync(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +This is the asynchronous version of unbind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unbindAll + +```ts +container.unbindAll(): void +``` + +Remove all bindings binded in this container. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAllAsync + +```ts +container.unbindAllAsync(): Promise\ +``` + +This is the asynchronous version of unbindAll. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unload + +```ts +container.unload(...modules: interfaces.ContainerModuleBase[]): void +``` + +Removes bindings and handlers added by the modules. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). +See [container modules](../features-and-api/2_container_modules) + +### unloadAsync + +```ts +container.unloadAsync(...modules: interfaces.ContainerModuleBase[]): Promise\ +``` + +Asynchronous version of unload. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### parent + +```ts +container.parent: Container | null; +``` + +Access the container hierarchy. + +### id + +```ts +container.id: number +``` + +An identifier auto generated to be unique. diff --git a/src/es/features-and-api/20_hierarchical_di.md b/src/es/features-and-api/20_hierarchical_di.md new file mode 100644 index 0000000..84a1bcc --- /dev/null +++ b/src/es/features-and-api/20_hierarchical_di.md @@ -0,0 +1,30 @@ +# Support for hierarchical DI systems + +Some applications use a hierarchical dependency injection (DI) system. +For example, Angular 2.0 applications use its own +[hierarchical DI system](https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html). + +In a hierarchical DI system, a container can have a parent container and multiple containers +can be used in one application. The containers form a hierarchical structure. + +When a container at the bottom of the hierarchical structure requests a dependency, +the container tries to satisfy that dependency with it's own bindings. If the container +lacks bindings, it passes the request up to its parent container. If that container can't +satisfy the request, it passes it along to its parent container. The requests keep +bubbling up until we find an container that can handle the request or run out of container +ancestors. + +```ts +let weaponIdentifier = 'Weapon'; + +@injectable() +class Katana {} + +let parentContainer = new Container(); +parentContainer.bind(weaponIdentifier).to(Katana); + +let childContainer = new Container(); +childContainer.parent = parentContainer; + +expect(childContainer.get(weaponIdentifier)).to.be.instanceOf(Katana); // true +``` diff --git a/src/es/features-and-api/21_contextual_bindings.md b/src/es/features-and-api/21_contextual_bindings.md new file mode 100644 index 0000000..f8b9da2 --- /dev/null +++ b/src/es/features-and-api/21_contextual_bindings.md @@ -0,0 +1,105 @@ +# Contextual bindings & @targetName + +The `@targetName` decorator is used to access the names of the constructor arguments from a +contextual constraint even when the code is compressed. The `constructor(katana, shuriken) { ...` +becomes `constructor(a, b) { ...` after compression but thanks to `@targetName` we can still +refer to the design-time names `katana` and `shuriken` at runtime. + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @targetName('katana') katana: Weapon, + @inject('Weapon') @targetName('shuriken') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a custom `when` constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); + +container + .bind('Weapon') + .to(Katana) + .when((request: interfaces.Request) => { + return request.target.name.equals('katana'); + }); + +container + .bind('Weapon') + .to(Shuriken) + .when((request: interfaces.Request) => { + return request.target.name.equals('shuriken'); + }); +``` + +The target fields implement the `IQueryableString` interface to help you to create your custom constraints: + +```ts +interface QueryableString { + startsWith(searchString: string): boolean; + endsWith(searchString: string): boolean; + contains(searchString: string): boolean; + equals(compareString: string): boolean; + value(): string; +} +``` + +We have included some helpers to facilitate the creation of custom constraints: + +```ts +import { Container, traverseAncerstors, taggedConstraint, namedConstraint, typeConstraint } from 'inversify'; + +let whenParentNamedCanThrowConstraint = (request: interfaces.Request) => { + return namedConstraint('canThrow')(request.parentRequest); +}; + +let whenAnyAncestorIsConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, typeConstraint(Ninja)); +}; + +let whenAnyAncestorTaggedConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, taggedConstraint('canThrow')(true)); +}; +``` + +The InversifyJS fluent syntax for bindings includes some already implemented common contextual constraints: + +```ts +interface BindingWhenSyntax { + when(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenTargetNamed(name: string): interfaces.BindingOnSyntax; + whenTargetTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenInjectedInto(parent: Function | string): interfaces.BindingOnSyntax; + whenParentNamed(name: string): interfaces.BindingOnSyntax; + whenParentTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenNoAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenAnyAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenAnyAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenNoAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenNoAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenNoAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; +} +``` diff --git a/src/es/features-and-api/22_property_injection.md b/src/es/features-and-api/22_property_injection.md new file mode 100644 index 0000000..46989c0 --- /dev/null +++ b/src/es/features-and-api/22_property_injection.md @@ -0,0 +1,128 @@ +# Property injection + +InversifyJS supports property injection because sometimes constructor injection is not the best kind of injection pattern. However, you should try to avoid using property injection and prefer constructor injection in most cases. + +> If the class cannot do its job without the dependency, then add it to the constructor. The class needs the new dependency, so you want your change to break things. Also, creating a class that is not fully initialized ("two-step construction") is an anti-pattern (IMHO). If the class can work without the dependency, a setter is fine. + +Source: [http://stackoverflow.com/](http://stackoverflow.com/questions/1503584/dependency-injection-through-constructors-or-property-setters) + +There are two cases in which you may want to use property injection. + +- When we CAN use InversifyJS to create an instance of a class. +- When we CANNOT use InversifyJS to create an instance of a class. + +These cases are quite different an require different implementations of property injection. + +## When we CAN use InversifyJS to create an instance of a class + +If you are working with a library or framework that allows InversifyJS +to create instances of the classes in the application, then you can inject into +a property using the `@inject` decorator: + +```ts +import { injectable, inject, container } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +@injectable() +class Summary { + // ... +} + +@injectable() +class Author { + // ... +} + +@injectable() +class Book { + private _author: Author; + private _summary: Summary; + + @inject('PrintService') + private _printService: PrintService; + + public constructor(@inject('Author') author: Author, @inject('Summary') summary: Summary) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +container.bind('Author').to(Author); +container.bind('Summary').to(Summary); +container.bind('Book').to(Book); + +// Book instance is created by InversifyJS +let book = container.get('Book'); +book.print(); +``` + +Please refer to our [unit tests](https://github.com/inversify/InversifyJS/blob/master/test/annotation/inject.test.ts) for additional examples. + +## When we CANNOT use InversifyJS to create an instance of a class + +InversifyJS has been designed in a way that facilitates its integration with as many +libraries and frameworks as possible. However, many of its features require being able to +create the instances of the classes in an application. + +The problem is that some frameworks take the control over the creation of instances. +For example, React takes control over the creation of instances of a given Component. + +We have developed an utility that allows you to inject into a property even when +InversifyJS has not created its instances: + +```ts +import getDecorators from 'inversify-inject-decorators'; +import { Container, injectable } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +let { lazyInject } = getDecorators(container); + +class Book { + private _author: string; + private _summary: string; + + @lazyInject('PrintService') + private _printService: PrintService; + + public constructor(author: string, summary: string) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +// Book instance is NOT created by InversifyJS +let book = new Book('Title', 'Summary'); +book.print(); +``` + +The utility module is called `inversify-inject-decorators` +and provides the following decorators: + +- `@lazyInject` for the injection of a property without metadata +- `@lazyInjectNamed` for the injection of a property without named metadata. +- `@lazyInjectTagged` for the injection of a property without tagged metadata. +- `@lazyMultiInject` for multi-injections. + +Please visit the module +[project on GitHub](https://github.com/inversify/inversify-inject-decorators) +to learn more. diff --git a/src/es/features-and-api/23_circular_dependencies.md b/src/es/features-and-api/23_circular_dependencies.md new file mode 100644 index 0000000..8164de1 --- /dev/null +++ b/src/es/features-and-api/23_circular_dependencies.md @@ -0,0 +1,21 @@ +# Circular dependencies + +## Circular dependencies in your modules (ES6, CommonJS, etc.) + +If you have a circular dependency between two modules and you use the `@inject(SomeClass)` annotation. At runtime, one module will be parsed before the other and the decorator could be invoked with `@inject(SomeClass /* SomeClass = undefined*/)`. InversifyJS will throw the following exception: + +> @inject called with undefined this could mean that the class \${name} has a circular dependency problem. You can use a LazyServiceIdentifer to overcome this limitation. + +There are two ways to overcome this limitation: + +- Use a `LazyServiceIdentifer`. The lazy identifier doesn't delay the injection of the dependencies and all dependencies are injected when the class instance is created. However, it does delay the access to the property identifier (solving the module issue). An example of this can be found in [our unit tests](https://github.com/krzkaczor/InversifyJS/blob/a53bf2cbee65803b197998c1df496c3be84731d9/test/inversify.test.ts#L236-L300). + +- Use the `@lazyInject` decorator. This decorator is part of the [`inversify-inject-decorators`](https://github.com/inversify/inversify-inject-decorators) module. The `@lazyInject` decorator delays the injection of the dependencies until they are actually used, this takes place after a class instance has been created. + +## Circular dependencies in the dependency graph (classes) + +InversifyJS is able to identify circular dependencies and will throw an exception to help you to identify the location of the problem if a circular dependency is detected: + +```ts +Error: Circular dependency found: Ninja -> A -> B -> C -> D -> A +``` diff --git a/src/es/features-and-api/24_inheritance.md b/src/es/features-and-api/24_inheritance.md new file mode 100644 index 0000000..4a8e908 --- /dev/null +++ b/src/es/features-and-api/24_inheritance.md @@ -0,0 +1,260 @@ +# Inheritance + +We try to provide developers with useful error feedback like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +This works fine in most cases but it causes some problem when using inheritance. + +For example, the following code snippet throws a misleading error: + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +```ts +@injectable() +class Warrior { + public rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super('master'); + } +} +``` + +In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: + +> A derived class must explicitly declare its constructor. + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +If you don't follow this rule an exception will be thrown: + +> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. + +The users have a few ways to overcome this limitation available: + +## Use the @unmanaged decorator + +The `@unmanaged()` decorator allow users to flag that an argument will +be manually injected into a base class. We use the word "unmanaged" +because InversifyJS does not have control under user provided values +and it doesn't manage their injection. + +The following code snippet showcases how to apply this decorator: + +```ts +import { Container, injectable, unmanaged } from '../src/inversify'; + +const BaseId = 'Base'; + +@injectable() +class Base { + public prop: string; + public constructor(@unmanaged() arg: string) { + this.prop = arg; + } +} + +@injectable() +class Derived extends Base { + public constructor() { + super('unmanaged-injected-value'); + } +} + +container.bind(BaseId).to(Derived); +let derived = container.get(BaseId); + +derived instanceof Derived2; // true +derived.prop; // "unmanaged-injected-value" +``` + +## Property setter + +You can use the `public`, `protected` or `private` access modifier and a +property setter to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() { + // args count = 0 + this.rank = null; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super(); + this.rank = 'master'; + } +} +``` + +## Property injection + +We can also use property injection to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() {} // args count = 0 +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + @injectNamed(TYPES.Rank, 'master') + @named('master') + protected rank: string; + + public constructor() { + // args count = 0 + super(); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Inject into the derived class + +If we don't want to avoid injecting into the base class we can +inject into the derived class and then into the base class using +its constructor (super). + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + public constructor( + @inject(TYPES.Rank) @named('master') rank: string // args count = 1 + ) { + super(rank); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +The following should also work: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +let TYPES = { + Rank: 'Rank', + Weapon: 'Weapon' +}; + +@injectable() +class SamuraiMaster extends Warrior { + public weapon: Weapon; + public constructor( + @inject(TYPES.Rank) @named('master') rank: string, // args count = 2 + @inject(TYPES.Weapon) weapon: Weapon + ) { + super(rank); + this.weapon = weapon; + } +} + +container.bind(TYPES.Weapon).to(Katana); + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Skip Base class `@injectable` checks + +Setting the `skipBaseClassChecks` option to `true` for the container will disable all checking of base classes. This means it will be completely up to the developer to ensure that the `super()` constructor is called with the correct arguments and at the correct time. + +```ts +// Not injectable +class UnmanagedBase { + public constructor(public unmanagedDependency: string) {} +} + +@injectable() +class InjectableDerived extends UnmanagedBase { + public constructor() // Any arguments defined here will be injected like normal + { + super("Don't forget me..."); + } +} + +const container = new Container({ skipBaseClassChecks: true }); +container.bind(InjectableDerived).toSelf(); +``` + +This will work, and you'll be able to use your `InjectableDerived` class just like normal, including injecting dependencies from elsewhere in the container through the constructor. The one caveat is that you must make sure your `UnmanagedBase` receives the correct arguments. + +## What can I do when my base class is provided by a third party module? + +In some cases, you may get errors about missing annotations in classes +provided by a third party module like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +You can overcome this problem using the `decorate` function: + +```ts +import { decorate, injectable } from 'inversify'; +import SomeClass from 'some-module'; + +decorate(injectable(), SomeClass); +return SomeClass; +``` + +Check out the [JS example](https://github.com/inversify/InversifyJS/blob/master/wiki/basic_js_example.md) +page on the wiki for more info. diff --git a/src/es/features-and-api/25_transitive_bindings.md b/src/es/features-and-api/25_transitive_bindings.md new file mode 100644 index 0000000..69e2db1 --- /dev/null +++ b/src/es/features-and-api/25_transitive_bindings.md @@ -0,0 +1,62 @@ +# Transitive bindings + +A transitive type binding allows as to declare a type binding that is resolved by a previously declared type binding. + +A transitive binding can be declared using the `toService` method: + +```ts +@injectable() +class MySqlDatabaseTransactionLog { + public time: number; + public name: string; + public constructor() { + this.time = new Date().getTime(); + this.name = 'MySqlDatabaseTransactionLog'; + } +} + +@injectable() +class DatabaseTransactionLog { + public time: number; + public name: string; +} + +@injectable() +class TransactionLog { + public time: number; + public name: string; +} + +const container = new Container(); +container + .bind(MySqlDatabaseTransactionLog) + .toSelf() + .inSingletonScope(); +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); + +const mySqlDatabaseTransactionLog = container.get(MySqlDatabaseTransactionLog); +const databaseTransactionLog = container.get(DatabaseTransactionLog); +const transactionLog = container.get(TransactionLog); + +expect(mySqlDatabaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(databaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(transactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(mySqlDatabaseTransactionLog.time).to.eq(databaseTransactionLog.time); +expect(databaseTransactionLog.time).to.eq(transactionLog.time); +``` + +There is also an utility function named `multiBindToService` which allows us to declare multiple transitive bindings in one go. + +For example, instead of writing the following: + +```ts +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); +``` + +We can use `multiBindToService` to write the following: + +```ts +multiBindToService(container)(MySqlDatabaseTransactionLog)(DatabaseTransactionLog, TransactionLog); +``` diff --git a/src/es/features-and-api/26_pre_destroy.md b/src/es/features-and-api/26_pre_destroy.md new file mode 100644 index 0000000..1a6879e --- /dev/null +++ b/src/es/features-and-api/26_pre_destroy.md @@ -0,0 +1,23 @@ +# Pre Destroy Decorator + +It is possible to add a **@preDestroy** decorator for a class method. This decorator will run before a service is unbinded for any cached instance. For this reason, only bindings in singleton scope can contain a method with this decorator. + +```ts +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + console.log('Destroyable is about to be unbinded!'); + } +} + +const container = new Container(); +container + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope(); + +container.get('Destroyable'); + +container.unbindAll(); +``` diff --git a/src/es/features-and-api/2_container_modules.md b/src/es/features-and-api/2_container_modules.md new file mode 100644 index 0000000..c5ee011 --- /dev/null +++ b/src/es/features-and-api/2_container_modules.md @@ -0,0 +1,65 @@ +# Declaring container modules + +Container modules can help you to manage the complexity of your bindings in very large applications. + +The constructor argument for ContainerModule and AsyncContainerModule is a registration callback that is passed functions that behave the same as the methods of the Container class. The registration callback for the AsyncContainerModule is asynchronous. + +When a container module is loaded into a Container the registration callback is invoked. This is the opportunity for the container module to register bindings and handlers. Use the Container load method for ContainerModule instances and the Container loadAsync method for AsyncContainerModule instances. + +When a container module is unloaded from a Container the bindings added by that container will be removed and the [deactivation process](../features-and-api/12_deactivation_handler) will occur for each of them. Container deactivation and [activation handlers](../features-and-api/11_activation_handler) will also be removed. +Use the unloadAsync method to unload when there will be an async deactivation handler or async [pre destroy](../features-and-api/26_pre_destroy) + +## Synchronous container modules + +```ts +let warriors = new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind) => { + bind('Ninja').to(Ninja); +}); + +let weapons = new ContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +container.load(warriors, weapons); +container.unload(warriors); +``` + +## Asynchronous container modules + +```ts +let warriors = new AsyncContainerModule(async (bind: interfaces.Bind, unbind: interfaces.Unbind) => { + const ninja = await getNinja(); + bind('Ninja').toConstantValue(ninja); +}); + +let weapons = new AsyncContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +await container.loadAsync(warriors, weapons); +container.unload(warriors); +``` diff --git a/src/es/features-and-api/3_container_snapshots.md b/src/es/features-and-api/3_container_snapshots.md new file mode 100644 index 0000000..8125b41 --- /dev/null +++ b/src/es/features-and-api/3_container_snapshots.md @@ -0,0 +1,53 @@ +# Container snapshots + +Declaring container snapshots is a feature that helps you to write unit tests with ease: + +```ts +import { expect } from 'chai'; +import * as sinon from 'sinon'; + +// application container is shared by all unit tests +import container from '../../src/ioc/container'; + +describe('Ninja', () => { + beforeEach(() => { + // create a snapshot so each unit test can modify + // it without breaking other unit tests + container.snapshot(); + }); + + afterEach(() => { + // Restore to last snapshot so each unit test + // takes a clean copy of the application container + container.restore(); + }); + + // each test is executed with a snapshot of the container + + it('Ninja can fight', () => { + let katanaMock = { + hit: () => { + return 'hit with mock'; + } + }; + + container.unbind('Katana'); + container.bind('Katana').toConstantValue(katanaMock); + let ninja = container.get('Ninja'); + expect(ninja.fight()).eql('hit with mock'); + }); + + it('Ninja can sneak', () => { + let shurikenMock = { + throw: () => { + return 'hit with mock'; + } + }; + + container.unbind('Shuriken'); + container.bind('Shuriken').toConstantValue(shurikenMock); + let ninja = container.get('Shuriken'); + expect(ninja.sneak()).eql('hit with mock'); + }); +}); +``` diff --git a/src/es/features-and-api/4_scope.md b/src/es/features-and-api/4_scope.md new file mode 100644 index 0000000..2716beb --- /dev/null +++ b/src/es/features-and-api/4_scope.md @@ -0,0 +1,104 @@ +# Controlling the scope of the dependencies + +InversifyJS uses transient scope by default but you can also use singleton and request scope: + +```ts +container + .bind('Shuriken') + .to(Shuriken) + .inTransientScope(); // Default +container + .bind('Shuriken') + .to(Shuriken) + .inSingletonScope(); +container + .bind('Shuriken') + .to(Shuriken) + .inRequestScope(); +``` + +## About `inSingletonScope` + +There are many available kinds of bindings: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingWhenOnSyntax; + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +In terms of how scope behaves we can group these types of bindings in two main groups: + +- Bindings that will inject an `object` +- Bindings that will inject a `function` + +### Bindings that will inject an `object` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingInWhenOnSyntax; +} +``` + +The `inTransientScope` is used by default and we can select the scope of this types of binding, except for `toConstantValue` which will always use `inSingletonScope`. + +When we invoke `container.get` for the first time and we are using `to`, `toSelf` or `toDynamicValue` the InversifyJS container will try to generate an object instance or value using a constructor or the dynamic value factory. If the scope has been set to `inSingletonScope` the value is cached. The second time we invoke `container.get` for the same resource ID, and if `inSingletonScope` has been selected, InversifyJS will try to get the value from the cache. + +Note that a class can have some dependencies and a dynamic value can access other types via the current context. These dependencies may or may not be a singleton independently of the selected scope of their parent object in their respective composition tree, + +### Bindings that will inject a `function` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +We cannot select the scope of this types of binding because the value to be injected (a factory `function`) is always a singleton. However, the factory internal implementation may or may not return a singleton. + +For example, the following binding will inject a factory which will always be a singleton. + +```ts +container.bind>('Factory').toAutoFactory('Katana'); +``` + +However, the value returned by the factory may or may not be a singleton: + +```ts +container + .bind('Katana') + .to(Katana) + .inTransientScope(); +// or +container + .bind('Katana') + .to(Katana) + .inSingletonScope(); +``` + +## About `inRequestScope` + +When we use inRequestScope we are using a special kind of singleton. + +- The `inSingletonScope` creates a singleton that will last for the entire life cycle of a type binding. This means that the `inSingletonScope` can be cleared up from memory when we unbind a type binding using `container.unbind`. + +- The `inRequestScope` creates a singleton that will last for the entire life cycle of one call to the `container.get`, `container.getTagged` or `container.getNamed` methods. Each call to one of this methods will resolve a root dependency and all its sub-dependencies. Internally, a dependency graph known as the "resolution plan" is created by InversifyJS. The `inRequestScope` scope will use one single instance for objects that appear multiple times in the resolution plan. This reduces the number of required resolutions and it can be used as a performance optimization in some cases. diff --git a/src/es/features-and-api/5_optional_dependencies.md b/src/es/features-and-api/5_optional_dependencies.md new file mode 100644 index 0000000..0304d25 --- /dev/null +++ b/src/es/features-and-api/5_optional_dependencies.md @@ -0,0 +1,87 @@ +# Optional dependencies + +We can declare an optional dependency using the `@optional()` decorator: + +```ts +@injectable() +class Katana { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken // Optional! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} + +let container = new Container(); + +container.bind('Katana').to(Katana); +container.bind('Ninja').to(Ninja); + +let ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken).to.eql(undefined); + +container.bind('Shuriken').to(Shuriken); + +ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken.name).to.eql('Shuriken'); +``` + +In the example we can see how the first time we resolve `Ninja`, its +property `shuriken` is undefined because no bindings have been declared +for `Shuriken` and the property is annotated with the `@optional()` decorator. + +After declaring a binding for `Shuriken`: + +```ts +container.bind('Shuriken').to(Shuriken); +``` + +All the resolved instances of `Ninja` will contain an instance of `Shuriken`. + +## Default values + +If a dependency is decorated with the `@optional()` decorator, we will be able to to declare +a default value just like you can do in any other TypeScript application: + +```ts +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken = { name: 'DefaultShuriken' } // Default value! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/es/features-and-api/6_value_injection.md b/src/es/features-and-api/6_value_injection.md new file mode 100644 index 0000000..764b696 --- /dev/null +++ b/src/es/features-and-api/6_value_injection.md @@ -0,0 +1,19 @@ +# Injecting a constant or dynamic value + +Binds an abstraction to a constant value: + +```ts +container.bind('Katana').toConstantValue(new Katana()); +``` + +Binds an abstraction to a dynamic value: + +```ts +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return new Katana(); +}); +// a dynamic value can return a promise that will resolve to the value +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return Promise.resolve(new Katana()); +}); +``` diff --git a/src/es/features-and-api/7_constructor_injection.md b/src/es/features-and-api/7_constructor_injection.md new file mode 100644 index 0000000..8f2ef9b --- /dev/null +++ b/src/es/features-and-api/7_constructor_injection.md @@ -0,0 +1,54 @@ +# Injecting a class constructor + +InversifyJS supports constructor injection to allow passing abstractions or instances of concrete classes +during the creation of the injectable object. + +In case of abstractions (interfaces) you need to use the @inject decorator. This is required because +the metadata of the abstractions are not available during runtime : + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Newable') Katana: interfaces.Newable, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = new Katana(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Newable').toConstructor(Katana); +``` + +In case of concrete injections, you can simply define your constructor parameters as usual without using the @inject decorator. + +InversifyJS also supports TypeScript's constructor assignments so you can have private or protected access modifiers in your parameters +and the container will have no trouble injecting the dependencies : + +```ts +@injectable() +class Ninja implements Ninja { + public constructor(private _dagger: Dagger) {} + + public throwDagger() { + this._dagger.throw(); + } +} +``` + +```ts +container.bind(Dagger).toSelf(); +``` diff --git a/src/es/features-and-api/8_factory_injection.md b/src/es/features-and-api/8_factory_injection.md new file mode 100644 index 0000000..da1e16f --- /dev/null +++ b/src/es/features-and-api/8_factory_injection.md @@ -0,0 +1,79 @@ +# Injecting a Factory + +Binds an abstraction to a user defined Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Factory') katanaFactory: () => Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return () => { + return context.container.get('Katana'); + }; +}); +``` + +You can also define a Factory with args: + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return (throwable: boolean) => { + if (throwable) { + return context.container.getTagged('Weapon', 'throwable', true); + } else { + return context.container.getTagged('Weapon', 'throwable', false); + } + }; +}); +``` + +Sometimes you might need to pass arguments to a factory in different moments during the execution: + +```ts +container + .bind('Engine') + .to(PetrolEngine) + .whenTargetNamed('petrol'); +container + .bind('Engine') + .to(DieselEngine) + .whenTargetNamed('diesel'); + +container.bind>('Factory').toFactory((context) => { + return (named: string) => (displacement: number) => { + let engine = context.container.getNamed('Engine', named); + engine.displacement = displacement; + return engine; + }; +}); + +@injectable() +class DieselCarFactory implements CarFactory { + private _dieselFactory: (displacement: number) => Engine; + constructor( + @inject('Factory') factory: (category: string) => (displacement: number) => Engine // Injecting an engine factory + ) { + this._dieselFactory = factory('diesel'); // Creating a diesel engine factory + } + public createEngine(displacement: number): Engine { + return this._dieselFactory(displacement); // Creating a concrete diesel engine + } +} +``` diff --git a/src/es/features-and-api/9_auto_factory.md b/src/es/features-and-api/9_auto_factory.md new file mode 100644 index 0000000..e152a64 --- /dev/null +++ b/src/es/features-and-api/9_auto_factory.md @@ -0,0 +1,32 @@ +# Auto factory + +Binds an abstraction to an auto-generated Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Factory') katanaFactory: interfaces.Factory, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind('Katana').to(Katana); + +container.bind>('Factory').toAutoFactory('Katana'); +``` diff --git a/src/es/features-and-api/README.md b/src/es/features-and-api/README.md new file mode 100644 index 0000000..8bd8303 --- /dev/null +++ b/src/es/features-and-api/README.md @@ -0,0 +1,168 @@ +# Support for classes + +InversifyJS allows your classes to have a direct dependency on other classes. When doing so you will need to use the `@injectable` decorator but you will not be required to use the `@inject` decorator. + +The `@inject` decorator is not required when you use classes. The annotation is not required because the typescript compiler generates the metadata for us. However, this won't happen if you forget one of the following things: + +- Import `reflect-metadata` +- Set `emitDecoratorMetadata` to `true` in `tsconfig.json`. + +```ts +import { Container, injectable, inject } from 'inversify'; + +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrion { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(Katana).to(Katana); +container.bind(Shuriken).to(Shuriken); +``` + +## Self-binding of concrete types + +If the type you’re resolving is a concrete type the registration of a binding can feel a repetitive and verbose: + +```ts +container.bind(Samurai).to(Samurai); +``` + +A better solution is to use the `toSelf` method: + +```ts +container.bind(Samurai).toSelf(); +``` + +## Known Limitation: Classes as identifiers and circular dependencies + +An exception: + +::: danger +Error: Missing required @Inject or @multiinject annotation in: argument 0 in class Dom. +::: + +Will be thrown if we use classes as identifiers in circular dependencies. For example: + +```ts +import 'reflect-metadata'; +import { Container, injectable } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +let container = new Container(); +let { lazyInject } = getDecorators(container); + +@injectable() +class Dom { + public domUi: DomUi; + constructor(domUi: DomUi) { + this.domUi = domUi; + } +} + +@injectable() +class DomUi { + @lazyInject(Dom) public dom: Dom; +} + +@injectable() +class Test { + constructor(dom: Dom) { + console.log(dom); + } +} + +container + .bind(Dom) + .toSelf() + .inSingletonScope(); +container + .bind(DomUi) + .toSelf() + .inSingletonScope(); +const dom = container.resolve(Test); // Error! +``` + +This error may seem a bit misleading because when using classes as service identifiers `@inject` annotations should not be required and if we do add an annotation like `@inject(Dom)` or `@inject(DomUi)` we will still get the same exception. This happens because, at the point in time in which the decorator is invoked, the class has not been declared so the decorator is invoked as `@inject(undefined)`. This trigger InversifyJS to think that the annotation was never added. + +The solution is to use symbols like `Symbol.for("Dom")` as service identifiers instead of the classes like `Dom`: + +```ts +import 'reflect-metadata'; +import { Container, injectable, inject } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +const container = new Container(); +const { lazyInject } = getDecorators(container); + +const TYPE = { + Dom: Symbol.for('Dom'), + DomUi: Symbol.for('DomUi') +}; + +@injectable() +class DomUi { + public dom: Dom; + public name: string; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + this.name = 'DomUi'; + } +} + +@injectable() +class Dom { + public name: string; + @lazyInject(TYPE.DomUi) public domUi: DomUi; + public constructor() { + this.name = 'Dom'; + } +} + +@injectable() +class Test { + public dom: Dom; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + } +} + +container + .bind(TYPE.Dom) + .to(Dom) + .inSingletonScope(); +container + .bind(TYPE.DomUi) + .to(DomUi) + .inSingletonScope(); + +const test = container.resolve(Test); // Works! +``` diff --git a/src/es/getting-started/README.md b/src/es/getting-started/README.md new file mode 100644 index 0000000..0a2a05d --- /dev/null +++ b/src/es/getting-started/README.md @@ -0,0 +1,142 @@ +# Getting Started + +## Installation + +You can get the latest release and the type definitions using npm: + +```sh +npm install inversify@5.1.1 reflect-metadata --save +``` + +Or using yarn: + +```sh +yarn add inversify@5.1.1 reflect-metadata +``` + +The InversifyJS type definitions are included in the inversify npm package. InversifyJS requires the `experimentalDecorators`, `emitDecoratorMetadata`and `lib` compilation options in your `tsconfig.json` file. + +```js +{ + "compilerOptions": { + "target": "es5", + "lib": ["es6"], + "types": ["reflect-metadata"], + "module": "commonjs", + "moduleResolution": "node", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +InversifyJS requires a modern JavaScript engine with support for: + +- [Reflect metadata](https://github.com/rbuckton/ReflectDecorators/blob/master/spec/metadata.md) +- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) (Only required if using [provider injection](../features-and-api/10_provider_injection)) +- [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) (Only required if using [activation handlers](../features-and-api/11_activation_handler)) + +If your environment don't support one of these you will need to import a shim or polyfill. + +**Check out the [Environment support and polyfills](https://github.com/inversify/InversifyJS/blob/master/wiki/environment.md) +page in the wiki to learn more.** + +## Declaring Interfaces + +Our goal is to write code that adheres to the [dependency inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle). This means that we should "depend upon Abstractions and do not depend upon concretions". Let's start by declaring some interfaces (abstractions). + +```ts +interface Warrior { + fight(): string; + sneak(): string; +} + +interface Weapon { + hit(): string; +} + +interface ThrowableWeapon { + throw(): string; +} +``` + +InversifyJS need to use the type as identifiers at runtime. We use symbols as identifiers but you can also use classes and or string literals. + +```ts +let TYPES = { + Warrior: Symbol('Warrior'), + Weapon: Symbol('Weapon'), + ThrowableWeapon: Symbol('ThrowableWeapon') +}; + +export default TYPES; +``` + +::: tip +**Note:** It is recommended to use Symbols but InversifyJS also support the usage of Classes and string literals (please refer to the features section to learn more). +::: + +## Declaring Classes and Dependencies + +Let's continue by declaring some classes (concretions). The classes are implementations of the interfaces that we just declared. All the classes must be annotated with the `@injectable` decorator. + +When a class has a dependency on an interface we also need to use the @inject decorator to define an identifier for the interface that will be available at runtime. In this case we will use the Symbols `Symbol("Weapon")` and `Symbol("ThrowableWeapon")` as runtime identifiers. + +```ts +import { injectable, inject } from 'inversify'; +import 'reflect-metadata'; +import TYPES from './types'; + +@injectable() +class Katana implements Weapon { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements ThrowableWeapon { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrior { + private _katana: Weapon; + private _shuriken: ThrowableWeapon; + + public constructor(@inject(TYPES.Weapon) katana: Weapon, @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} + +export { Ninja, Katana, Shuriken }; +``` + +If you prefer it you can use property injection instead of constructor injection so you don't have to declare the class constructor: + +```ts +@injectable() +class Ninja implements Warrior { + @inject(TYPES.Weapon) private _katana: Weapon; + @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon; + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} +``` diff --git a/src/es/index.md b/src/es/index.md new file mode 100644 index 0000000..980e0a2 --- /dev/null +++ b/src/es/index.md @@ -0,0 +1,91 @@ +--- +home: true +title: InversifyJS +heroImage: /logo_transparent.svg +heroText: InversifyJS +tagline: A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript. +actionText: Quick Start → +actionLink: /es/introduction/ +companies: + - link: https://opensource.microsoft.com/ + logo: https://avatars0.githubusercontent.com/u/6154722?s=200&v=4 + + - link: https://code.facebook.com/projects/1021334114569758/nuclide/ + logo: https://avatars2.githubusercontent.com/u/69631?s=200&v=4 + + - link: https://aws.github.io/aws-amplify/ + logo: https://avatars0.githubusercontent.com/u/2232217?s=200&v=4 + + - link: https://www.plainconcepts.com/ + logo: https://avatars0.githubusercontent.com/u/1520648?s=200&v=4 + + - link: https://api.slack.com/ + logo: https://avatars3.githubusercontent.com/u/6962987?s=200&v=4 + + - link: https://www.lonelyplanet.com/ + logo: https://avatars3.githubusercontent.com/u/114767?s=200&v=4 + + - link: https://jincor.com/ + logo: https://avatars0.githubusercontent.com/u/25283328?s=200&v=4 + + - link: https://www.web-computing.de/ + logo: https://avatars1.githubusercontent.com/u/1957282?s=200&v=4 + + - link: https://dcos.io/ + logo: https://avatars1.githubusercontent.com/u/17648048?s=200&v=4 + + - link: https://typefox.io/ + logo: https://avatars0.githubusercontent.com/u/16970371?s=200&v=4 + + - link: https://code4.ro/ + logo: https://avatars0.githubusercontent.com/u/18010308?s=200&v=4 + + - link: http://www.baidu.com/ + logo: https://user-images.githubusercontent.com/10656223/33888109-fae0852e-df43-11e7-97f6-9db543da0bde.png + + - link: https://www.imdada.cn/ + logo: https://avatars2.githubusercontent.com/u/8085382?s=200&v=4 + + - link: https://www.ato.gov.au/ + logo: https://avatars2.githubusercontent.com/u/17041151?s=200&v=4 + + - link: https://www.kaneoh.com/ + logo: https://avatars1.githubusercontent.com/u/14963540?s=200&v=4 + + - link: https://particl.io/ + logo: https://avatars0.githubusercontent.com/u/26021686?s=200&v=4 + + - link: https://slackmap.com/ + logo: https://avatars2.githubusercontent.com/u/24523195?s=200&v=4 + + - link: https://www.go1.com/ + logo: https://avatars3.githubusercontent.com/u/16556899?s=200&v=4 + + - link: http://www.stellwagengroup.com/stellwagen-technology/ + logo: https://avatars3.githubusercontent.com/u/23475730?s=200&v=4 + + - link: https://www.edrlab.org/ + logo: https://avatars1.githubusercontent.com/u/15262567?s=200&v=4 + + - link: https://www.goodgamestudios.com/ + logo: https://avatars1.githubusercontent.com/u/10072104?s=200&v=4 + + - link: https://freshfox.at/ + logo: https://avatars2.githubusercontent.com/u/13613760?s=200&v=4 + + - link: https://schubergphilis.com/ + logo: https://avatars1.githubusercontent.com/u/864482?s=200&v=4 + +features: + - title: Strongly Typed + details: InversifyJS is powered by TypeScript. TypeScript enable JavaScript developers to use highly-productive development tools and practices when developing JavaScript applications. + + - title: Universal + details: InversifyJS compiles to clean, simple JavaScript code which runs on any browser, in Node.js, or in any JavaScript engine that supports ECMAScript 5 (or newer). + + - title: Pluggable + details: Inversifyjs is framework-agnostic and has been designed to in a way that makes possible its integration with popular frameworks and libraries like hapi, express, react or backbone. + +footer: Released under the MIT License +copyright: Copyright © 2015 - present Remo H. Jansen +--- diff --git a/src/es/introduction/README.md b/src/es/introduction/README.md new file mode 100644 index 0000000..32c1f75 --- /dev/null +++ b/src/es/introduction/README.md @@ -0,0 +1,55 @@ +--- +title: Introduction +--- + +# Introduction + +InversifyJS is a lightweight (4KB) inversion of control (IoC) container for TypeScript and JavaScript apps. A IoC container uses a class constructor to identify and inject its dependencies. + +InversifyJS has a friendly API and encourage the usage of the best OOP and IoC practices. + +## Motivation + +JavaScript now supports object oriented (OO) programming with class based inheritance. These features are great but the truth is that they are also dangerous. + +We need a good OO design to protect ourselves from these threats. The problem is that OO design is difficult and that is exactly why we created InversifyJS. + +InversifyJS is a tool that helps JavaScript developers to write code with a good OO design. + +## Philosophy + +InversifyJS has been developed with 4 main goals: + +- Allow JavaScript developers to write code that adheres to the SOLID principles. +- Facilitate and encourage the adherence to the best OOP and IoC practices. +- Add as little runtime overhead as possible. +- Provide a state of the art development experience. + +## Features and API + +InversifyJS is powerful IoC container and supports the following features: + +- [Support for classes](../features-and-api) +- [Support for Symbols](../features-and-api/0_symbols_as_id) +- [Container API](../features-and-api/1_container_api) +- [Declaring container modules](../features-and-api/2_container_modules) +- [Container snapshots](../features-and-api/3_container_snapshots) +- [Controlling the scope of the dependencies](../features-and-api/4_scope) +- [Declaring optional dependencies](../features-and-api/5_optional_dependencies) +- [Injecting a constant or dynamic value](../features-and-api/6_value_injection) +- [Injecting a class constructor](../features-and-api/7_constructor_injection) +- [Injecting a Factory](../features-and-api/8_factory_injection) +- [Auto factory](../features-and-api/9_auto_factory) +- [Injecting a Provider (asynchronous Factory)](../features-and-api/10_provider_injection) +- [Activation handler](../features-and-api/11_activation_handler) +- [Middleware](../features-and-api/12_middleware) +- [Multi-injection](../features-and-api/15_multi_injection) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Create your own tag decorators](../features-and-api/17_custom_tag_decorators) +- [Named bindings](../features-and-api/18_named_bindings) +- [Default target](../features-and-api/19_default_targets) +- [Support for hierarchical DI systems](../features-and-api/20_hierarchical_di) +- [Contextual bindings & @targetName](../features-and-api/21_contextual_bindings) +- [Property injection](../features-and-api/22_property_injection) +- [Circular dependencies](../features-and-api/23_circular_dependencies) +- [Inheritance](../features-and-api/24_inheritance) diff --git a/src/es/why-inversifyjs/README.md b/src/es/why-inversifyjs/README.md new file mode 100644 index 0000000..20bec4d --- /dev/null +++ b/src/es/why-inversifyjs/README.md @@ -0,0 +1,129 @@ +# Why InversifyJS? + +There are many good reasons to use InversifyJS but we would like to highlight some of them: + +## 1. Real decoupling + +InversifyJS offers you real decoupling. Consider the following class: + +```ts +let TYPES = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +export { TYPES }; +``` + +```ts +import { TYPES } from './constants/types'; + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(TYPES.Katana) katana: Katana, @inject(TYPES.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +The `Ninja` class will never point to the `Katana` or `Shuriken` classes. However, +it will point to the interfaces (at design-time) or Symbols (at run-time) which is +admissible because these are abstractions and +[**depending upon abstractions**](https://en.wikipedia.org/wiki/Dependency_inversion_principle) +is what DI is all about. + +The InversifyJS container is the only element in the application aware of the life-cycle and dependencies. +We recommend to do this in a file named `inversify.config.ts` and store the file in the root folder +that contains the application source code: + +```ts +import { TYPES } from './constants/types'; +import { Katana } from './entitites/katana'; +import { Shuriken } from './entitites/shuriken'; +import { Ninja } from './entitites/ninja'; + +container.bind(TYPES.KATANA).to(Katana); +container.bind(TYPES.SHURIKEN).to(Shuriken); +container.bind(TYPES.NINJA).to(Ninja); +``` + +This means that all the coupling in your application takes place in one unique place: the `inversify.config.ts` file. +This is really important and we are going to prove it with an example. +Let's imagine that we are changing the difficulty in a game. +We just need to go to the `inversify.config.ts` and change the Katana binding: + +```ts +import { Katana } from './entitites/SharpKatana'; + +if (difficulty === 'hard') { + container.bind(TYPES.KATANA).to(SharpKatana); +} else { + container.bind(TYPES.KATANA).to(Katana); +} +``` + +You don't need to change the Ninja file! + +The price to pay is the usage of Symbols or string literals but this price can be mitigated if you declare all your +string literals in a file which contains constants +([like actions in Redux](https://github.com/reactjs/redux/blob/master/examples/todomvc/src/constants/ActionTypes.js)). +The good news is that in the future the symbols or string literals +[could end up being generated by the TS compiler](https://github.com/Microsoft/TypeScript/issues/2577), but +that is in the hands of the TC39 committee for the moment. + +## 2. Solves competitors issues + +Some "old" JavaScript IoC container like the angular 1.x `$injector` have some problems: + +![](http://i.imgur.com/Y2lRw4N.png) + +[Source](https://angular.io/docs/ts/latest/guide/dependency-injection.html) + +InversifyJS solves these problems: + +- There is support for transient and singleton scope. +- There are no namespace collisions thanks to tagged, named and contextual bindings. +- It is a stand alone library. + +## 3. All the features that you may need + +As far as I know it is the only IoC container for JavaScript that features complex dependency +resolution (e.g. contextual bindings), multiple scopes (transient, singleton) and many other features. +On top of that there is room for growth with features like interception or web worker scope. +We also have plans for the development of dev-tools like browser extensions and middleware (logging, caching...). + +## 4. Object composition is a pain + +You may think that you don't need an IoC container. + +![](https://raw.githubusercontent.com/inversify/inversify.github.io/master/img/so.png) + +If the [preceding argument](http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code) is not enough you may want to read the following: + +- [The current state of dependency inversion in JavaScript](http://blog.wolksoftware.com/the-current-state-of-dependency-inversion-in-javascript) +- [About object-oriented design and the “class” & “extends” keywords in TypeScript / ES6](http://blog.wolksoftware.com/about-classes-inheritance-and-object-oriented-design-in-typescript-and-es6) + +## 5. Type safety + +The library has been developed using TypeScript so type safety comes out of the box if you work +with TypeScript but it is nice to mention that if you try to inject a Katana into a class that +expects an implementation of `Shuriken` you will get a compilation error. + +## 6. Great development experience + +We are working hard to provide you with a great IoC container for your JavaScript apps but also a great development experience. +We have spend a lot of time trying to make the InversifyJS as user friendly as possible and are working on development tools for chrome and we have already developed a logger middleware to help you to debug in Node.js. + +![](http://inversify.io/img/devtools1.png) diff --git a/src/index.md b/src/index.md new file mode 100644 index 0000000..037f77b --- /dev/null +++ b/src/index.md @@ -0,0 +1,91 @@ +--- +home: true +title: InversifyJS +heroImage: /logo_transparent.svg +heroText: InversifyJS +tagline: A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript. +actionText: Quick Start → +actionLink: /language +companies: + - link: https://opensource.microsoft.com/ + logo: https://avatars0.githubusercontent.com/u/6154722?s=200&v=4 + + - link: https://code.facebook.com/projects/1021334114569758/nuclide/ + logo: https://avatars2.githubusercontent.com/u/69631?s=200&v=4 + + - link: https://aws.github.io/aws-amplify/ + logo: https://avatars0.githubusercontent.com/u/2232217?s=200&v=4 + + - link: https://www.plainconcepts.com/ + logo: https://avatars0.githubusercontent.com/u/1520648?s=200&v=4 + + - link: https://api.slack.com/ + logo: https://avatars3.githubusercontent.com/u/6962987?s=200&v=4 + + - link: https://www.lonelyplanet.com/ + logo: https://avatars3.githubusercontent.com/u/114767?s=200&v=4 + + - link: https://jincor.com/ + logo: https://avatars0.githubusercontent.com/u/25283328?s=200&v=4 + + - link: https://www.web-computing.de/ + logo: https://avatars1.githubusercontent.com/u/1957282?s=200&v=4 + + - link: https://dcos.io/ + logo: https://avatars1.githubusercontent.com/u/17648048?s=200&v=4 + + - link: https://typefox.io/ + logo: https://avatars0.githubusercontent.com/u/16970371?s=200&v=4 + + - link: https://code4.ro/ + logo: https://avatars0.githubusercontent.com/u/18010308?s=200&v=4 + + - link: http://www.baidu.com/ + logo: https://user-images.githubusercontent.com/10656223/33888109-fae0852e-df43-11e7-97f6-9db543da0bde.png + + - link: https://www.imdada.cn/ + logo: https://avatars2.githubusercontent.com/u/8085382?s=200&v=4 + + - link: https://www.ato.gov.au/ + logo: https://avatars2.githubusercontent.com/u/17041151?s=200&v=4 + + - link: https://www.kaneoh.com/ + logo: https://avatars1.githubusercontent.com/u/14963540?s=200&v=4 + + - link: https://particl.io/ + logo: https://avatars0.githubusercontent.com/u/26021686?s=200&v=4 + + - link: https://slackmap.com/ + logo: https://avatars2.githubusercontent.com/u/24523195?s=200&v=4 + + - link: https://www.go1.com/ + logo: https://avatars3.githubusercontent.com/u/16556899?s=200&v=4 + + - link: http://www.stellwagengroup.com/stellwagen-technology/ + logo: https://avatars3.githubusercontent.com/u/23475730?s=200&v=4 + + - link: https://www.edrlab.org/ + logo: https://avatars1.githubusercontent.com/u/15262567?s=200&v=4 + + - link: https://www.goodgamestudios.com/ + logo: https://avatars1.githubusercontent.com/u/10072104?s=200&v=4 + + - link: https://freshfox.at/ + logo: https://avatars2.githubusercontent.com/u/13613760?s=200&v=4 + + - link: https://schubergphilis.com/ + logo: https://avatars1.githubusercontent.com/u/864482?s=200&v=4 + +features: + - title: Strongly Typed + details: InversifyJS is powered by TypeScript. TypeScript enable JavaScript developers to use highly-productive development tools and practices when developing JavaScript applications. + + - title: Universal + details: InversifyJS compiles to clean, simple JavaScript code which runs on any browser, in Node.js, or in any JavaScript engine that supports ECMAScript 5 (or newer). + + - title: Pluggable + details: Inversifyjs is framework-agnostic and has been designed to in a way that makes possible its integration with popular frameworks and libraries like hapi, express, react or backbone. + +footer: Released under the MIT License +copyright: Copyright © 2015 - present Remo H. Jansen +--- diff --git a/src/language.md b/src/language.md new file mode 100644 index 0000000..524c5f9 --- /dev/null +++ b/src/language.md @@ -0,0 +1,21 @@ +--- +sidebar: false +--- + +# Select Your Language + +These documents may not have your language. + +Check out [the support section](./support/) to learn how to contribute. + +## Languages + +[English](/en/introduction) + +## Additional Language Support + +Keep in mind that these are community maintained and may not be up to date. + +[Română](/ro/introduction) + +[Español](/es/introduction) diff --git a/src/main.js b/src/main.js deleted file mode 100644 index ddf890b..0000000 --- a/src/main.js +++ /dev/null @@ -1,42 +0,0 @@ -(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ -(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), -m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) -})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - -ga('create', 'UA-61841851-1', 'auto'); -ga('send', 'pageview'); - -$(document).ready(function() { - - $(".leftMenu").height(window.innerHeight); - $(window).on("resize", function() { $(".leftMenu").height(window.innerHeight); }); - - function showSection(id) { - $(".basic_section").hide(); - $("#" + id).show(); - } - - function showPage(pageUrl) { - $.ajax({ - method: "GET", - url: pageUrl - }).done(function(msg) { - $("#main").html(msg); - $("pre").addClass("prettyprint"); - $(".basic_link").on("click", function(e) { - e.preventDefault(); - var id = $(e.currentTarget).data("id"); - showSection(id); - }); - }); - } - - $(".link").on("click", function(e) { - e.preventDefault(); - var url = $(e.currentTarget).data("url"); - showPage(url); - }); - - showPage("./pages/home.html"); - -}); \ No newline at end of file diff --git a/src/ro/features-and-api/0_symbols_as_id.md b/src/ro/features-and-api/0_symbols_as_id.md new file mode 100644 index 0000000..66b50eb --- /dev/null +++ b/src/ro/features-and-api/0_symbols_as_id.md @@ -0,0 +1,54 @@ +# Support for Symbols + +In very large applications using strings as the identifiers of the types to be injected by the InversifyJS can lead to naming collisions. InversifyJS supports and recommends the usage of [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) instead of string literals. + +::: tip +A symbol is a unique and immutable data type and may be used as an identifier for object properties. The symbol object is an implicit object wrapper for the symbol primitive data type. +::: + +```ts +import { Container, injectable, inject } from 'inversify'; + +let Symbols = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +@injectable() +class Katana implements Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(Symbols.Katana) katana: Katana, @inject(Symbols.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Symbols.Ninja).to(Ninja); +container.bind(Symbols.Katana).to(Katana); +container.bind(Symbols.Shuriken).to(Shuriken); +``` diff --git a/src/ro/features-and-api/10_provider_injection.md b/src/ro/features-and-api/10_provider_injection.md new file mode 100644 index 0000000..0e3c818 --- /dev/null +++ b/src/ro/features-and-api/10_provider_injection.md @@ -0,0 +1,307 @@ +# Injecting a Provider (asynchronous Factory) + +Binds an abstraction to a Provider. A provider is an asynchronous factory, this +is useful when dealing with asynchronous I/O operations. + +```ts +type KatanaProvider = () => Promise; + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public shuriken: Shuriken; + public katanaProvider: KatanaProvider; + + public constructor( + @inject('KatanaProvider') katanaProvider: KatanaProvider, + @inject('Shuriken') shuriken: Shuriken + ) { + this.katanaProvider = katanaProvider; + this.katana = null; + this.shuriken = shuriken; + } + + public fight() { + return this.katana.hit(); + } + public sneak() { + return this.shuriken.throw(); + } +} +``` + +```ts +container.bind('KatanaProvider').toProvider((context) => { + return () => { + return new Promise((resolve) => { + let katana = context.container.get('Katana'); + resolve(katana); + }); + }; +}); + +var ninja = container.get('Ninja'); + +ninja + .katanaProvider() + .then((katana) => { + ninja.katana = katana; + }) + .catch((e) => { + console.log(e); + }); +``` + +## Provider custom arguments + +The `toProvider` binding expects a `ProviderCreator` as its only argument: + +```ts +interface ProviderCreator extends Function { + (context: Context): Provider; +} +``` + +The signature of a provider look as follows: + +```ts +interface Provider extends Function { + (...args: any[]): ((...args: any[]) => Promise) | Promise; +} +``` + +These type signatures allow as to pass custom arguments to a provider: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string, damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string, damage: number) => { + // Custom args! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; +}); + +let katanaProvider = container.get('SwordProvider'); + +katanaProvider('gold', 100).then((powerfulGoldKatana) => { + // Apply all custom args + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +katanaProvider('gold', 10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider partial application + +We can also pass the arguments using partial application: + +```ts +let container = new Container(); + +interface Sword { + material: string; + damage: number; +} + +@injectable() +class Katana implements Sword { + public material: string; + public damage: number; +} + +type SwordProvider = (material: string) => (damage: number) => Promise; + +container.bind('Sword').to(Katana); + +container.bind('SwordProvider').toProvider((context) => { + return (material: string) => { + // Custom arg 1! + return (damage: number) => { + // Custom arg 2! + return new Promise((resolve) => { + setTimeout(() => { + let katana = context.container.get('Sword'); + katana.material = material; + katana.damage = damage; + resolve(katana); + }, 10); + }); + }; + }; +}); + +let katanaProvider = container.get('SwordProvider'); +let goldKatanaProvider = katanaProvider('gold'); // Apply the first custom arg! + +goldKatanaProvider(100).then((powerfulGoldKatana) => { + // Apply the second custom args! + expect(powerfulGoldKatana.material).to.eql('gold'); + expect(powerfulGoldKatana.damage).to.eql(100); +}); + +goldKatanaProvider(10).then((notSoPowerfulGoldKatana) => { + expect(notSoPowerfulGoldKatana.material).to.eql('gold'); + expect(notSoPowerfulGoldKatana.damage).to.eql(10); +}); +``` + +## Provider as a singleton + +A Provider is always injected as a singleton but you can control if the value returned by the +Provider is uses singleton or transient scope: + +```ts +let container = new Container(); + +interface Warrior { + level: number; +} + +@injectable() +class Ninja implements Warrior { + public level: number; + public constructor() { + this.level = 0; + } +} + +type WarriorProvider = (level: number) => Promise; + +container + .bind('Warrior') + .to(Ninja) + .inSingletonScope(); // Value is singleton! + +container.bind('WarriorProvider').toProvider((context) => { + return (increaseLevel: number) => { + return new Promise((resolve) => { + setTimeout(() => { + let warrior = context.container.get('Warrior'); // Get singleton! + warrior.level += increaseLevel; + resolve(warrior); + }, 100); + }); + }; +}); + +let warriorProvider = container.get('WarriorProvider'); + +warriorProvider(10).then((warrior) => { + expect(warrior.level).to.eql(10); +}); + +warriorProvider(10).then((warrior2) => { + expect(warrior.level).to.eql(20); +}); +``` + +## Provider defaults + +The following function can be used as a helper to provide a default value when a provider is rejected: + +```ts +function valueOrDefault(provider: () => Promise, defaultValue: T) { + return new Promise((resolve, reject) => { + provider() + .then((value) => { + resolve(value); + }) + .catch(() => { + resolve(defaultValue); + }); + }); +} +``` + +The following example showcases how to apply the `valueOrDefault` helper: + +```ts +@injectable() +class Ninja { + public level: number; + public rank: string; + public constructor() { + this.level = 0; + this.rank = 'Ninja'; + } + public train(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + this.level += 10; + resolve(this.level); + }, 100); + }); + } +} + +@injectable() +class NinjaMaster { + public rank: string; + public constructor() { + this.rank = 'NinjaMaster'; + } +} + +type NinjaMasterProvider = () => Promise; + +let container = new Container(); + +container + .bind('Ninja') + .to(Ninja) + .inSingletonScope(); +container.bind('NinjaMasterProvider').toProvider((context) => { + return () => { + return new Promise((resolve, reject) => { + let ninja = context.container.get('Ninja'); + ninja.train().then((level) => { + if (level >= 20) { + resolve(new NinjaMaster()); + } else { + reject('Not enough training'); + } + }); + }); + }; +}); + +let ninjaMasterProvider = container.get('NinjaMasterProvider'); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // Using default here because the provider was rejected (the ninja has a level below 20) + expect(ninjaMaster.rank).to.eql('DefaultNinjaMaster'); +}); + +valueOrDefault(ninjaMasterProvider, { rank: 'DefaultNinjaMaster' }).then((ninjaMaster) => { + // A NinjaMaster was provided because the the ninja has a level above 20 + expect(ninjaMaster.rank).to.eql('NinjaMaster'); + done(); +}); +``` diff --git a/src/ro/features-and-api/11_activation_handler.md b/src/ro/features-and-api/11_activation_handler.md new file mode 100644 index 0000000..6be77d2 --- /dev/null +++ b/src/ro/features-and-api/11_activation_handler.md @@ -0,0 +1,67 @@ +# Activation handler + +It is possible to add an activation handler for a type. The activation handler is invoked after a dependency has been resolved and before it is added to a cache (if singleton or request singleton - [see scope](../features-and-api/4_scope)) and injected. The activation handler will not be invoked if the dependency is taken from a cache. The activation handler can be synchronous or asynchronous. + +Activation handlers are useful to keep our dependencies agnostic of the implementation of crosscutting concerns like caching or logging. + +The following example uses a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to intercept one of the methods (`use`) of a dependency (`Katana`). + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + public use() { + console.log('Used Katana!'); + } +} + +interface Ninja { + katana: Katana; +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(@inject('Katana') katana: Katana) { + this.katana = katana; + } +} +``` + +```ts +container.bind('Ninja').to(Ninja); + +container + .bind('Katana') + .to(Katana) + .onActivation((context, katana) => { + let handler = { + apply: function(target, thisArgument, argumentsList) { + console.log(`Starting: ${new Date().getTime()}`); + let result = target.apply(thisArgument, argumentsList); + console.log(`Finished: ${new Date().getTime()}`); + return result; + } + }; + katana.use = new Proxy(katana.use, handler); + return katana; + }); +``` + +```ts +let ninja = container.get(); +ninja.katana.use(); +> Starting: 1457895135761 +> Used Katana! +> Finished: 1457895135762 +``` + +There are multiple ways to provide an activation handler + +- Adding the handler to the container +- Adding the handler to the binding + +When multiple activation handlers are binded to a service identifier, the binding handler is called before any others. Then the container handlers are called, starting at the root container and descending the descendant containers stopping at the container with the binding. diff --git a/src/ro/features-and-api/12_deactivation_handler.md b/src/ro/features-and-api/12_deactivation_handler.md new file mode 100644 index 0000000..9f7bd92 --- /dev/null +++ b/src/ro/features-and-api/12_deactivation_handler.md @@ -0,0 +1,90 @@ +# Deactivation handler + +It is possible to add a deactivation handler for a type binded in singleton scope. The handler can be synchronous or asynchronous. The deactivation handler is invoked before the type is unbinded from the container: + +```ts +@injectable() +class Destroyable {} + +const container = new Container(); +container + .bind('Destroyable') + .toDynamicValue(() => Promise.resolve(new Destroyable())) + .inSingletonScope() + .onDeactivation((destroyable: Destroyable) => { + console.log('Destroyable service is about to be unbinded'); + }); + +await container.get('Destroyable'); + +await container.unbind('Destroyable'); +``` + +It's possible to add a deactivation handler in multiple ways + +- Adding the handler to the container. +- Adding the handler to a binding. +- Adding the handler to the class through the [preDestroy decorator](../features-and-api/26_pre_destroy). + +Handlers added to the container are the first ones to be resolved. Any handler added to a child container is called before the ones added to their parent. Relevant bindings from the container are called next and finally the `preDestroy` method is called. In the example above, relevant bindings are those bindings bound to the unbinded "Destroyable" service identifer. + +The example below demonstrates call order. + +```ts +let roll = 1; +let binding = null; +let klass = null; +let parent = null; +let child = null; + +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + return new Promise((presolve) => { + klass = roll; + roll += 1; + presolve({}); + }); + } +} + +const container = new Container(); +container.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + parent = roll; + roll += 1; + presolve(); + }); +}); + +const childContainer = container.createChild(); +childContainer + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope() + .onDeactivation( + () => + new Promise((presolve) => { + binding = roll; + roll += 1; + presolve(); + }) + ); +childContainer.onDeactivation('Destroyable', () => { + return new Promise((presolve) => { + child = roll; + roll += 1; + presolve(); + }); +}); + +childContainer.get('Destroyable'); +await childContainer.unbindAsync('Destroyable'); + +expect(roll).eql(5); +expect(child).eql(1); +expect(parent).eql(2); +expect(binding).eql(3); +expect(klass).eql(4); +``` diff --git a/src/ro/features-and-api/13_post_construct.md b/src/ro/features-and-api/13_post_construct.md new file mode 100644 index 0000000..ee71af7 --- /dev/null +++ b/src/ro/features-and-api/13_post_construct.md @@ -0,0 +1,66 @@ +# Post Construct Decorator + +It is possible to add a **@postConstruct** decorator for a class method. This decorator +will run after an object is instantiated and before any activation handlers. This +is useful in situations when the constructor has been called but the component has not +yet initialized or in cases you want to perform an initialization logic after the constructor call. + +Its some other cases it gives you a contract that guarantees +that this method will be invoked only once in the lifetime +of the object when used in singleton scope. See the following examples for usage. + +The method can be synchronous or asynchronous. + +```ts +interface Katana { + use: () => void; +} + +@injectable() +class Katana implements Katana { + constructor() { + console.log('Katana is born'); + } + + public use() { + return 'Used Katana!'; + } + + @postConstruct() + public testMethod() { + console.log('Used Katana!'); + } +} +``` + +```ts +container.bind('Katana').to(Katana); +``` + +```ts +let catana = container.get(); +> Katana is born +> Used Katana! +``` + +Note that you cannot use more than one @postConstruct decorators +on the same class. It will throw an error. + +```ts +class Katana { + @postConstruct() + public testMethod1() {/* ... */} + + @postConstruct() + public testMethod2() {/* ... */} + } + +Katana.toString(); +> Error("Cannot apply @postConstruct decorator multiple times in the same class") +``` + +Usage in basic Javascript + +```js +inversify.decorate(inversify.postConstruct(), Katana.prototype, 'testMethod'); +``` diff --git a/src/ro/features-and-api/14_middleware.md b/src/ro/features-and-api/14_middleware.md new file mode 100644 index 0000000..603f664 --- /dev/null +++ b/src/ro/features-and-api/14_middleware.md @@ -0,0 +1,179 @@ +# Middleware + +InversifyJS performs 3 mandatory operations before resolving a dependency: + +- Annotation +- Planning +- Resolution + +In some cases there will be some additional operations: + +- Activation +- Middleware + +If we have configured some Middleware it will be executed at some point before or after the planning, +resolution and activation phases. + +Middleware can be used to implement powerful development tools. This kind of tools will help developers +to identify problems during the development process. + +## Basic middleware + +```ts +import { interfaces, Container } from 'inversify'; + +function logger(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let start = new Date().getTime(); + let result = planAndResolve(args); + let end = new Date().getTime(); + console.log(`wooooo ${end - start}`); + return result; + }; +} + +let container = new Container(); +container.applyMiddleware(logger); +``` + +Now that we have declared a middleware we can create a new Container and use its applyMiddleware +method to apply it: + +```ts +interface Ninja {} + +@injectable() +class Ninja implements Ninja {} + +let container = new Container(); +container.bind('Ninja').to(Ninja); + +container.applyMiddleware(logger); +``` + +The logger middleware will log in console the execution time: + +```ts +let ninja = container.get("Ninja"); + +> 21 +``` + +## Multiple middleware functions + +When multiple middleware functions are applied: + +```ts +container.applyMiddleware(middleware1, middleware2); +``` + +The middleware will be invoked from right to left. +This means that `middleware2` is invoked before `middleware1`. + +## Context interceptor + +In some cases you may want to intercept the resolution plan. + +The default `contextInterceptor` is passed to the middleware as an property of `args`. + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + // args.nextContextInterceptor + // ... + }; +} +``` + +You can extend the default `contextInterceptor` using a function: + +```ts +function middleware1(planAndResolve: interfaces.Next): interfaces.Next { + return (args: interfaces.NextArgs) => { + let nextContextInterceptor = args.contextInterceptor; + args.contextInterceptor = (context: interfaces.Context) => { + console.log(context); + return nextContextInterceptor(context); + }; + return planAndResolve(args); + }; +} +``` + +## Custom metadata reader + +::: warning +Please note that it is not recommended to create your own custom +metadata reader. We have included this feature to allow library / framework creators +to have a higher level of customization but the average user should not use a custom +metadata reader. In general, a custom metadata reader should only be used when +developing a framework in order to provide users with an annotation APIs +less explicit than the default annotation API. + +If you are developing a framework or library and you create a custom metadata reader, +Please remember to provide your framework with support for an alternative for all the +decorators in the default API: ` @injectable, ``@inject `, `@multiInject`, `@tagged`, +`@named`, `@optional`, `@targetName` & `@unmanaged`. +::: + +Middleware allows you to intercept a plan and resolve it but you are not allowed to change the way the annotation phase behaves. + +There is a second extension point that allows you to decide what kind of annotation +system you would like to use. The default annotation system is powered by decorators and +reflect-metadata: + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Katana') katana: Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +You can use a custom metadata reader to implement a custom annotation system. + +For example, you could implement an annotation system based on static properties: + +```ts +class Ninja implements Ninja { + public static constructorInjections = ['Katana', 'Shuriken']; + + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +A custom metadata reader must implement the `interfaces.MetadataReader` interface. + +A full example [can be found in our unit tests](https://github.com/inversify/InversifyJS/blob/master/test/features/metadata_reader.test.ts). + +Once you have a custom metadata reader you will be ready to apply it: + +```ts +let container = new Container(); +container.applyCustomMetadataReader(new StaticPropsMetadataReader()); +``` diff --git a/src/ro/features-and-api/15_multi_injection.md b/src/ro/features-and-api/15_multi_injection.md new file mode 100644 index 0000000..2d0798a --- /dev/null +++ b/src/ro/features-and-api/15_multi_injection.md @@ -0,0 +1,94 @@ +# Multi-injection + +We can use multi-injection When two or more concretions have been bound to the an abstraction. +Notice how an array of `Weapon` is injected into the `Ninja` class via its constructor thanks to the usage of the `@multiInject` decorator: + +```ts +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name = 'Katana'; +} + +@injectable() +class Shuriken implements Weapon { + public name = 'Shuriken'; +} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@multiInject('Weapon') weapons: Weapon[]) { + this.katana = weapons[0]; + this.shuriken = weapons[1]; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon`: + +```ts +container.bind('Ninja').to(Ninja); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); +``` + +## About the spread `...` operator + +In early releases of InversifyJS the spread operator used to fail without throwing any errors. +That was not acceptable and we implemented a fix that allows you to inject arrays using the +spread operator. However it is not recommended because it turns out to be a bit useless. + +You can inject using `@multiInject` and `...` as follows: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) ...args: Bar[][]) { + // args will always contain one unique item the value of that item is a Bar[] + this.bar = args[0]; + } +} +``` + +The main problem is that this requires the type of `args` to be `Bar[][]` +because multiInject will wrap the injections using an array and the spread +operator will do the same. As a result the injection is wrapped by an array +two times. + +We tried to solve this problem but the only way was to generate some additional +metadata using a `@spread()` decorator. + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) @spread() ...args: Bar[]) { + this.bar = args[0]; + } +} +``` + +We discarded this idea because it is better to use decorators when there is not +other way to achieve something. In this case there is a much simpler way to +achieve the desired result. We just need to **use `@multiInject` and avoid using `...`**: + +```ts +@injectable() +class Foo { + public bar: Bar[]; + constructor(@multiInject(BAR) args: Bar[]) { + this.bar = args; + } +} +``` diff --git a/src/ro/features-and-api/16_tagged_bindings.md b/src/ro/features-and-api/16_tagged_bindings.md new file mode 100644 index 0000000..bf39534 --- /dev/null +++ b/src/ro/features-and-api/16_tagged_bindings.md @@ -0,0 +1,48 @@ +# Tagged bindings + +We can use tagged bindings to fix `AMBIGUOUS_MATCH` errors when two or more +concretions have been bound to an abstraction. Notice how the constructor +arguments of the `Ninja` class have been annotated using the `@tagged` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @tagged('canThrow', false) katana: Weapon, + @inject('Weapon') @tagged('canThrow', true) shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetTagged` +constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); +container + .bind(weaponId) + .to(Katana) + .whenTargetTagged('canThrow', false); +container + .bind(weaponId) + .to(Shuriken) + .whenTargetTagged('canThrow', true); +``` diff --git a/src/ro/features-and-api/17_custom_tag_decorators.md b/src/ro/features-and-api/17_custom_tag_decorators.md new file mode 100644 index 0000000..60e4af4 --- /dev/null +++ b/src/ro/features-and-api/17_custom_tag_decorators.md @@ -0,0 +1,18 @@ +# Create your own tag decorators + +Creating your own decorators is really simple: + +```ts +let throwable = tagged('canThrow', true); +let notThrowable = tagged('canThrow', false); + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor(@inject('Weapon') @notThrowable katana: Weapon, @inject('Weapon') @throwable shuriken: Weapon) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/ro/features-and-api/18_named_bindings.md b/src/ro/features-and-api/18_named_bindings.md new file mode 100644 index 0000000..f64595d --- /dev/null +++ b/src/ro/features-and-api/18_named_bindings.md @@ -0,0 +1,48 @@ +# Named bindings + +We can use named bindings to fix `AMBIGUOUS_MATCH` errors when two or more concretions have +been bound to the an abstraction. Notice how the constructor arguments of the `Ninja` class +have been annotated using the `@named` decorator: + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @named('strong') katana: Weapon, + @inject('Weapon') @named('weak') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a `whenTargetNamed` constraint is +added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind('Ninja').to(Ninja); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` diff --git a/src/ro/features-and-api/19_default_targets.md b/src/ro/features-and-api/19_default_targets.md new file mode 100644 index 0000000..48b43b1 --- /dev/null +++ b/src/ro/features-and-api/19_default_targets.md @@ -0,0 +1,104 @@ +# whenTargetIsDefault + +When multiple bindings are available for a given service identifier, we can use +one of the following features to resolve the potential `AMBIGUOUS_MATCH` exception: + +- [Named bindings](../features-and-api/18_named_bindings) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Contextual bindings](../features-and-api/21_contextual_bindings) +- Default targets + +In this section we will explain how to use default targets. + +We can resolve an `AMBIGUOUS_MATCH` exception using a named constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('strong'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('weak'); +``` + +Or a tagged constraint: + +```ts +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('strong', true); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('strong', false); +``` + +The problem with this solution is that we will have to annotate using +the `@named("strong")`/`@named("weak")` or `@tagged("strong", true)`/`@tagged("strong", false)` +every single injection. + +A better solution is to use a default target: + +```ts +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); +``` + +We can use the `whenTargetIsDefault` to indicate which binding should be used as default +to resolve an `AMBIGUOUS_MATCH` exception when no `@named` or `@tagged` annotations +are available. + +```ts +let TYPES = { + Weapon: 'Weapon' +}; + +let TAG = { + throwable: 'throwable' +}; + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken implements Weapon { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +let container = new Container(); +container + .bind(TYPES.Weapon) + .to(Shuriken) + .whenTargetNamed(TAG.throwable); +container + .bind(TYPES.Weapon) + .to(Katana) + .whenTargetIsDefault(); + +let defaultWeapon = container.get(TYPES.Weapon); +let throwableWeapon = container.getNamed(TYPES.Weapon, TAG.throwable); + +expect(defaultWeapon.name).eql('Katana'); +expect(throwableWeapon.name).eql('Shuriken'); +``` diff --git a/src/ro/features-and-api/1_container_api.md b/src/ro/features-and-api/1_container_api.md new file mode 100644 index 0000000..281b540 --- /dev/null +++ b/src/ro/features-and-api/1_container_api.md @@ -0,0 +1,811 @@ +# The Container API + +The InversifyJS container is where dependencies are first configured through bind and, possibly later, reconfigured and removed. The container can be worked on directly in this regard or container modules can be utilized. +You can query the configuration and resolve configured dependencies with resolved and the 'get' methods. +You can react to resolutions with container activation handlers and unbinding with container deactivation handlers. +You can create container hierarchies where container ascendants can supply the dependencies for descendants. +For testing, state can be saved as a snapshot on a stack and later restored. +For advanced control you can apply middleware to intercept the resolution request and the resolved dependency. +You can even provide your own annotation solution. + +## Container Options + +Container options can be passed to the Container constructor and defaults will be provided if you do not or if you do but omit an option. +Options can be changed after construction and will be shared by child containers created from the Container if you do not provide options for them. + +### defaultScope + +The default scope is `transient` when binding to/toSelf/toDynamicValue/toService. +The other types of bindings are `singleton`. + +You can use container options to change the default scope for the bindings that default to `transient` at application level: + +```ts +let container = new Container({ defaultScope: 'Singleton' }); +``` + +For all types of bindings you can change the scope when declaring: + +```ts +container + .bind(TYPES.Warrior) + .to(Ninja) + .inSingletonScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inTransientScope(); +container + .bind(TYPES.Warrior) + .to(Ninja) + .inRequestScope(); +``` + +### autoBindInjectable + +You can use this to activate automatic binding for `@injectable()` decorated classes: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.isBound(Ninja); // returns false +container.get(Ninja); // returns a Ninja +container.isBound(Ninja); // returns true +``` + +Manually defined bindings will take precedence: + +```ts +let container = new Container({ autoBindInjectable: true }); +container.bind(Ninja).to(Samurai); +container.get(Ninja); // returns a Samurai +``` + +### skipBaseClassChecks + +You can use this to skip checking base classes for the @injectable property, which is +especially useful if any of your @injectable classes extend classes that you don't control +(third party classes). By default, this value is `false`. + +```ts +let container = new Container({ skipBaseClassChecks: true }); +``` + +### merge + +```ts +container.merge(a: interfaces.Container, b: interfaces.Container, ...containers: interfaces.Container[]): interfaces.Container +``` + +Creates a new Container containing the bindings ( cloned bindings ) of two or more containers: + +```ts +@injectable() +class Ninja { + public name = 'Ninja'; +} + +@injectable() +class Shuriken { + public name = 'Shuriken'; +} + +let CHINA_EXPANSION_TYPES = { + Ninja: 'Ninja', + Shuriken: 'Shuriken' +}; + +let chinaExpansionContainer = new Container(); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Ninja).to(Ninja); +chinaExpansionContainer.bind(CHINA_EXPANSION_TYPES.Shuriken).to(Shuriken); + +@injectable() +class Samurai { + public name = 'Samurai'; +} + +@injectable() +class Katana { + public name = 'Katana'; +} + +let JAPAN_EXPANSION_TYPES = { + Katana: 'Katana', + Samurai: 'Samurai' +}; + +let japanExpansionContainer = new Container(); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Samurai).to(Samurai); +japanExpansionContainer.bind(JAPAN_EXPANSION_TYPES.Katana).to(Katana); + +let gameContainer = Container.merge(chinaExpansionContainer, japanExpansionContainer); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Ninja).name).to.eql('Ninja'); +expect(gameContainer.get(CHINA_EXPANSION_TYPES.Shuriken).name).to.eql('Shuriken'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Samurai).name).to.eql('Samurai'); +expect(gameContainer.get(JAPAN_EXPANSION_TYPES.Katana).name).to.eql('Katana'); +``` + +### applyCustomMetadataReader + +```ts +container.applyCustomMetadataReader(metadataReader: interfaces.MetadataReader): void +``` + +An advanced feature.... See [middleware](../features-and-api/14_middleware). + +### applyMiddleware + +```ts +container.applyMiddleware(...middleware: interfaces.Middleware[]): void +``` + +An advanced feature that can be used for cross cutting concerns. See [middleware](../features-and-api/14_middleware). + +### bind + +```ts +container.bind\(serviceIdentifier: interfaces.ServiceIdentifier\): interfaces.BindingToSyntax\ +``` + +### createChild + +```ts +container.createChild(containerOptions?: interfaces.ContainerOptions): Container; +``` + +Create a [container hierarchy ](../features-and-api/20_hierarchical_di). If you do not provide options the child receives the options of the parent. + +### get + +```ts +container.get\(serviceIdentifier: interfaces.ServiceIdentifier\): T +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); + +let katana = container.get('Weapon'); +``` + +### getAsync + +```ts +container.getAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Resolves a dependency by its runtime identifier. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +async function buildLevel1(): Level1 { + return new Level1(); +} + +let container = new Container(); +container.bind('Level1').toDynamicValue(() => buildLevel1()); + +let level1 = await container.getAsync('Level1'); // Returns Promise +``` + +### getNamed + +```ts +container.getNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetNamed('chinese'); + +let katana = container.getNamed('Weapon', 'japanese'); +let shuriken = container.getNamed('Weapon', 'chinese'); +``` + +### getNamedAsync + +```ts +container.getNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given named constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetNamed('japanese'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetNamed('chinese'); + +let katana = await container.getNamedAsync('Weapon', 'japanese'); +let shuriken = await container.getNamedAsync('Weapon', 'chinese'); +``` + +### getTagged + +```ts +container.getTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding and the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .to(Katana) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .to(Shuriken) + .whenTargetTagged('faction', 'ninja'); + +let katana = container.getTagged('Weapon', 'faction', 'samurai'); +let shuriken = container.getTagged('Weapon', 'faction', 'ninja'); +``` + +### getTaggedAsync + +```ts +container.getTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves a dependency by its runtime identifier that matches the given tagged constraint. The runtime identifier must be associated with only one binding, otherwise an error is thrown: + +```ts +let container = new Container(); +container + .bind('Weapon') + .toDynamicValue(async () => new Katana()) + .whenTargetTagged('faction', 'samurai'); +container + .bind('Weapon') + .toDynamicValue(async () => new Weapon()) + .whenTargetTagged('faction', 'ninja'); + +let katana = await container.getTaggedAsync('Weapon', 'faction', 'samurai'); +let shuriken = await container.getTaggedAsync('Weapon', 'faction', 'ninja'); +``` + +### getAll + +```ts +container.getAll\(serviceIdentifier: interfaces.ServiceIdentifier\): T[] +``` + +Get all available bindings for a given identifier. All the bindings must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').to(Shuriken); + +let weapons = container.getAll('Weapon'); // returns Weapon[] +``` + +### getAllAsync + +```ts +container.getAllAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +Get all available bindings for a given identifier: + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.bind('Weapon').toDynamicValue(async () => new Shuriken()); + +let weapons = await container.getAllAsync('Weapon'); // returns Promise +``` + +### getAllNamed + +```ts +container.getAllNamed\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetNamed('es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetNamed('es'); + +let fr = container.getAllNamed('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllNamed('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllNamedAsync + +```ts +container.getAllNamedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, named: string | number | symbol): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given named constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetNamed('fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetNamed('fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetNamed('es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetNamed('es'); + +let fr = await container.getAllNamedAsync('Intl', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllNamedAsync('Intl', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTagged + +```ts +container.getAllTagged\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): T[] +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint. All the binding must be synchronously resolved, otherwise an error is thrown: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toConstantValue({ hello: 'bonjour' }) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'au revoir' }) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toConstantValue({ hello: 'hola' }) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toConstantValue({ goodbye: 'adios' }) + .whenTargetTagged('lang', 'es'); + +let fr = container.getAllTagged('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = container.getAllTagged('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### getAllTaggedAsync + +```ts +container.getAllTaggedAsync\(serviceIdentifier: interfaces.ServiceIdentifier\, key: string | number | symbol, value: any): Promise\ +``` + +Resolves all the dependencies by its runtime identifier that matches the given tagged constraint: + +```ts +let container = new Container(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'bonjour' })) + .whenTargetTagged('lang', 'fr'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'au revoir' })) + .whenTargetTagged('lang', 'fr'); + +container + .bind('Intl') + .toDynamicValue(async () => ({ hello: 'hola' })) + .whenTargetTagged('lang', 'es'); +container + .bind('Intl') + .toDynamicValue(async () => ({ goodbye: 'adios' })) + .whenTargetTagged('lang', 'es'); + +let fr = await container.getAllTaggedAsync('Intl', 'lang', 'fr'); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql('bonjour'); +expect(fr[1].goodbye).to.eql('au revoir'); + +let es = await container.getAllTaggedAsync('Intl', 'lang', 'es'); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql('hola'); +expect(es[1].goodbye).to.eql('adios'); +``` + +### isBound + +```ts +container.isBound(serviceIdentifier: interfaces.ServiceIdentifier\): boolean +``` + +You can use the `isBound` method to check if there are registered bindings for a given service identifier. + +```ts +interface Warrior {} +let warriorId = 'Warrior'; +let warriorSymbol = Symbol.for('Warrior'); + +@injectable() +class Ninja implements Warrior {} + +interface Katana {} +let katanaId = 'Katana'; +let katanaSymbol = Symbol.for('Katana'); + +@injectable() +class Katana implements Katana {} + +let container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(warriorId).to(Ninja); +container.bind(warriorSymbol).to(Ninja); + +expect(container.isBound(Ninja)).to.eql(true); +expect(container.isBound(warriorId)).to.eql(true); +expect(container.isBound(warriorSymbol)).to.eql(true); +expect(container.isBound(Katana)).to.eql(false); +expect(container.isBound(katanaId)).to.eql(false); +expect(container.isBound(katanaSymbol)).to.eql(false); +``` + +### isBoundNamed + +```ts +container.isBoundNamed(serviceIdentifier: interfaces.ServiceIdentifier\, named: string): boolean +``` + +You can use the `isBoundNamed` method to check if there are registered bindings for a given service identifier with a given named constraint. + +```ts +const zero = 'Zero'; +const invalidDivisor = 'InvalidDivisor'; +const validDivisor = 'ValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetNamed(invalidDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetNamed(validDivisor); +expect(container.isBoundNamed(zero, invalidDivisor)).to.eql(true); +expect(container.isBoundNamed(zero, validDivisor)).to.eql(true); +``` + +### isBoundTagged + +```ts +container.isBoundTagged(serviceIdentifier: interfaces.ServiceIdentifier\, key: string, value: any): boolean +``` + +You can use the `isBoundTagged` method to check if there are registered bindings for a given service identifier with a given tagged constraint. + +```ts +const zero = 'Zero'; +const isValidDivisor = 'IsValidDivisor'; +let container = new Container(); + +expect(container.isBound(zero)).to.eql(false); +container.bind(zero).toConstantValue(0); +expect(container.isBound(zero)).to.eql(true); + +container.unbindAll(); +expect(container.isBound(zero)).to.eql(false); +container + .bind(zero) + .toConstantValue(0) + .whenTargetTagged(isValidDivisor, false); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(false); + +container + .bind(zero) + .toConstantValue(1) + .whenTargetTagged(isValidDivisor, true); +expect(container.isBoundTagged(zero, isValidDivisor, false)).to.eql(true); +expect(container.isBoundTagged(zero, isValidDivisor, true)).to.eql(true); +``` + +### load + +```ts +container.load(...modules: interfaces.ContainerModule[]): void +``` + +Calls the registration method of each module. See [container modules](../features-and-api/2_container_modules) + +### loadAsync + +```ts +container.loadAsync(...modules: interfaces.AsyncContainerModule[]): Promise\ +``` + +As per load but for asynchronous registration. + +### rebind + +```ts +container.rebind\(serviceIdentifier: interfaces.ServiceIdentifier\): : interfaces.BindingToSyntax\ +``` + +You can use the `rebind` method to replace all the existing bindings for a given `serviceIdentifier`. +The function returns an instance of `BindingToSyntax` which allows to create the replacement binding. + +```ts +let TYPES = { + someType: 'someType' +}; + +let container = new Container(); +container.bind(TYPES.someType).toConstantValue(1); +container.bind(TYPES.someType).toConstantValue(2); + +let values1 = container.getAll(TYPES.someType); +expect(values1[0]).to.eq(1); +expect(values1[1]).to.eq(2); + +container.rebind(TYPES.someType).toConstantValue(3); +let values2 = container.getAll(TYPES.someType); +expect(values2[0]).to.eq(3); +expect(values2[1]).to.eq(undefined); +``` + +### rebindAsync + +```ts +container.rebindAsync\(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\> +``` + +This is an asynchronous version of rebind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### resolve + +```ts +container.resolve\(constructor: interfaces.Newable\): T +``` + +Resolve is like `container.get(serviceIdentifier: ServiceIdentifier)` but it allows users to create an instance even if no bindings have been declared: + +```ts +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Ninja implements Ninja { + public katana: Katana; + public constructor(katana: Katana) { + this.katana = katana; + } + public fight() { + return this.katana.hit(); + } +} + +const container = new Container(); +container.bind(Katana).toSelf(); + +const tryGet = () => container.get(Ninja); +expect(tryGet).to.throw('No matching bindings found for serviceIdentifier: Ninja'); + +const ninja = container.resolve(Ninja); +expect(ninja.fight()).to.eql('cut!'); +``` + +Please note that it only allows to skip declaring a binding for the root element in the dependency graph (composition root). All the sub-dependencies (e.g. `Katana` in the preceding example) will require a binding to be declared. + +### onActivation + +```ts +container.onActivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onActivation: interfaces.BindingActivation\): void +``` + +Adds an activation handler for all dependencies registered with the specified identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onActivation('Weapon', (context: interfaces.Context, katana: Katana): Katana | Promise => { + console.log('katana instance activation!'); + return katana; +}); + +let katana = container.get('Weapon'); +``` + +### onDeactivation + +```ts +container.onDeactivation\(serviceIdentifier: interfaces.ServiceIdentifier\, onDeactivation: interfaces.BindingDeactivation\): void +``` + +Adds a deactivation handler for the dependencie's identifier. + +```ts +let container = new Container(); +container.bind('Weapon').to(Katana); +container.onDeactivation('Weapon', (katana: Katana): void | Promise => { + console.log('katana instance deactivation!'); +}); + +container.unbind('Weapon'); +``` + +### restore + +```ts +container.restore(): void; +``` + +Restore container state to last snapshot. + +### snapshot + +```ts +container.snapshot(): void +``` + +Save the state of the container to be later restored with the restore method. + +### unbind + +```ts +container.unbind(serviceIdentifier: interfaces.ServiceIdentifier\): void +``` + +Remove all bindings binded in this container to the service identifer. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAsync + +```ts +container.unbindAsync(serviceIdentifier: interfaces.ServiceIdentifier\): Promise\ +``` + +This is the asynchronous version of unbind. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unbindAll + +```ts +container.unbindAll(): void +``` + +Remove all bindings binded in this container. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). + +### unbindAllAsync + +```ts +container.unbindAllAsync(): Promise\ +``` + +This is the asynchronous version of unbindAll. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### unload + +```ts +container.unload(...modules: interfaces.ContainerModuleBase[]): void +``` + +Removes bindings and handlers added by the modules. This will result in the [deactivation process](../features-and-api/12_deactivation_handler). +See [container modules](../features-and-api/2_container_modules) + +### unloadAsync + +```ts +container.unloadAsync(...modules: interfaces.ContainerModuleBase[]): Promise\ +``` + +Asynchronous version of unload. If you know deactivation is asynchronous then this should be used. +If you are not sure then use this method ! + +### parent + +```ts +container.parent: Container | null; +``` + +Access the container hierarchy. + +### id + +```ts +container.id: number +``` + +An identifier auto generated to be unique. diff --git a/src/ro/features-and-api/20_hierarchical_di.md b/src/ro/features-and-api/20_hierarchical_di.md new file mode 100644 index 0000000..84a1bcc --- /dev/null +++ b/src/ro/features-and-api/20_hierarchical_di.md @@ -0,0 +1,30 @@ +# Support for hierarchical DI systems + +Some applications use a hierarchical dependency injection (DI) system. +For example, Angular 2.0 applications use its own +[hierarchical DI system](https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html). + +In a hierarchical DI system, a container can have a parent container and multiple containers +can be used in one application. The containers form a hierarchical structure. + +When a container at the bottom of the hierarchical structure requests a dependency, +the container tries to satisfy that dependency with it's own bindings. If the container +lacks bindings, it passes the request up to its parent container. If that container can't +satisfy the request, it passes it along to its parent container. The requests keep +bubbling up until we find an container that can handle the request or run out of container +ancestors. + +```ts +let weaponIdentifier = 'Weapon'; + +@injectable() +class Katana {} + +let parentContainer = new Container(); +parentContainer.bind(weaponIdentifier).to(Katana); + +let childContainer = new Container(); +childContainer.parent = parentContainer; + +expect(childContainer.get(weaponIdentifier)).to.be.instanceOf(Katana); // true +``` diff --git a/src/ro/features-and-api/21_contextual_bindings.md b/src/ro/features-and-api/21_contextual_bindings.md new file mode 100644 index 0000000..f8b9da2 --- /dev/null +++ b/src/ro/features-and-api/21_contextual_bindings.md @@ -0,0 +1,105 @@ +# Contextual bindings & @targetName + +The `@targetName` decorator is used to access the names of the constructor arguments from a +contextual constraint even when the code is compressed. The `constructor(katana, shuriken) { ...` +becomes `constructor(a, b) { ...` after compression but thanks to `@targetName` we can still +refer to the design-time names `katana` and `shuriken` at runtime. + +```ts +interface Weapon {} + +@injectable() +class Katana implements Weapon {} + +@injectable() +class Shuriken implements Weapon {} + +interface Ninja { + katana: Weapon; + shuriken: Weapon; +} + +@injectable() +class Ninja implements Ninja { + public katana: Weapon; + public shuriken: Weapon; + public constructor( + @inject('Weapon') @targetName('katana') katana: Weapon, + @inject('Weapon') @targetName('shuriken') shuriken: Weapon + ) { + this.katana = katana; + this.shuriken = shuriken; + } +} +``` + +We are binding `Katana` and `Shuriken` to `Weapon` but a custom `when` constraint is added to avoid `AMBIGUOUS_MATCH` errors: + +```ts +container.bind(ninjaId).to(Ninja); + +container + .bind('Weapon') + .to(Katana) + .when((request: interfaces.Request) => { + return request.target.name.equals('katana'); + }); + +container + .bind('Weapon') + .to(Shuriken) + .when((request: interfaces.Request) => { + return request.target.name.equals('shuriken'); + }); +``` + +The target fields implement the `IQueryableString` interface to help you to create your custom constraints: + +```ts +interface QueryableString { + startsWith(searchString: string): boolean; + endsWith(searchString: string): boolean; + contains(searchString: string): boolean; + equals(compareString: string): boolean; + value(): string; +} +``` + +We have included some helpers to facilitate the creation of custom constraints: + +```ts +import { Container, traverseAncerstors, taggedConstraint, namedConstraint, typeConstraint } from 'inversify'; + +let whenParentNamedCanThrowConstraint = (request: interfaces.Request) => { + return namedConstraint('canThrow')(request.parentRequest); +}; + +let whenAnyAncestorIsConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, typeConstraint(Ninja)); +}; + +let whenAnyAncestorTaggedConstraint = (request: interfaces.Request) => { + return traverseAncerstors(request, taggedConstraint('canThrow')(true)); +}; +``` + +The InversifyJS fluent syntax for bindings includes some already implemented common contextual constraints: + +```ts +interface BindingWhenSyntax { + when(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenTargetNamed(name: string): interfaces.BindingOnSyntax; + whenTargetTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenInjectedInto(parent: Function | string): interfaces.BindingOnSyntax; + whenParentNamed(name: string): interfaces.BindingOnSyntax; + whenParentTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenNoAncestorIs(ancestor: Function | string): interfaces.BindingOnSyntax; + whenAnyAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenAnyAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenNoAncestorNamed(name: string): interfaces.BindingOnSyntax; + whenNoAncestorTagged(tag: string, value: any): interfaces.BindingOnSyntax; + whenAnyAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; + whenNoAncestorMatches(constraint: (request: interfaces.Request) => boolean): interfaces.BindingOnSyntax; +} +``` diff --git a/src/ro/features-and-api/22_property_injection.md b/src/ro/features-and-api/22_property_injection.md new file mode 100644 index 0000000..46989c0 --- /dev/null +++ b/src/ro/features-and-api/22_property_injection.md @@ -0,0 +1,128 @@ +# Property injection + +InversifyJS supports property injection because sometimes constructor injection is not the best kind of injection pattern. However, you should try to avoid using property injection and prefer constructor injection in most cases. + +> If the class cannot do its job without the dependency, then add it to the constructor. The class needs the new dependency, so you want your change to break things. Also, creating a class that is not fully initialized ("two-step construction") is an anti-pattern (IMHO). If the class can work without the dependency, a setter is fine. + +Source: [http://stackoverflow.com/](http://stackoverflow.com/questions/1503584/dependency-injection-through-constructors-or-property-setters) + +There are two cases in which you may want to use property injection. + +- When we CAN use InversifyJS to create an instance of a class. +- When we CANNOT use InversifyJS to create an instance of a class. + +These cases are quite different an require different implementations of property injection. + +## When we CAN use InversifyJS to create an instance of a class + +If you are working with a library or framework that allows InversifyJS +to create instances of the classes in the application, then you can inject into +a property using the `@inject` decorator: + +```ts +import { injectable, inject, container } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +@injectable() +class Summary { + // ... +} + +@injectable() +class Author { + // ... +} + +@injectable() +class Book { + private _author: Author; + private _summary: Summary; + + @inject('PrintService') + private _printService: PrintService; + + public constructor(@inject('Author') author: Author, @inject('Summary') summary: Summary) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +container.bind('Author').to(Author); +container.bind('Summary').to(Summary); +container.bind('Book').to(Book); + +// Book instance is created by InversifyJS +let book = container.get('Book'); +book.print(); +``` + +Please refer to our [unit tests](https://github.com/inversify/InversifyJS/blob/master/test/annotation/inject.test.ts) for additional examples. + +## When we CANNOT use InversifyJS to create an instance of a class + +InversifyJS has been designed in a way that facilitates its integration with as many +libraries and frameworks as possible. However, many of its features require being able to +create the instances of the classes in an application. + +The problem is that some frameworks take the control over the creation of instances. +For example, React takes control over the creation of instances of a given Component. + +We have developed an utility that allows you to inject into a property even when +InversifyJS has not created its instances: + +```ts +import getDecorators from 'inversify-inject-decorators'; +import { Container, injectable } from 'inversify'; + +@injectable() +class PrintService { + // ... +} + +let container = new Container(); +container.bind('PrintService').to(PrintService); +let { lazyInject } = getDecorators(container); + +class Book { + private _author: string; + private _summary: string; + + @lazyInject('PrintService') + private _printService: PrintService; + + public constructor(author: string, summary: string) { + this._author = author; + this._summary = summary; + } + + public print() { + this._printService.print(this); + } +} + +// Book instance is NOT created by InversifyJS +let book = new Book('Title', 'Summary'); +book.print(); +``` + +The utility module is called `inversify-inject-decorators` +and provides the following decorators: + +- `@lazyInject` for the injection of a property without metadata +- `@lazyInjectNamed` for the injection of a property without named metadata. +- `@lazyInjectTagged` for the injection of a property without tagged metadata. +- `@lazyMultiInject` for multi-injections. + +Please visit the module +[project on GitHub](https://github.com/inversify/inversify-inject-decorators) +to learn more. diff --git a/src/ro/features-and-api/23_circular_dependencies.md b/src/ro/features-and-api/23_circular_dependencies.md new file mode 100644 index 0000000..8164de1 --- /dev/null +++ b/src/ro/features-and-api/23_circular_dependencies.md @@ -0,0 +1,21 @@ +# Circular dependencies + +## Circular dependencies in your modules (ES6, CommonJS, etc.) + +If you have a circular dependency between two modules and you use the `@inject(SomeClass)` annotation. At runtime, one module will be parsed before the other and the decorator could be invoked with `@inject(SomeClass /* SomeClass = undefined*/)`. InversifyJS will throw the following exception: + +> @inject called with undefined this could mean that the class \${name} has a circular dependency problem. You can use a LazyServiceIdentifer to overcome this limitation. + +There are two ways to overcome this limitation: + +- Use a `LazyServiceIdentifer`. The lazy identifier doesn't delay the injection of the dependencies and all dependencies are injected when the class instance is created. However, it does delay the access to the property identifier (solving the module issue). An example of this can be found in [our unit tests](https://github.com/krzkaczor/InversifyJS/blob/a53bf2cbee65803b197998c1df496c3be84731d9/test/inversify.test.ts#L236-L300). + +- Use the `@lazyInject` decorator. This decorator is part of the [`inversify-inject-decorators`](https://github.com/inversify/inversify-inject-decorators) module. The `@lazyInject` decorator delays the injection of the dependencies until they are actually used, this takes place after a class instance has been created. + +## Circular dependencies in the dependency graph (classes) + +InversifyJS is able to identify circular dependencies and will throw an exception to help you to identify the location of the problem if a circular dependency is detected: + +```ts +Error: Circular dependency found: Ninja -> A -> B -> C -> D -> A +``` diff --git a/src/ro/features-and-api/24_inheritance.md b/src/ro/features-and-api/24_inheritance.md new file mode 100644 index 0000000..4a8e908 --- /dev/null +++ b/src/ro/features-and-api/24_inheritance.md @@ -0,0 +1,260 @@ +# Inheritance + +We try to provide developers with useful error feedback like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +This works fine in most cases but it causes some problem when using inheritance. + +For example, the following code snippet throws a misleading error: + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +```ts +@injectable() +class Warrior { + public rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super('master'); + } +} +``` + +In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: + +> A derived class must explicitly declare its constructor. + +> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. + +If you don't follow this rule an exception will be thrown: + +> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. + +The users have a few ways to overcome this limitation available: + +## Use the @unmanaged decorator + +The `@unmanaged()` decorator allow users to flag that an argument will +be manually injected into a base class. We use the word "unmanaged" +because InversifyJS does not have control under user provided values +and it doesn't manage their injection. + +The following code snippet showcases how to apply this decorator: + +```ts +import { Container, injectable, unmanaged } from '../src/inversify'; + +const BaseId = 'Base'; + +@injectable() +class Base { + public prop: string; + public constructor(@unmanaged() arg: string) { + this.prop = arg; + } +} + +@injectable() +class Derived extends Base { + public constructor() { + super('unmanaged-injected-value'); + } +} + +container.bind(BaseId).to(Derived); +let derived = container.get(BaseId); + +derived instanceof Derived2; // true +derived.prop; // "unmanaged-injected-value" +``` + +## Property setter + +You can use the `public`, `protected` or `private` access modifier and a +property setter to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() { + // args count = 0 + this.rank = null; + } +} + +@injectable() +class SamuraiMaster extends Warrior { + public constructor() { + // args count = 0 + super(); + this.rank = 'master'; + } +} +``` + +## Property injection + +We can also use property injection to avoid injecting into the base class: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor() {} // args count = 0 +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + @injectNamed(TYPES.Rank, 'master') + @named('master') + protected rank: string; + + public constructor() { + // args count = 0 + super(); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Inject into the derived class + +If we don't want to avoid injecting into the base class we can +inject into the derived class and then into the base class using +its constructor (super). + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +let TYPES = { Rank: 'Rank' }; + +@injectable() +class SamuraiMaster extends Warrior { + public constructor( + @inject(TYPES.Rank) @named('master') rank: string // args count = 1 + ) { + super(rank); + } +} + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +The following should also work: + +```ts +@injectable() +class Warrior { + protected rank: string; + public constructor(rank: string) { + // args count = 1 + this.rank = rank; + } +} + +interface Weapon { + name: string; +} + +@injectable() +class Katana implements Weapon { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +let TYPES = { + Rank: 'Rank', + Weapon: 'Weapon' +}; + +@injectable() +class SamuraiMaster extends Warrior { + public weapon: Weapon; + public constructor( + @inject(TYPES.Rank) @named('master') rank: string, // args count = 2 + @inject(TYPES.Weapon) weapon: Weapon + ) { + super(rank); + this.weapon = weapon; + } +} + +container.bind(TYPES.Weapon).to(Katana); + +container + .bind(TYPES.Rank) + .toConstantValue('master') + .whenTargetNamed('master'); +``` + +## Skip Base class `@injectable` checks + +Setting the `skipBaseClassChecks` option to `true` for the container will disable all checking of base classes. This means it will be completely up to the developer to ensure that the `super()` constructor is called with the correct arguments and at the correct time. + +```ts +// Not injectable +class UnmanagedBase { + public constructor(public unmanagedDependency: string) {} +} + +@injectable() +class InjectableDerived extends UnmanagedBase { + public constructor() // Any arguments defined here will be injected like normal + { + super("Don't forget me..."); + } +} + +const container = new Container({ skipBaseClassChecks: true }); +container.bind(InjectableDerived).toSelf(); +``` + +This will work, and you'll be able to use your `InjectableDerived` class just like normal, including injecting dependencies from elsewhere in the container through the constructor. The one caveat is that you must make sure your `UnmanagedBase` receives the correct arguments. + +## What can I do when my base class is provided by a third party module? + +In some cases, you may get errors about missing annotations in classes +provided by a third party module like: + +> Error: Missing required @injectable annotation in: SamuraiMaster + +You can overcome this problem using the `decorate` function: + +```ts +import { decorate, injectable } from 'inversify'; +import SomeClass from 'some-module'; + +decorate(injectable(), SomeClass); +return SomeClass; +``` + +Check out the [JS example](https://github.com/inversify/InversifyJS/blob/master/wiki/basic_js_example.md) +page on the wiki for more info. diff --git a/src/ro/features-and-api/25_transitive_bindings.md b/src/ro/features-and-api/25_transitive_bindings.md new file mode 100644 index 0000000..69e2db1 --- /dev/null +++ b/src/ro/features-and-api/25_transitive_bindings.md @@ -0,0 +1,62 @@ +# Transitive bindings + +A transitive type binding allows as to declare a type binding that is resolved by a previously declared type binding. + +A transitive binding can be declared using the `toService` method: + +```ts +@injectable() +class MySqlDatabaseTransactionLog { + public time: number; + public name: string; + public constructor() { + this.time = new Date().getTime(); + this.name = 'MySqlDatabaseTransactionLog'; + } +} + +@injectable() +class DatabaseTransactionLog { + public time: number; + public name: string; +} + +@injectable() +class TransactionLog { + public time: number; + public name: string; +} + +const container = new Container(); +container + .bind(MySqlDatabaseTransactionLog) + .toSelf() + .inSingletonScope(); +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); + +const mySqlDatabaseTransactionLog = container.get(MySqlDatabaseTransactionLog); +const databaseTransactionLog = container.get(DatabaseTransactionLog); +const transactionLog = container.get(TransactionLog); + +expect(mySqlDatabaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(databaseTransactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(transactionLog.name).to.eq('MySqlDatabaseTransactionLog'); +expect(mySqlDatabaseTransactionLog.time).to.eq(databaseTransactionLog.time); +expect(databaseTransactionLog.time).to.eq(transactionLog.time); +``` + +There is also an utility function named `multiBindToService` which allows us to declare multiple transitive bindings in one go. + +For example, instead of writing the following: + +```ts +container.bind(DatabaseTransactionLog).toService(MySqlDatabaseTransactionLog); +container.bind(TransactionLog).toService(DatabaseTransactionLog); +``` + +We can use `multiBindToService` to write the following: + +```ts +multiBindToService(container)(MySqlDatabaseTransactionLog)(DatabaseTransactionLog, TransactionLog); +``` diff --git a/src/ro/features-and-api/26_pre_destroy.md b/src/ro/features-and-api/26_pre_destroy.md new file mode 100644 index 0000000..1a6879e --- /dev/null +++ b/src/ro/features-and-api/26_pre_destroy.md @@ -0,0 +1,23 @@ +# Pre Destroy Decorator + +It is possible to add a **@preDestroy** decorator for a class method. This decorator will run before a service is unbinded for any cached instance. For this reason, only bindings in singleton scope can contain a method with this decorator. + +```ts +@injectable() +class Destroyable { + @preDestroy() + public myPreDestroyMethod() { + console.log('Destroyable is about to be unbinded!'); + } +} + +const container = new Container(); +container + .bind('Destroyable') + .to(Destroyable) + .inSingletonScope(); + +container.get('Destroyable'); + +container.unbindAll(); +``` diff --git a/src/ro/features-and-api/2_container_modules.md b/src/ro/features-and-api/2_container_modules.md new file mode 100644 index 0000000..c5ee011 --- /dev/null +++ b/src/ro/features-and-api/2_container_modules.md @@ -0,0 +1,65 @@ +# Declaring container modules + +Container modules can help you to manage the complexity of your bindings in very large applications. + +The constructor argument for ContainerModule and AsyncContainerModule is a registration callback that is passed functions that behave the same as the methods of the Container class. The registration callback for the AsyncContainerModule is asynchronous. + +When a container module is loaded into a Container the registration callback is invoked. This is the opportunity for the container module to register bindings and handlers. Use the Container load method for ContainerModule instances and the Container loadAsync method for AsyncContainerModule instances. + +When a container module is unloaded from a Container the bindings added by that container will be removed and the [deactivation process](../features-and-api/12_deactivation_handler) will occur for each of them. Container deactivation and [activation handlers](../features-and-api/11_activation_handler) will also be removed. +Use the unloadAsync method to unload when there will be an async deactivation handler or async [pre destroy](../features-and-api/26_pre_destroy) + +## Synchronous container modules + +```ts +let warriors = new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind) => { + bind('Ninja').to(Ninja); +}); + +let weapons = new ContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +container.load(warriors, weapons); +container.unload(warriors); +``` + +## Asynchronous container modules + +```ts +let warriors = new AsyncContainerModule(async (bind: interfaces.Bind, unbind: interfaces.Unbind) => { + const ninja = await getNinja(); + bind('Ninja').toConstantValue(ninja); +}); + +let weapons = new AsyncContainerModule( + ( + bind: interfaces.Bind, + unbind: interfaces.Unbind, + isBound: interfaces.IsBound, + rebind: interfaces.Rebind, + unbindAsync: interfaces.UnbindAsync, + onActivation: interfaces.Container['onActivation'], + onDeactivation: interfaces.Container['onDeactivation'] + ) => { + bind('Katana').to(Katana); + bind('Shuriken').to(Shuriken); + } +); + +let container = new Container(); +await container.loadAsync(warriors, weapons); +container.unload(warriors); +``` diff --git a/src/ro/features-and-api/3_container_snapshots.md b/src/ro/features-and-api/3_container_snapshots.md new file mode 100644 index 0000000..8125b41 --- /dev/null +++ b/src/ro/features-and-api/3_container_snapshots.md @@ -0,0 +1,53 @@ +# Container snapshots + +Declaring container snapshots is a feature that helps you to write unit tests with ease: + +```ts +import { expect } from 'chai'; +import * as sinon from 'sinon'; + +// application container is shared by all unit tests +import container from '../../src/ioc/container'; + +describe('Ninja', () => { + beforeEach(() => { + // create a snapshot so each unit test can modify + // it without breaking other unit tests + container.snapshot(); + }); + + afterEach(() => { + // Restore to last snapshot so each unit test + // takes a clean copy of the application container + container.restore(); + }); + + // each test is executed with a snapshot of the container + + it('Ninja can fight', () => { + let katanaMock = { + hit: () => { + return 'hit with mock'; + } + }; + + container.unbind('Katana'); + container.bind('Katana').toConstantValue(katanaMock); + let ninja = container.get('Ninja'); + expect(ninja.fight()).eql('hit with mock'); + }); + + it('Ninja can sneak', () => { + let shurikenMock = { + throw: () => { + return 'hit with mock'; + } + }; + + container.unbind('Shuriken'); + container.bind('Shuriken').toConstantValue(shurikenMock); + let ninja = container.get('Shuriken'); + expect(ninja.sneak()).eql('hit with mock'); + }); +}); +``` diff --git a/src/ro/features-and-api/4_scope.md b/src/ro/features-and-api/4_scope.md new file mode 100644 index 0000000..2716beb --- /dev/null +++ b/src/ro/features-and-api/4_scope.md @@ -0,0 +1,104 @@ +# Controlling the scope of the dependencies + +InversifyJS uses transient scope by default but you can also use singleton and request scope: + +```ts +container + .bind('Shuriken') + .to(Shuriken) + .inTransientScope(); // Default +container + .bind('Shuriken') + .to(Shuriken) + .inSingletonScope(); +container + .bind('Shuriken') + .to(Shuriken) + .inRequestScope(); +``` + +## About `inSingletonScope` + +There are many available kinds of bindings: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingWhenOnSyntax; + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +In terms of how scope behaves we can group these types of bindings in two main groups: + +- Bindings that will inject an `object` +- Bindings that will inject a `function` + +### Bindings that will inject an `object` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + to(constructor: { new (...args: any[]): T }): BindingInWhenOnSyntax; + toSelf(): BindingInWhenOnSyntax; + toConstantValue(value: T): BindingWhenOnSyntax; + toDynamicValue(func: (context: Context) => T): BindingInWhenOnSyntax; +} +``` + +The `inTransientScope` is used by default and we can select the scope of this types of binding, except for `toConstantValue` which will always use `inSingletonScope`. + +When we invoke `container.get` for the first time and we are using `to`, `toSelf` or `toDynamicValue` the InversifyJS container will try to generate an object instance or value using a constructor or the dynamic value factory. If the scope has been set to `inSingletonScope` the value is cached. The second time we invoke `container.get` for the same resource ID, and if `inSingletonScope` has been selected, InversifyJS will try to get the value from the cache. + +Note that a class can have some dependencies and a dynamic value can access other types via the current context. These dependencies may or may not be a singleton independently of the selected scope of their parent object in their respective composition tree, + +### Bindings that will inject a `function` + +In this group are included the following types of binding: + +```ts +interface BindingToSyntax { + toConstructor(constructor: Newable): BindingWhenOnSyntax; + toFactory(factory: FactoryCreator): BindingWhenOnSyntax; + toFunction(func: T): BindingWhenOnSyntax; + toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; + toProvider(provider: ProviderCreator): BindingWhenOnSyntax; +} +``` + +We cannot select the scope of this types of binding because the value to be injected (a factory `function`) is always a singleton. However, the factory internal implementation may or may not return a singleton. + +For example, the following binding will inject a factory which will always be a singleton. + +```ts +container.bind>('Factory').toAutoFactory('Katana'); +``` + +However, the value returned by the factory may or may not be a singleton: + +```ts +container + .bind('Katana') + .to(Katana) + .inTransientScope(); +// or +container + .bind('Katana') + .to(Katana) + .inSingletonScope(); +``` + +## About `inRequestScope` + +When we use inRequestScope we are using a special kind of singleton. + +- The `inSingletonScope` creates a singleton that will last for the entire life cycle of a type binding. This means that the `inSingletonScope` can be cleared up from memory when we unbind a type binding using `container.unbind`. + +- The `inRequestScope` creates a singleton that will last for the entire life cycle of one call to the `container.get`, `container.getTagged` or `container.getNamed` methods. Each call to one of this methods will resolve a root dependency and all its sub-dependencies. Internally, a dependency graph known as the "resolution plan" is created by InversifyJS. The `inRequestScope` scope will use one single instance for objects that appear multiple times in the resolution plan. This reduces the number of required resolutions and it can be used as a performance optimization in some cases. diff --git a/src/ro/features-and-api/5_optional_dependencies.md b/src/ro/features-and-api/5_optional_dependencies.md new file mode 100644 index 0000000..0304d25 --- /dev/null +++ b/src/ro/features-and-api/5_optional_dependencies.md @@ -0,0 +1,87 @@ +# Optional dependencies + +We can declare an optional dependency using the `@optional()` decorator: + +```ts +@injectable() +class Katana { + public name: string; + public constructor() { + this.name = 'Katana'; + } +} + +@injectable() +class Shuriken { + public name: string; + public constructor() { + this.name = 'Shuriken'; + } +} + +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken // Optional! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} + +let container = new Container(); + +container.bind('Katana').to(Katana); +container.bind('Ninja').to(Ninja); + +let ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken).to.eql(undefined); + +container.bind('Shuriken').to(Shuriken); + +ninja = container.get('Ninja'); +expect(ninja.name).to.eql('Ninja'); +expect(ninja.katana.name).to.eql('Katana'); +expect(ninja.shuriken.name).to.eql('Shuriken'); +``` + +In the example we can see how the first time we resolve `Ninja`, its +property `shuriken` is undefined because no bindings have been declared +for `Shuriken` and the property is annotated with the `@optional()` decorator. + +After declaring a binding for `Shuriken`: + +```ts +container.bind('Shuriken').to(Shuriken); +``` + +All the resolved instances of `Ninja` will contain an instance of `Shuriken`. + +## Default values + +If a dependency is decorated with the `@optional()` decorator, we will be able to to declare +a default value just like you can do in any other TypeScript application: + +```ts +@injectable() +class Ninja { + public name: string; + public katana: Katana; + public shuriken: Shuriken; + public constructor( + @inject('Katana') katana: Katana, + @inject('Shuriken') @optional() shuriken: Shuriken = { name: 'DefaultShuriken' } // Default value! + ) { + this.name = 'Ninja'; + this.katana = katana; + this.shuriken = shuriken; + } +} +``` diff --git a/src/ro/features-and-api/6_value_injection.md b/src/ro/features-and-api/6_value_injection.md new file mode 100644 index 0000000..764b696 --- /dev/null +++ b/src/ro/features-and-api/6_value_injection.md @@ -0,0 +1,19 @@ +# Injecting a constant or dynamic value + +Binds an abstraction to a constant value: + +```ts +container.bind('Katana').toConstantValue(new Katana()); +``` + +Binds an abstraction to a dynamic value: + +```ts +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return new Katana(); +}); +// a dynamic value can return a promise that will resolve to the value +container.bind('Katana').toDynamicValue((context: interfaces.Context) => { + return Promise.resolve(new Katana()); +}); +``` diff --git a/src/ro/features-and-api/7_constructor_injection.md b/src/ro/features-and-api/7_constructor_injection.md new file mode 100644 index 0000000..8f2ef9b --- /dev/null +++ b/src/ro/features-and-api/7_constructor_injection.md @@ -0,0 +1,54 @@ +# Injecting a class constructor + +InversifyJS supports constructor injection to allow passing abstractions or instances of concrete classes +during the creation of the injectable object. + +In case of abstractions (interfaces) you need to use the @inject decorator. This is required because +the metadata of the abstractions are not available during runtime : + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Newable') Katana: interfaces.Newable, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = new Katana(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Newable').toConstructor(Katana); +``` + +In case of concrete injections, you can simply define your constructor parameters as usual without using the @inject decorator. + +InversifyJS also supports TypeScript's constructor assignments so you can have private or protected access modifiers in your parameters +and the container will have no trouble injecting the dependencies : + +```ts +@injectable() +class Ninja implements Ninja { + public constructor(private _dagger: Dagger) {} + + public throwDagger() { + this._dagger.throw(); + } +} +``` + +```ts +container.bind(Dagger).toSelf(); +``` diff --git a/src/ro/features-and-api/8_factory_injection.md b/src/ro/features-and-api/8_factory_injection.md new file mode 100644 index 0000000..da1e16f --- /dev/null +++ b/src/ro/features-and-api/8_factory_injection.md @@ -0,0 +1,79 @@ +# Injecting a Factory + +Binds an abstraction to a user defined Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject('Factory') katanaFactory: () => Katana, @inject('Shuriken') shuriken: Shuriken) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return () => { + return context.container.get('Katana'); + }; +}); +``` + +You can also define a Factory with args: + +```ts +container.bind>('Factory').toFactory((context: interfaces.Context) => { + return (throwable: boolean) => { + if (throwable) { + return context.container.getTagged('Weapon', 'throwable', true); + } else { + return context.container.getTagged('Weapon', 'throwable', false); + } + }; +}); +``` + +Sometimes you might need to pass arguments to a factory in different moments during the execution: + +```ts +container + .bind('Engine') + .to(PetrolEngine) + .whenTargetNamed('petrol'); +container + .bind('Engine') + .to(DieselEngine) + .whenTargetNamed('diesel'); + +container.bind>('Factory').toFactory((context) => { + return (named: string) => (displacement: number) => { + let engine = context.container.getNamed('Engine', named); + engine.displacement = displacement; + return engine; + }; +}); + +@injectable() +class DieselCarFactory implements CarFactory { + private _dieselFactory: (displacement: number) => Engine; + constructor( + @inject('Factory') factory: (category: string) => (displacement: number) => Engine // Injecting an engine factory + ) { + this._dieselFactory = factory('diesel'); // Creating a diesel engine factory + } + public createEngine(displacement: number): Engine { + return this._dieselFactory(displacement); // Creating a concrete diesel engine + } +} +``` diff --git a/src/ro/features-and-api/9_auto_factory.md b/src/ro/features-and-api/9_auto_factory.md new file mode 100644 index 0000000..e152a64 --- /dev/null +++ b/src/ro/features-and-api/9_auto_factory.md @@ -0,0 +1,32 @@ +# Auto factory + +Binds an abstraction to an auto-generated Factory. + +```ts +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor( + @inject('Factory') katanaFactory: interfaces.Factory, + @inject('Shuriken') shuriken: Shuriken + ) { + this._katana = katanaFactory(); + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +```ts +container.bind('Katana').to(Katana); + +container.bind>('Factory').toAutoFactory('Katana'); +``` diff --git a/src/ro/features-and-api/README.md b/src/ro/features-and-api/README.md new file mode 100644 index 0000000..8bd8303 --- /dev/null +++ b/src/ro/features-and-api/README.md @@ -0,0 +1,168 @@ +# Support for classes + +InversifyJS allows your classes to have a direct dependency on other classes. When doing so you will need to use the `@injectable` decorator but you will not be required to use the `@inject` decorator. + +The `@inject` decorator is not required when you use classes. The annotation is not required because the typescript compiler generates the metadata for us. However, this won't happen if you forget one of the following things: + +- Import `reflect-metadata` +- Set `emitDecoratorMetadata` to `true` in `tsconfig.json`. + +```ts +import { Container, injectable, inject } from 'inversify'; + +@injectable() +class Katana { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrion { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(katana: Katana, shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} + +var container = new Container(); +container.bind(Ninja).to(Ninja); +container.bind(Katana).to(Katana); +container.bind(Shuriken).to(Shuriken); +``` + +## Self-binding of concrete types + +If the type you’re resolving is a concrete type the registration of a binding can feel a repetitive and verbose: + +```ts +container.bind(Samurai).to(Samurai); +``` + +A better solution is to use the `toSelf` method: + +```ts +container.bind(Samurai).toSelf(); +``` + +## Known Limitation: Classes as identifiers and circular dependencies + +An exception: + +::: danger +Error: Missing required @Inject or @multiinject annotation in: argument 0 in class Dom. +::: + +Will be thrown if we use classes as identifiers in circular dependencies. For example: + +```ts +import 'reflect-metadata'; +import { Container, injectable } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +let container = new Container(); +let { lazyInject } = getDecorators(container); + +@injectable() +class Dom { + public domUi: DomUi; + constructor(domUi: DomUi) { + this.domUi = domUi; + } +} + +@injectable() +class DomUi { + @lazyInject(Dom) public dom: Dom; +} + +@injectable() +class Test { + constructor(dom: Dom) { + console.log(dom); + } +} + +container + .bind(Dom) + .toSelf() + .inSingletonScope(); +container + .bind(DomUi) + .toSelf() + .inSingletonScope(); +const dom = container.resolve(Test); // Error! +``` + +This error may seem a bit misleading because when using classes as service identifiers `@inject` annotations should not be required and if we do add an annotation like `@inject(Dom)` or `@inject(DomUi)` we will still get the same exception. This happens because, at the point in time in which the decorator is invoked, the class has not been declared so the decorator is invoked as `@inject(undefined)`. This trigger InversifyJS to think that the annotation was never added. + +The solution is to use symbols like `Symbol.for("Dom")` as service identifiers instead of the classes like `Dom`: + +```ts +import 'reflect-metadata'; +import { Container, injectable, inject } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; + +const container = new Container(); +const { lazyInject } = getDecorators(container); + +const TYPE = { + Dom: Symbol.for('Dom'), + DomUi: Symbol.for('DomUi') +}; + +@injectable() +class DomUi { + public dom: Dom; + public name: string; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + this.name = 'DomUi'; + } +} + +@injectable() +class Dom { + public name: string; + @lazyInject(TYPE.DomUi) public domUi: DomUi; + public constructor() { + this.name = 'Dom'; + } +} + +@injectable() +class Test { + public dom: Dom; + constructor(@inject(TYPE.Dom) dom: Dom) { + this.dom = dom; + } +} + +container + .bind(TYPE.Dom) + .to(Dom) + .inSingletonScope(); +container + .bind(TYPE.DomUi) + .to(DomUi) + .inSingletonScope(); + +const test = container.resolve(Test); // Works! +``` diff --git a/src/ro/getting-started/README.md b/src/ro/getting-started/README.md new file mode 100644 index 0000000..0a2a05d --- /dev/null +++ b/src/ro/getting-started/README.md @@ -0,0 +1,142 @@ +# Getting Started + +## Installation + +You can get the latest release and the type definitions using npm: + +```sh +npm install inversify@5.1.1 reflect-metadata --save +``` + +Or using yarn: + +```sh +yarn add inversify@5.1.1 reflect-metadata +``` + +The InversifyJS type definitions are included in the inversify npm package. InversifyJS requires the `experimentalDecorators`, `emitDecoratorMetadata`and `lib` compilation options in your `tsconfig.json` file. + +```js +{ + "compilerOptions": { + "target": "es5", + "lib": ["es6"], + "types": ["reflect-metadata"], + "module": "commonjs", + "moduleResolution": "node", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +InversifyJS requires a modern JavaScript engine with support for: + +- [Reflect metadata](https://github.com/rbuckton/ReflectDecorators/blob/master/spec/metadata.md) +- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) (Only required if using [provider injection](../features-and-api/10_provider_injection)) +- [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) (Only required if using [activation handlers](../features-and-api/11_activation_handler)) + +If your environment don't support one of these you will need to import a shim or polyfill. + +**Check out the [Environment support and polyfills](https://github.com/inversify/InversifyJS/blob/master/wiki/environment.md) +page in the wiki to learn more.** + +## Declaring Interfaces + +Our goal is to write code that adheres to the [dependency inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle). This means that we should "depend upon Abstractions and do not depend upon concretions". Let's start by declaring some interfaces (abstractions). + +```ts +interface Warrior { + fight(): string; + sneak(): string; +} + +interface Weapon { + hit(): string; +} + +interface ThrowableWeapon { + throw(): string; +} +``` + +InversifyJS need to use the type as identifiers at runtime. We use symbols as identifiers but you can also use classes and or string literals. + +```ts +let TYPES = { + Warrior: Symbol('Warrior'), + Weapon: Symbol('Weapon'), + ThrowableWeapon: Symbol('ThrowableWeapon') +}; + +export default TYPES; +``` + +::: tip +**Note:** It is recommended to use Symbols but InversifyJS also support the usage of Classes and string literals (please refer to the features section to learn more). +::: + +## Declaring Classes and Dependencies + +Let's continue by declaring some classes (concretions). The classes are implementations of the interfaces that we just declared. All the classes must be annotated with the `@injectable` decorator. + +When a class has a dependency on an interface we also need to use the @inject decorator to define an identifier for the interface that will be available at runtime. In this case we will use the Symbols `Symbol("Weapon")` and `Symbol("ThrowableWeapon")` as runtime identifiers. + +```ts +import { injectable, inject } from 'inversify'; +import 'reflect-metadata'; +import TYPES from './types'; + +@injectable() +class Katana implements Weapon { + public hit() { + return 'cut!'; + } +} + +@injectable() +class Shuriken implements ThrowableWeapon { + public throw() { + return 'hit!'; + } +} + +@injectable() +class Ninja implements Warrior { + private _katana: Weapon; + private _shuriken: ThrowableWeapon; + + public constructor(@inject(TYPES.Weapon) katana: Weapon, @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} + +export { Ninja, Katana, Shuriken }; +``` + +If you prefer it you can use property injection instead of constructor injection so you don't have to declare the class constructor: + +```ts +@injectable() +class Ninja implements Warrior { + @inject(TYPES.Weapon) private _katana: Weapon; + @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon; + + public fight() { + return this._katana.hit(); + } + + public sneak() { + return this._shuriken.throw(); + } +} +``` diff --git a/src/ro/index.md b/src/ro/index.md new file mode 100644 index 0000000..89de674 --- /dev/null +++ b/src/ro/index.md @@ -0,0 +1,91 @@ +--- +home: true +title: InversifyJS +heroImage: /logo_transparent.svg +heroText: InversifyJS +tagline: A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript. +actionText: Quick Start → +actionLink: /ro/introduction/ +companies: + - link: https://opensource.microsoft.com/ + logo: https://avatars0.githubusercontent.com/u/6154722?s=200&v=4 + + - link: https://code.facebook.com/projects/1021334114569758/nuclide/ + logo: https://avatars2.githubusercontent.com/u/69631?s=200&v=4 + + - link: https://aws.github.io/aws-amplify/ + logo: https://avatars0.githubusercontent.com/u/2232217?s=200&v=4 + + - link: https://www.plainconcepts.com/ + logo: https://avatars0.githubusercontent.com/u/1520648?s=200&v=4 + + - link: https://api.slack.com/ + logo: https://avatars3.githubusercontent.com/u/6962987?s=200&v=4 + + - link: https://www.lonelyplanet.com/ + logo: https://avatars3.githubusercontent.com/u/114767?s=200&v=4 + + - link: https://jincor.com/ + logo: https://avatars0.githubusercontent.com/u/25283328?s=200&v=4 + + - link: https://www.web-computing.de/ + logo: https://avatars1.githubusercontent.com/u/1957282?s=200&v=4 + + - link: https://dcos.io/ + logo: https://avatars1.githubusercontent.com/u/17648048?s=200&v=4 + + - link: https://typefox.io/ + logo: https://avatars0.githubusercontent.com/u/16970371?s=200&v=4 + + - link: https://code4.ro/ + logo: https://avatars0.githubusercontent.com/u/18010308?s=200&v=4 + + - link: http://www.baidu.com/ + logo: https://user-images.githubusercontent.com/10656223/33888109-fae0852e-df43-11e7-97f6-9db543da0bde.png + + - link: https://www.imdada.cn/ + logo: https://avatars2.githubusercontent.com/u/8085382?s=200&v=4 + + - link: https://www.ato.gov.au/ + logo: https://avatars2.githubusercontent.com/u/17041151?s=200&v=4 + + - link: https://www.kaneoh.com/ + logo: https://avatars1.githubusercontent.com/u/14963540?s=200&v=4 + + - link: https://particl.io/ + logo: https://avatars0.githubusercontent.com/u/26021686?s=200&v=4 + + - link: https://slackmap.com/ + logo: https://avatars2.githubusercontent.com/u/24523195?s=200&v=4 + + - link: https://www.go1.com/ + logo: https://avatars3.githubusercontent.com/u/16556899?s=200&v=4 + + - link: http://www.stellwagengroup.com/stellwagen-technology/ + logo: https://avatars3.githubusercontent.com/u/23475730?s=200&v=4 + + - link: https://www.edrlab.org/ + logo: https://avatars1.githubusercontent.com/u/15262567?s=200&v=4 + + - link: https://www.goodgamestudios.com/ + logo: https://avatars1.githubusercontent.com/u/10072104?s=200&v=4 + + - link: https://freshfox.at/ + logo: https://avatars2.githubusercontent.com/u/13613760?s=200&v=4 + + - link: https://schubergphilis.com/ + logo: https://avatars1.githubusercontent.com/u/864482?s=200&v=4 + +features: + - title: Strongly Typed + details: InversifyJS is powered by TypeScript. TypeScript enable JavaScript developers to use highly-productive development tools and practices when developing JavaScript applications. + + - title: Universal + details: InversifyJS compiles to clean, simple JavaScript code which runs on any browser, in Node.js, or in any JavaScript engine that supports ECMAScript 5 (or newer). + + - title: Pluggable + details: Inversifyjs is framework-agnostic and has been designed to in a way that makes possible its integration with popular frameworks and libraries like hapi, express, react or backbone. + +footer: Released under the MIT License +copyright: Copyright © 2015 - present Remo H. Jansen +--- diff --git a/src/ro/introduction/README.md b/src/ro/introduction/README.md new file mode 100644 index 0000000..32c1f75 --- /dev/null +++ b/src/ro/introduction/README.md @@ -0,0 +1,55 @@ +--- +title: Introduction +--- + +# Introduction + +InversifyJS is a lightweight (4KB) inversion of control (IoC) container for TypeScript and JavaScript apps. A IoC container uses a class constructor to identify and inject its dependencies. + +InversifyJS has a friendly API and encourage the usage of the best OOP and IoC practices. + +## Motivation + +JavaScript now supports object oriented (OO) programming with class based inheritance. These features are great but the truth is that they are also dangerous. + +We need a good OO design to protect ourselves from these threats. The problem is that OO design is difficult and that is exactly why we created InversifyJS. + +InversifyJS is a tool that helps JavaScript developers to write code with a good OO design. + +## Philosophy + +InversifyJS has been developed with 4 main goals: + +- Allow JavaScript developers to write code that adheres to the SOLID principles. +- Facilitate and encourage the adherence to the best OOP and IoC practices. +- Add as little runtime overhead as possible. +- Provide a state of the art development experience. + +## Features and API + +InversifyJS is powerful IoC container and supports the following features: + +- [Support for classes](../features-and-api) +- [Support for Symbols](../features-and-api/0_symbols_as_id) +- [Container API](../features-and-api/1_container_api) +- [Declaring container modules](../features-and-api/2_container_modules) +- [Container snapshots](../features-and-api/3_container_snapshots) +- [Controlling the scope of the dependencies](../features-and-api/4_scope) +- [Declaring optional dependencies](../features-and-api/5_optional_dependencies) +- [Injecting a constant or dynamic value](../features-and-api/6_value_injection) +- [Injecting a class constructor](../features-and-api/7_constructor_injection) +- [Injecting a Factory](../features-and-api/8_factory_injection) +- [Auto factory](../features-and-api/9_auto_factory) +- [Injecting a Provider (asynchronous Factory)](../features-and-api/10_provider_injection) +- [Activation handler](../features-and-api/11_activation_handler) +- [Middleware](../features-and-api/12_middleware) +- [Multi-injection](../features-and-api/15_multi_injection) +- [Tagged bindings](../features-and-api/16_tagged_bindings) +- [Create your own tag decorators](../features-and-api/17_custom_tag_decorators) +- [Named bindings](../features-and-api/18_named_bindings) +- [Default target](../features-and-api/19_default_targets) +- [Support for hierarchical DI systems](../features-and-api/20_hierarchical_di) +- [Contextual bindings & @targetName](../features-and-api/21_contextual_bindings) +- [Property injection](../features-and-api/22_property_injection) +- [Circular dependencies](../features-and-api/23_circular_dependencies) +- [Inheritance](../features-and-api/24_inheritance) diff --git a/src/ro/why-inversifyjs/README.md b/src/ro/why-inversifyjs/README.md new file mode 100644 index 0000000..20bec4d --- /dev/null +++ b/src/ro/why-inversifyjs/README.md @@ -0,0 +1,129 @@ +# Why InversifyJS? + +There are many good reasons to use InversifyJS but we would like to highlight some of them: + +## 1. Real decoupling + +InversifyJS offers you real decoupling. Consider the following class: + +```ts +let TYPES = { + Ninja: Symbol.for('Ninja'), + Katana: Symbol.for('Katana'), + Shuriken: Symbol.for('Shuriken') +}; + +export { TYPES }; +``` + +```ts +import { TYPES } from './constants/types'; + +@injectable() +class Ninja implements Ninja { + private _katana: Katana; + private _shuriken: Shuriken; + + public constructor(@inject(TYPES.Katana) katana: Katana, @inject(TYPES.Shuriken) shuriken: Shuriken) { + this._katana = katana; + this._shuriken = shuriken; + } + + public fight() { + return this._katana.hit(); + } + public sneak() { + return this._shuriken.throw(); + } +} +``` + +The `Ninja` class will never point to the `Katana` or `Shuriken` classes. However, +it will point to the interfaces (at design-time) or Symbols (at run-time) which is +admissible because these are abstractions and +[**depending upon abstractions**](https://en.wikipedia.org/wiki/Dependency_inversion_principle) +is what DI is all about. + +The InversifyJS container is the only element in the application aware of the life-cycle and dependencies. +We recommend to do this in a file named `inversify.config.ts` and store the file in the root folder +that contains the application source code: + +```ts +import { TYPES } from './constants/types'; +import { Katana } from './entitites/katana'; +import { Shuriken } from './entitites/shuriken'; +import { Ninja } from './entitites/ninja'; + +container.bind(TYPES.KATANA).to(Katana); +container.bind(TYPES.SHURIKEN).to(Shuriken); +container.bind(TYPES.NINJA).to(Ninja); +``` + +This means that all the coupling in your application takes place in one unique place: the `inversify.config.ts` file. +This is really important and we are going to prove it with an example. +Let's imagine that we are changing the difficulty in a game. +We just need to go to the `inversify.config.ts` and change the Katana binding: + +```ts +import { Katana } from './entitites/SharpKatana'; + +if (difficulty === 'hard') { + container.bind(TYPES.KATANA).to(SharpKatana); +} else { + container.bind(TYPES.KATANA).to(Katana); +} +``` + +You don't need to change the Ninja file! + +The price to pay is the usage of Symbols or string literals but this price can be mitigated if you declare all your +string literals in a file which contains constants +([like actions in Redux](https://github.com/reactjs/redux/blob/master/examples/todomvc/src/constants/ActionTypes.js)). +The good news is that in the future the symbols or string literals +[could end up being generated by the TS compiler](https://github.com/Microsoft/TypeScript/issues/2577), but +that is in the hands of the TC39 committee for the moment. + +## 2. Solves competitors issues + +Some "old" JavaScript IoC container like the angular 1.x `$injector` have some problems: + +![](http://i.imgur.com/Y2lRw4N.png) + +[Source](https://angular.io/docs/ts/latest/guide/dependency-injection.html) + +InversifyJS solves these problems: + +- There is support for transient and singleton scope. +- There are no namespace collisions thanks to tagged, named and contextual bindings. +- It is a stand alone library. + +## 3. All the features that you may need + +As far as I know it is the only IoC container for JavaScript that features complex dependency +resolution (e.g. contextual bindings), multiple scopes (transient, singleton) and many other features. +On top of that there is room for growth with features like interception or web worker scope. +We also have plans for the development of dev-tools like browser extensions and middleware (logging, caching...). + +## 4. Object composition is a pain + +You may think that you don't need an IoC container. + +![](https://raw.githubusercontent.com/inversify/inversify.github.io/master/img/so.png) + +If the [preceding argument](http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code) is not enough you may want to read the following: + +- [The current state of dependency inversion in JavaScript](http://blog.wolksoftware.com/the-current-state-of-dependency-inversion-in-javascript) +- [About object-oriented design and the “class” & “extends” keywords in TypeScript / ES6](http://blog.wolksoftware.com/about-classes-inheritance-and-object-oriented-design-in-typescript-and-es6) + +## 5. Type safety + +The library has been developed using TypeScript so type safety comes out of the box if you work +with TypeScript but it is nice to mention that if you try to inject a Katana into a class that +expects an implementation of `Shuriken` you will get a compilation error. + +## 6. Great development experience + +We are working hard to provide you with a great IoC container for your JavaScript apps but also a great development experience. +We have spend a lot of time trying to make the InversifyJS as user friendly as possible and are working on development tools for chrome and we have already developed a logger middleware to help you to debug in Node.js. + +![](http://inversify.io/img/devtools1.png) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..a36b61a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8261 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" + integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== + +"@babel/core@^7.11.0", "@babel/core@^7.8.4": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" + integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" + integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== + dependencies: + "@babel/types" "^7.14.1" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8", "@babel/helper-compilation-targets@^7.9.6": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== + dependencies: + "@babel/compat-data" "^7.13.15" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.13.11", "@babel/helper-create-class-features-plugin@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c" + integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" + integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1" + integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== + dependencies: + "@babel/types" "^7.13.0" + +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== + dependencies: + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12", "@babel/helper-module-imports@^7.8.3": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" + integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== + +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" + +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + +"@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.12.13", "@babel/parser@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" + integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" + integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + +"@babel/plugin-proposal-async-generator-functions@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" + integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-proposal-class-static-block@^7.13.11": + version "7.13.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.13.11.tgz#6fcbba4a962702c17e5371a0c7b39afde186d703" + integrity sha512-fJTdFI4bfnMjvxJyNuaf8i9mVcZ0UhetaGEUHaHV9KEnibLugJkZAtXikR8KcYj+NYmI4DZMS8yQAyg+hvfSqg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-class-static-block" "^7.12.13" + +"@babel/plugin-proposal-decorators@^7.8.3": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.13.15.tgz#e91ccfef2dc24dd5bd5dcc9fc9e2557c684ecfb8" + integrity sha512-ibAMAqUm97yzi+LPgdr5Nqb9CMkeieGHvwPg1ywSGjZrZHQEGqE01HmOio8kxRpA/+VtOHouIVy2FMpBbtltjA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.11" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-decorators" "^7.12.13" + +"@babel/plugin-proposal-dynamic-import@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" + integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" + integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" + integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" + integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" + integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== + dependencies: + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.13.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" + integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" + integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-proposal-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" + integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" + integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-decorators@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz#fac829bf3c7ef4a1bc916257b403e58c6bdaf648" + integrity sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15" + integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" + integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-syntax-top-level-await@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-arrow-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== + dependencies: + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + +"@babel/plugin-transform-block-scoped-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-block-scoping@^7.14.1": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" + integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-classes@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" + integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-split-export-declaration" "^7.12.13" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-destructuring@^7.13.17": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" + integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-duplicate-keys@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-exponentiation-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-for-of@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-member-expression-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-modules-amd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" + integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== + dependencies: + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== + dependencies: + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.13.12" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== + dependencies: + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-identifier" "^7.12.11" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" + integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== + dependencies: + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + +"@babel/plugin-transform-new-target@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-object-super@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" + +"@babel/plugin-transform-parameters@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" + integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-property-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-regenerator@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-runtime@^7.11.0": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz#2eddf585dd066b84102517e10a577f24f76a9cd7" + integrity sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-plugin-utils" "^7.13.0" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-spread@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + +"@babel/plugin-transform-sticky-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-template-literals@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-typeof-symbol@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-unicode-escapes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-unicode-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/preset-env@^7.11.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.1.tgz#b55914e2e68885ea03f69600b2d3537e54574a93" + integrity sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ== + dependencies: + "@babel/compat-data" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-async-generator-functions" "^7.13.15" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-class-static-block" "^7.13.11" + "@babel/plugin-proposal-dynamic-import" "^7.13.8" + "@babel/plugin-proposal-export-namespace-from" "^7.12.13" + "@babel/plugin-proposal-json-strings" "^7.13.8" + "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" + "@babel/plugin-proposal-numeric-separator" "^7.12.13" + "@babel/plugin-proposal-object-rest-spread" "^7.13.8" + "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-private-methods" "^7.13.0" + "@babel/plugin-proposal-private-property-in-object" "^7.14.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/plugin-syntax-top-level-await" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.13.0" + "@babel/plugin-transform-async-to-generator" "^7.13.0" + "@babel/plugin-transform-block-scoped-functions" "^7.12.13" + "@babel/plugin-transform-block-scoping" "^7.14.1" + "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.17" + "@babel/plugin-transform-dotall-regex" "^7.12.13" + "@babel/plugin-transform-duplicate-keys" "^7.12.13" + "@babel/plugin-transform-exponentiation-operator" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.13.0" + "@babel/plugin-transform-function-name" "^7.12.13" + "@babel/plugin-transform-literals" "^7.12.13" + "@babel/plugin-transform-member-expression-literals" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.14.0" + "@babel/plugin-transform-modules-commonjs" "^7.14.0" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.14.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" + "@babel/plugin-transform-new-target" "^7.12.13" + "@babel/plugin-transform-object-super" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-property-literals" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.13.15" + "@babel/plugin-transform-reserved-words" "^7.12.13" + "@babel/plugin-transform-shorthand-properties" "^7.12.13" + "@babel/plugin-transform-spread" "^7.13.0" + "@babel/plugin-transform-sticky-regex" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.13.0" + "@babel/plugin-transform-typeof-symbol" "^7.12.13" + "@babel/plugin-transform-unicode-escapes" "^7.12.13" + "@babel/plugin-transform-unicode-regex" "^7.12.13" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.14.1" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" + core-js-compat "^3.9.0" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.11.0", "@babel/runtime@^7.8.4": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.0.0", "@babel/template@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" + integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.14.0" + "@babel/types" "^7.14.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.4.4": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" + integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + to-fast-properties "^2.0.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/json-schema@^7.0.5": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + +"@types/minimatch@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== + +"@types/node@*": + version "15.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" + integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== + +"@types/q@^1.5.1": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" + integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== + +"@vue/babel-helper-vue-jsx-merge-props@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81" + integrity sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA== + +"@vue/babel-helper-vue-transform-on@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc" + integrity sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA== + +"@vue/babel-plugin-jsx@^1.0.3": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.6.tgz#184bf3541ab6efdbe5079ab8b20c19e2af100bfb" + integrity sha512-RzYsvBhzKUmY2YG6LoV+W5PnlnkInq0thh1AzCmewwctAgGN6e9UFon6ZrQQV1CO5G5PeME7MqpB+/vvGg0h4g== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + "@vue/babel-helper-vue-transform-on" "^1.0.2" + camelcase "^6.0.0" + html-tags "^3.1.0" + svg-tags "^1.0.0" + +"@vue/babel-plugin-transform-vue-jsx@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz#646046c652c2f0242727f34519d917b064041ed7" + integrity sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + html-tags "^2.0.0" + lodash.kebabcase "^4.1.1" + svg-tags "^1.0.0" + +"@vue/babel-preset-app@^4.1.2": + version "4.5.12" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-4.5.12.tgz#c3a23cf33f6e5ea30536f13c0f9b1fc7e028b1c1" + integrity sha512-8q67ORQ9O0Ms0nlqsXTVhaBefRBaLrzPxOewAZhdcO7onHwcO5/wRdWtHhZgfpCZlhY7NogkU16z3WnorSSkEA== + dependencies: + "@babel/core" "^7.11.0" + "@babel/helper-compilation-targets" "^7.9.6" + "@babel/helper-module-imports" "^7.8.3" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.11.0" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.0" + "@vue/babel-plugin-jsx" "^1.0.3" + "@vue/babel-preset-jsx" "^1.2.4" + babel-plugin-dynamic-import-node "^2.3.3" + core-js "^3.6.5" + core-js-compat "^3.6.5" + semver "^6.1.0" + +"@vue/babel-preset-jsx@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz#92fea79db6f13b01e80d3a0099e2924bdcbe4e87" + integrity sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w== + dependencies: + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + "@vue/babel-sugar-composition-api-inject-h" "^1.2.1" + "@vue/babel-sugar-composition-api-render-instance" "^1.2.4" + "@vue/babel-sugar-functional-vue" "^1.2.2" + "@vue/babel-sugar-inject-h" "^1.2.2" + "@vue/babel-sugar-v-model" "^1.2.3" + "@vue/babel-sugar-v-on" "^1.2.3" + +"@vue/babel-sugar-composition-api-inject-h@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz#05d6e0c432710e37582b2be9a6049b689b6f03eb" + integrity sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-composition-api-render-instance@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz#e4cbc6997c344fac271785ad7a29325c51d68d19" + integrity sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-functional-vue@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz#267a9ac8d787c96edbf03ce3f392c49da9bd2658" + integrity sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-inject-h@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz#d738d3c893367ec8491dcbb669b000919293e3aa" + integrity sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-v-model@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz#fa1f29ba51ebf0aa1a6c35fa66d539bc459a18f2" + integrity sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + html-tags "^2.0.0" + svg-tags "^1.0.0" + +"@vue/babel-sugar-v-on@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz#342367178586a69f392f04bfba32021d02913ada" + integrity sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + +"@vue/component-compiler-utils@^3.1.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz#8f85182ceed28e9b3c75313de669f83166d11e5d" + integrity sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw== + dependencies: + consolidate "^0.15.1" + hash-sum "^1.0.2" + lru-cache "^4.1.2" + merge-source-map "^1.1.0" + postcss "^7.0.14" + postcss-selector-parser "^6.0.2" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + optionalDependencies: + prettier "^1.18.2" + +"@vuepress/core@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/core/-/core-1.8.2.tgz#4f5bafc894691bfea4146294a582a129483daf2a" + integrity sha512-lh9BLC06k9s0wxTuWtCkiNj49fkbW87enp0XSrFZHEoyDGSGndQjZmMMErcHc5Hx7nrW1nzc33sPH1NNtJl0hw== + dependencies: + "@babel/core" "^7.8.4" + "@vue/babel-preset-app" "^4.1.2" + "@vuepress/markdown" "1.8.2" + "@vuepress/markdown-loader" "1.8.2" + "@vuepress/plugin-last-updated" "1.8.2" + "@vuepress/plugin-register-components" "1.8.2" + "@vuepress/shared-utils" "1.8.2" + autoprefixer "^9.5.1" + babel-loader "^8.0.4" + cache-loader "^3.0.0" + chokidar "^2.0.3" + connect-history-api-fallback "^1.5.0" + copy-webpack-plugin "^5.0.2" + core-js "^3.6.4" + cross-spawn "^6.0.5" + css-loader "^2.1.1" + file-loader "^3.0.1" + js-yaml "^3.13.1" + lru-cache "^5.1.1" + mini-css-extract-plugin "0.6.0" + optimize-css-assets-webpack-plugin "^5.0.1" + portfinder "^1.0.13" + postcss-loader "^3.0.0" + postcss-safe-parser "^4.0.1" + toml "^3.0.0" + url-loader "^1.0.1" + vue "^2.6.10" + vue-loader "^15.7.1" + vue-router "^3.4.5" + vue-server-renderer "^2.6.10" + vue-template-compiler "^2.6.10" + vuepress-html-webpack-plugin "^3.2.0" + vuepress-plugin-container "^2.0.2" + webpack "^4.8.1" + webpack-chain "^6.0.0" + webpack-dev-server "^3.5.1" + webpack-merge "^4.1.2" + webpackbar "3.2.0" + +"@vuepress/markdown-loader@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/markdown-loader/-/markdown-loader-1.8.2.tgz#b2a58291a967f2bbe0af6e58f9542f5911879233" + integrity sha512-mWzFXikCUcAN/chpKkqZpRYKdo0312hMv8cBea2hvrJYV6y4ODB066XKvXN8JwOcxuCjxWYJkhWGr+pXq1oTtw== + dependencies: + "@vuepress/markdown" "1.8.2" + loader-utils "^1.1.0" + lru-cache "^5.1.1" + +"@vuepress/markdown@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/markdown/-/markdown-1.8.2.tgz#50ea5a1962591a436b26d1aa2b111df37eb9ea8a" + integrity sha512-zznBHVqW+iBkznF/BO/GY9RFu53khyl0Ey0PnGqvwCJpRLNan6y5EXgYumtjw2GSYn5nDTTALYxtyNBdz64PKg== + dependencies: + "@vuepress/shared-utils" "1.8.2" + markdown-it "^8.4.1" + markdown-it-anchor "^5.0.2" + markdown-it-chain "^1.3.0" + markdown-it-emoji "^1.4.0" + markdown-it-table-of-contents "^0.4.0" + prismjs "^1.13.0" + +"@vuepress/plugin-active-header-links@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.8.2.tgz#0cb9b29c826dd97d35357a9b09c962ef782cb793" + integrity sha512-JmXAQg8D7J8mcKe2Ue3BZ9dOCzJMJXP4Cnkkc/IrqfDg0ET0l96gYWZohCqlvRIWt4f0VPiFAO4FLYrW+hko+g== + dependencies: + lodash.debounce "^4.0.8" + +"@vuepress/plugin-back-to-top@^1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-back-to-top/-/plugin-back-to-top-1.8.2.tgz#e9794409d1d589e4952b0700291270d2696e6d01" + integrity sha512-htAf2m8+6cGmYQexWerznGBY10y1E4TBfebYC3Y3wqNjFjvXUmRKcAG/u6Yxvey4OFkQUxbth2ilKi/GlIW8aQ== + dependencies: + lodash.debounce "^4.0.8" + +"@vuepress/plugin-last-updated@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-last-updated/-/plugin-last-updated-1.8.2.tgz#7ce689f8d5050cf0213949bc2e5aa879c09ff4b1" + integrity sha512-pYIRZi52huO9b6HY3JQNPKNERCLzMHejjBRt9ekdnJ1xhLs4MmRvt37BoXjI/qzvXkYtr7nmGgnKThNBVRTZuA== + dependencies: + cross-spawn "^6.0.5" + +"@vuepress/plugin-medium-zoom@^1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-medium-zoom/-/plugin-medium-zoom-1.8.2.tgz#0243dd27edf0c710f9a41a234d253d76ab51e625" + integrity sha512-Mljso/8E6IbNmIKmwKeC6FDfnhKY3fsOUSs5kEGzz3RQwd54eshqHAMRVwW4LZkYZHhwQXF8+qk7YqoMZB7jjg== + dependencies: + medium-zoom "^1.0.4" + +"@vuepress/plugin-nprogress@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-nprogress/-/plugin-nprogress-1.8.2.tgz#dc6c082925420c8c59ecb7fc2d4a9401f6d4664a" + integrity sha512-3TOBee2NM3WLr1tdjDTGfrAMggjN+OlEPyKyv8FqThsVkDYhw48O3HwqlThp9KX7UbL3ExxIFBwWRFLC+kYrdw== + dependencies: + nprogress "^0.2.0" + +"@vuepress/plugin-register-components@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-register-components/-/plugin-register-components-1.8.2.tgz#2fb45a68b0a1efb8822670d95c3b231a2d0eb74d" + integrity sha512-6SUq3nHFMEh9qKFnjA8QnrNxj0kLs7+Gspq1OBU8vtu0NQmSvLFZVaMV7pzT/9zN2nO5Pld5qhsUJv1g71MrEA== + dependencies: + "@vuepress/shared-utils" "1.8.2" + +"@vuepress/plugin-search@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-search/-/plugin-search-1.8.2.tgz#74b92f663acf6b4560e15dc0442a84c4e874e206" + integrity sha512-JrSJr9o0Kar14lVtZ4wfw39pplxvvMh8vDBD9oW09a+6Zi/4bySPGdcdaqdqGW+OHSiZNvG+6uyfKSBBBqF6PA== + +"@vuepress/shared-utils@1.8.2", "@vuepress/shared-utils@^1.2.0": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/shared-utils/-/shared-utils-1.8.2.tgz#5ec1601f2196aca34ad82eed7c9be2d7948f705b" + integrity sha512-6kGubc7iBDWruEBUU7yR+sQ++SOhMuvKWvWeTZJKRZedthycdzYz7QVpua0FaZSAJm5/dIt8ymU4WQvxTtZgTQ== + dependencies: + chalk "^2.3.2" + escape-html "^1.0.3" + fs-extra "^7.0.1" + globby "^9.2.0" + gray-matter "^4.0.1" + hash-sum "^1.0.2" + semver "^6.0.0" + toml "^3.0.0" + upath "^1.1.0" + +"@vuepress/theme-default@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@vuepress/theme-default/-/theme-default-1.8.2.tgz#7f474036c752c1f9801b83f68f5c70c092b182b4" + integrity sha512-rE7M1rs3n2xp4a/GrweO8EGwqFn3EA5gnFWdVmVIHyr7C1nix+EqjpPQF1SVWNnIrDdQuCw38PqS+oND1K2vYw== + dependencies: + "@vuepress/plugin-active-header-links" "1.8.2" + "@vuepress/plugin-nprogress" "1.8.2" + "@vuepress/plugin-search" "1.8.2" + docsearch.js "^2.5.2" + lodash "^4.17.15" + stylus "^0.54.8" + stylus-loader "^3.0.2" + vuepress-plugin-container "^2.0.2" + vuepress-plugin-smooth-scroll "^0.0.3" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +agentkeepalive@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" + integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +algoliasearch@^3.24.5: + version "3.35.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.35.1.tgz#297d15f534a3507cab2f5dfb996019cac7568f0c" + integrity sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-align@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" + integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + dependencies: + string-width "^3.0.0" + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autocomplete.js@0.36.0: + version "0.36.0" + resolved "https://registry.yarnpkg.com/autocomplete.js/-/autocomplete.js-0.36.0.tgz#94fe775fe64b6cd42e622d076dc7fd26bedd837b" + integrity sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q== + dependencies: + immediate "^3.2.3" + +autoprefixer@^9.5.1: + version "9.8.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + colorette "^1.2.1" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +babel-loader@^8.0.4: + version "8.2.2" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" + integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^1.4.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-polyfill-corejs2@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4" + integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.0" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2" + integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" + core-js-compat "^3.9.1" + +babel-plugin-polyfill-regenerator@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8" + integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.1.1, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +boxen@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" + integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^5.3.1" + chalk "^3.0.0" + cli-boxes "^2.2.0" + string-width "^4.1.0" + term-size "^2.1.0" + type-fest "^0.8.1" + widest-line "^3.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cac@^6.5.6: + version "6.7.3" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.3.tgz#10410b8611677990cc2e3c8b576d471c1d71b768" + integrity sha512-ECVqVZh74qgSuZG9YOt2OJPI3wGcf+EwwuF/XIOYqZBD0KZYLtgPWqFPxmDPQ6joxI1nOlvVgRV6VT53Ooyocg== + +cacache@^12.0.2, cacache@^12.0.3: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-loader@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-3.0.1.tgz#cee6cf4b3cdc7c610905b26bad6c2fc439c821af" + integrity sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^2.1.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^1.0.0" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219: + version "1.0.30001223" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz#39b49ff0bfb3ee3587000d2f66c47addc6e14443" + integrity sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^2.0.3, chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +ci-info@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.1.1.tgz#9a32fcefdf7bcdb6f0a7e1c0f8098ec57897b80a" + integrity sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.x: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +cli-boxes@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + +clipboard@^2.0.0: + version "2.0.8" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba" + integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ== + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.4" + +colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + +connect-history-api-fallback@^1.5.0, connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +consola@^2.6.0: + version "2.15.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" + integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" + integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-webpack-plugin@^5.0.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz#8a889e1dcafa6c91c6cd4be1ad158f1d3823bae2" + integrity sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ== + dependencies: + cacache "^12.0.3" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.1" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + webpack-log "^2.0.0" + +core-js-compat@^3.6.5, core-js-compat@^3.9.0, core-js-compat@^3.9.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.0.tgz#a031e51fe411085e33cb629bfee2acaa53bc309a" + integrity sha512-vvaN8EOvYBEjrr+MN3vCKrMNc/xdYZI+Rt/uPMROi4T5Hj8Fz6TiPQm2mrB9aZoQVW1lCFHYmMrv99aUct9mkg== + dependencies: + browserslist "^4.16.6" + semver "7.0.0" + +core-js@^3.6.4, core-js@^3.6.5: + version "3.12.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.0.tgz#62bac86f7d7f087d40dba3e90a211c2c3c8559ea" + integrity sha512-SaMnchL//WwU2Ot1hhkPflE8gzo7uq1FGvUJ8GKmi3TOU7rGTHIU+eir1WGf6qOtTyxdfdcp10yPdGZ59sQ3hw== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0, cosmiconfig@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-loader@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" + integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== + dependencies: + camelcase "^5.2.0" + icss-utils "^4.1.0" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.14" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^2.0.6" + postcss-modules-scope "^2.1.0" + postcss-modules-values "^2.0.0" + postcss-value-parser "^3.3.0" + schema-utils "^1.0.0" + +css-parse@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" + integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q= + dependencies: + css "^2.0.0" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0, css-select@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" + integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.3" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.11" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99" + integrity sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.8" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.1, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deepmerge@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" + integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" + integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0, dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +docsearch.js@^2.5.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/docsearch.js/-/docsearch.js-2.6.3.tgz#57cb4600d3b6553c677e7cbbe6a734593e38625d" + integrity sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A== + dependencies: + algoliasearch "^3.24.5" + autocomplete.js "0.36.0" + hogan.js "^3.0.2" + request "^2.87.0" + stack-utils "^1.0.1" + to-factory "^1.0.0" + zepto "^1.2.0" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.723: + version "1.3.727" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz#857e310ca00f0b75da4e1db6ff0e073cc4a91ddf" + integrity sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +envify@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" + integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== + dependencies: + esprima "^4.0.0" + through "~2.3.4" + +envinfo@^7.2.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.2, es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^4.1.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +eventsource@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" + integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +faye-websocket@^0.11.3: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-loader@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" + integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.0.tgz#f5d260f95c5f8c105894491feee5dc8993b402fe" + integrity sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg== + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +generate-robotstxt@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/generate-robotstxt/-/generate-robotstxt-7.1.0.tgz#3fe0d9b1ea284533d04a323a29e01bc6cc814f91" + integrity sha512-CA1cT9sX+Q0mDfZmQaigd34dSqzvhLGoiHdC1RnBGCVwpklYRAs/PeQbC5wfYxKhTdQDV0h0DXLA+jXExZe5SA== + dependencies: + cosmiconfig "^5.2.1" + fs-extra "^8.1.0" + ip-regex "^4.1.0" + is-absolute-url "^3.0.0" + meow "^5.0.0" + resolve-from "^5.0.0" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" + integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== + dependencies: + ini "1.3.7" + +global@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= + dependencies: + delegate "^3.1.2" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +gray-matter@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== + dependencies: + js-yaml "^3.13.1" + kind-of "^6.0.2" + section-matter "^1.0.0" + strip-bom-string "^1.0.0" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.x, he@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hogan.js@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/hogan.js/-/hogan.js-3.0.2.tgz#4cd9e1abd4294146e7679e41d7898732b02c7bfd" + integrity sha1-TNnhq9QpQUbnZ55B14mHMrAse/0= + dependencies: + mkdirp "0.3.0" + nopt "1.0.10" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-entities@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" + integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= + +html-tags@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" + integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== + +htmlparser2@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" + integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip-regex@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute-url@^3.0.0, is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-core-module@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" + integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.3.tgz#4c0802ae9c8097939ea8001eaae3c502f3dbe72f" + integrity sha512-tDpEUInNcy2Yw3lNSepK3Wdw1RnXLcIVienz6Ou631Acl15cJyRWK4dgA1vCmOEgIbtOV0W7MHg+AR2Gdg1NXQ== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" + integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== + dependencies: + global-dirs "^2.0.1" + is-path-inside "^3.0.1" + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-npm@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" + integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== + +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-path-inside@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" + integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +javascript-stringify@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3" + integrity sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM= + +javascript-stringify@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +latest-version@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +load-script@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4" + integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ= + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.3, lodash@^4.17.5: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loglevel@^1.6.8: + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.1.2: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^5.0.2: + version "5.3.0" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz#d549acd64856a8ecd1bea58365ef385effbac744" + integrity sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA== + +markdown-it-chain@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz#ccf6fe86c10266bafb4e547380dfd7f277cc17bc" + integrity sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ== + dependencies: + webpack-chain "^4.9.0" + +markdown-it-container@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-2.0.0.tgz#0019b43fd02eefece2f1960a2895fba81a404695" + integrity sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU= + +markdown-it-emoji@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" + integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw= + +markdown-it-table-of-contents@^0.4.0: + version "0.4.4" + resolved "https://registry.yarnpkg.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz#3dc7ce8b8fc17e5981c77cc398d1782319f37fbc" + integrity sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw== + +markdown-it@^8.4.1: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +medium-zoom@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/medium-zoom/-/medium-zoom-1.0.6.tgz#9247f21ca9313d8bbe9420aca153a410df08d027" + integrity sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg== + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + yargs-parser "^10.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +merge2@^1.2.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.47.0, "mime-db@>= 1.43.0 < 2": + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + dependencies: + mime-db "1.47.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.0.3, mime@^2.4.4: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +mini-css-extract-plugin@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz#a3f13372d6fcde912f3ee4cd039665704801e3b9" + integrity sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw== + dependencies: + loader-utils "^1.1.0" + normalize-url "^2.0.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nan@^2.12.1: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + +nopt@1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +nprogress@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.9.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.2.tgz#b6385a3e2b7cae0b5eafcf90cddf85d128767f30" + integrity sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.0, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" + integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +opencollective-postinstall@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" + integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimize-css-assets-webpack-plugin@^5.0.1: + version "5.0.4" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" + integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== + dependencies: + cssnano "^4.1.10" + last-call-webpack-plugin "^3.0.0" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +portfinder@^1.0.13, portfinder@^1.0.26: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-calc@^7.0.1: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" + integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-load-config@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" + integrity sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" + integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-value-parser "^3.3.1" + +postcss-modules-scope@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" + integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^7.0.6" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-safe-parser@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" + integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== + dependencies: + postcss "^7.0.26" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" + integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" + integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" + integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +pretty-error@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== + dependencies: + lodash "^4.17.20" + renderkid "^2.0.4" + +pretty-time@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" + integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== + +prismjs@^1.13.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" + integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA== + optionalDependencies: + clipboard "^2.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +pupa@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0, querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +reduce@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.2.tgz#0cd680ad3ffe0b060e57a5c68bdfce37168d361b" + integrity sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ== + dependencies: + object-keys "^1.1.0" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpu-core@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.6.4: + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.5.tgz#483b1ac59c6601ab30a7a596a5965cabccfdd0a5" + integrity sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ== + dependencies: + css-select "^2.0.2" + dom-converter "^0.2" + htmlparser2 "^3.10.1" + lodash "^4.17.20" + strip-ansi "^3.0.0" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request@^2.87.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.2.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +section-matter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== + dependencies: + extend-shallow "^2.0.1" + kind-of "^6.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= + +selfsigned@^1.10.8: + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== + dependencies: + node-forge "^0.10.0" + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" + integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +smoothscroll-polyfill@^0.4.3: + version "0.4.4" + resolved "https://registry.yarnpkg.com/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz#3a259131dc6930e6ca80003e1cb03b603b69abf8" + integrity sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.1.tgz#256908f6d5adfb94dabbdbd02c66362cca0f9ea6" + integrity sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ== + dependencies: + debug "^3.2.6" + eventsource "^1.0.7" + faye-websocket "^0.11.3" + inherits "^2.0.4" + json3 "^3.3.3" + url-parse "^1.5.1" + +sockjs@^0.3.21: + version "0.3.21" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== + dependencies: + faye-websocket "^0.11.3" + uuid "^3.4.0" + websocket-driver "^0.7.4" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== + dependencies: + figgy-pudding "^3.5.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" + integrity sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ== + dependencies: + escape-string-regexp "^2.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +std-env@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.3.0.tgz#66d4a4a4d5224242ed8e43f5d65cfa9095216eee" + integrity sha512-4qT5B45+Kjef2Z6pE0BkskzsH0GO7GrND0wGlTM1ioUe3v0dGYx9ZJH0Aro/YyA8fqQ5EyIKDRjZojJYMFTflw== + dependencies: + ci-info "^3.0.0" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.0.0, string-width@^4.1.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +stylus-loader@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" + integrity sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA== + dependencies: + loader-utils "^1.0.2" + lodash.clonedeep "^4.5.0" + when "~3.6.x" + +stylus@^0.54.8: + version "0.54.8" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.8.tgz#3da3e65966bc567a7b044bfe0eece653e099d147" + integrity sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg== + dependencies: + css-parse "~2.0.0" + debug "~3.1.0" + glob "^7.1.6" + mkdirp "~1.0.4" + safer-buffer "^2.1.2" + sax "~1.2.4" + semver "^6.3.0" + source-map "^0.7.3" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= + +svgo@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +term-size@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" + integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== + +terser-webpack-plugin@^1.4.3: + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tiny-emitter@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-factory@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-factory/-/to-factory-1.0.0.tgz#8738af8bd97120ad1d4047972ada5563bf9479b1" + integrity sha1-hzivi9lxIK0dQEeXKtpVY7+UebE= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +unbox-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.0, upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-notifier@^4.0.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" + integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== + dependencies: + boxen "^4.2.0" + chalk "^3.0.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.3.1" + is-npm "^4.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.0.0" + pupa "^2.0.1" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-parse@^1.4.3, url-parse@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" + integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +vue-hot-reload-api@^2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" + integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== + +vue-loader@^15.7.1: + version "15.9.6" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.6.tgz#f4bb9ae20c3a8370af3ecf09b8126d38ffdb6b8b" + integrity sha512-j0cqiLzwbeImIC6nVIby2o/ABAWhlppyL/m5oJ67R5MloP0hj/DtFgb0Zmq3J9CG7AJ+AXIvHVnJAPBvrLyuDg== + dependencies: + "@vue/component-compiler-utils" "^3.1.0" + hash-sum "^1.0.2" + loader-utils "^1.1.0" + vue-hot-reload-api "^2.3.0" + vue-style-loader "^4.1.0" + +vue-router@^3.4.5: + version "3.5.1" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.1.tgz#edf3cf4907952d1e0583e079237220c5ff6eb6c9" + integrity sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw== + +vue-server-renderer@^2.6.10: + version "2.6.12" + resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.12.tgz#a8cb9c49439ef205293cb41c35d0d2b0541653a5" + integrity sha512-3LODaOsnQx7iMFTBLjki8xSyOxhCtbZ+nQie0wWY4iOVeEtTg1a3YQAjd82WvKxrWHHTshjvLb7OXMc2/dYuxw== + dependencies: + chalk "^1.1.3" + hash-sum "^1.0.2" + he "^1.1.0" + lodash.template "^4.5.0" + lodash.uniq "^4.5.0" + resolve "^1.2.0" + serialize-javascript "^3.1.0" + source-map "0.5.6" + +vue-style-loader@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35" + integrity sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg== + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-template-compiler@^2.6.10: + version "2.6.12" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e" + integrity sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg== + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== + +vue@^2.6.10: + version "2.6.12" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123" + integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg== + +vuepress-html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz#219be272ad510faa8750d2d4e70fd028bfd1c16e" + integrity sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A== + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + +vuepress-plugin-container@^2.0.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/vuepress-plugin-container/-/vuepress-plugin-container-2.1.5.tgz#37fff05662fedbd63ffd3a5463b2592c7a7f3133" + integrity sha512-TQrDX/v+WHOihj3jpilVnjXu9RcTm6m8tzljNJwYhxnJUW0WWQ0hFLcDTqTBwgKIFdEiSxVOmYE+bJX/sq46MA== + dependencies: + "@vuepress/shared-utils" "^1.2.0" + markdown-it-container "^2.0.0" + +vuepress-plugin-robots@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vuepress-plugin-robots/-/vuepress-plugin-robots-1.0.1.tgz#65a714ed9de61893f02a743cdb5f29d42942a9d8" + integrity sha512-WNZuxuiPKXEbDhFDDu4coKpJrnccmSoqRiVbANmUa1T0Ezw7txsInGH2QnwElws2rSVqda9E19iVzTg6vmU5XA== + dependencies: + generate-robotstxt "^7.1.0" + +vuepress-plugin-seo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/vuepress-plugin-seo/-/vuepress-plugin-seo-0.1.4.tgz#be8e5577491c1fc317a7ad4abe3ae51ff317be1e" + integrity sha512-foNKrAAKihiC47bx0UXFzs/+BIFmnowTQsLVF/8pfsnsPDp8FXjkTGyjxyjOhbwj7ADPv32CdX3pEoYGnZ7OjA== + +vuepress-plugin-smooth-scroll@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz#6eff2d4c186cca917cc9f7df2b0af7de7c8c6438" + integrity sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg== + dependencies: + smoothscroll-polyfill "^0.4.3" + +vuepress@^1.5.3: + version "1.8.2" + resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-1.8.2.tgz#97e8bf979630611fc7b621fc4cc35b798ee5e847" + integrity sha512-BU1lUDwsA3ghf7a9ga4dsf0iTc++Z/l7BR1kUagHWVBHw7HNRgRDfAZBDDQXhllMILVToIxaTifpne9mSi94OA== + dependencies: + "@vuepress/core" "1.8.2" + "@vuepress/theme-default" "1.8.2" + cac "^6.5.6" + envinfo "^7.2.0" + opencollective-postinstall "^2.0.2" + update-notifier "^4.0.0" + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-chain@^4.9.0: + version "4.12.1" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.12.1.tgz#6c8439bbb2ab550952d60e1ea9319141906c02a6" + integrity sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ== + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^1.6.0" + +webpack-chain@^6.0.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206" + integrity sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA== + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^2.0.1" + +webpack-dev-middleware@^3.7.2: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.5.1: + version "3.11.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" + integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.8" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "^0.3.21" + sockjs-client "^1.5.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^4.1.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.8.1: + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +webpackbar@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-3.2.0.tgz#bdaad103fad11a4e612500e72aaae98b08ba493f" + integrity sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw== + dependencies: + ansi-escapes "^4.1.0" + chalk "^2.4.1" + consola "^2.6.0" + figures "^3.0.0" + pretty-time "^1.1.0" + std-env "^2.2.1" + text-table "^0.2.0" + wrap-ansi "^5.1.0" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +when@~3.6.x: + version "3.6.4" + resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" + integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +zepto@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98" + integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g= From 7453730b47726dd200204a9e8a5433b49ff74cfb Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Thu, 6 May 2021 23:09:11 +0200 Subject: [PATCH 02/14] add more pretty warnings/tips --- src/en/features-and-api/24_inheritance.md | 23 ++++++++++++++++------- src/es/features-and-api/24_inheritance.md | 23 ++++++++++++++++------- src/ro/features-and-api/24_inheritance.md | 23 ++++++++++++++++------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/en/features-and-api/24_inheritance.md b/src/en/features-and-api/24_inheritance.md index 4a8e908..3fba42b 100644 --- a/src/en/features-and-api/24_inheritance.md +++ b/src/en/features-and-api/24_inheritance.md @@ -2,13 +2,17 @@ We try to provide developers with useful error feedback like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: This works fine in most cases but it causes some problem when using inheritance. For example, the following code snippet throws a misleading error: -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: danger +Error: The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: ```ts @injectable() @@ -31,13 +35,16 @@ class SamuraiMaster extends Warrior { In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: -> A derived class must explicitly declare its constructor. - -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: tip +A derived class must explicitly declare its constructor. +The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: If you don't follow this rule an exception will be thrown: -> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: danger +Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: The users have a few ways to overcome this limitation available: @@ -244,7 +251,9 @@ This will work, and you'll be able to use your `InjectableDerived` class just li In some cases, you may get errors about missing annotations in classes provided by a third party module like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: You can overcome this problem using the `decorate` function: diff --git a/src/es/features-and-api/24_inheritance.md b/src/es/features-and-api/24_inheritance.md index 4a8e908..615b964 100644 --- a/src/es/features-and-api/24_inheritance.md +++ b/src/es/features-and-api/24_inheritance.md @@ -2,13 +2,17 @@ We try to provide developers with useful error feedback like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: This works fine in most cases but it causes some problem when using inheritance. For example, the following code snippet throws a misleading error: -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: danger +The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: ```ts @injectable() @@ -31,13 +35,16 @@ class SamuraiMaster extends Warrior { In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: -> A derived class must explicitly declare its constructor. - -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: tip +A derived class must explicitly declare its constructor. +The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: If you don't follow this rule an exception will be thrown: -> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: danger +Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: The users have a few ways to overcome this limitation available: @@ -244,7 +251,9 @@ This will work, and you'll be able to use your `InjectableDerived` class just li In some cases, you may get errors about missing annotations in classes provided by a third party module like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: You can overcome this problem using the `decorate` function: diff --git a/src/ro/features-and-api/24_inheritance.md b/src/ro/features-and-api/24_inheritance.md index 4a8e908..36a04be 100644 --- a/src/ro/features-and-api/24_inheritance.md +++ b/src/ro/features-and-api/24_inheritance.md @@ -2,13 +2,17 @@ We try to provide developers with useful error feedback like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: This works fine in most cases but it causes some problem when using inheritance. For example, the following code snippet throws a misleading error: -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: tip +The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: ```ts @injectable() @@ -31,13 +35,16 @@ class SamuraiMaster extends Warrior { In order to overcome this issues InversifyJS restricts the usage of inheritance with two rules: -> A derived class must explicitly declare its constructor. - -> The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: tip +A derived class must explicitly declare its constructor. +The number of constructor arguments in a derived class must be >= than the number of constructor arguments of its base class. +::: If you don't follow this rule an exception will be thrown: -> Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: danger +Error: The number of constructor arguments in the derived class SamuraiMaster must be >= than the number of constructor arguments of its base class. +::: The users have a few ways to overcome this limitation available: @@ -244,7 +251,9 @@ This will work, and you'll be able to use your `InjectableDerived` class just li In some cases, you may get errors about missing annotations in classes provided by a third party module like: -> Error: Missing required @injectable annotation in: SamuraiMaster +::: danger +Error: Missing required @injectable annotation in: SamuraiMaster +::: You can overcome this problem using the `decorate` function: From 50bc6cf555902df3476bbcbd24bb9e2a4afed416 Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Thu, 6 May 2021 23:12:01 +0200 Subject: [PATCH 03/14] fix locales --- src/.vuepress/config.js | 10 ++++++++-- src/.vuepress/locales/es.js | 8 ++++---- src/.vuepress/locales/ro.js | 8 ++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index e3db0fb..45e9302 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -3,6 +3,8 @@ const { defaultNavbar } = require('./defaults/navbar'); // Locale Imports const { enLocale, enMenus } = require('./locales/en'); +const { roLocale, roMenus } = require('./locales/ro'); +const { esLocale, esMenus } = require('./locales/es'); const BASE_URL = 'https://inversify.leonard.sh/'; @@ -80,7 +82,9 @@ module.exports = { title: title, description: desc, locales: { - ...enLocale + ...enLocale, + ...roLocale, + ...esLocale }, head: meta, themeConfig: { @@ -91,7 +95,9 @@ module.exports = { smoothScroll: true, logo: '/logo.png', locales: { - ...enMenus + ...enMenus, + ...roMenus, + ...esMenus }, nav: [...defaultNavbar] }, diff --git a/src/.vuepress/locales/es.js b/src/.vuepress/locales/es.js index 1eef947..693f8d0 100644 --- a/src/.vuepress/locales/es.js +++ b/src/.vuepress/locales/es.js @@ -5,7 +5,7 @@ const language = 'es'; const languageUpper = 'ES'; const languageName = 'Español'; -const enLocale = { +const esLocale = { [`/${language}/`]: { lang: `${language}-${languageUpper}`, title: `Documentación | ${languageName}` @@ -38,7 +38,7 @@ const sidebar = [ } ]; -const enMenus = { +const esMenus = { [`/${language}/`]: { label: languageName, nav: [...defaultNavbar], @@ -51,6 +51,6 @@ const enMenus = { }; module.exports = { - enLocale, - enMenus + esLocale, + esMenus }; diff --git a/src/.vuepress/locales/ro.js b/src/.vuepress/locales/ro.js index 18ad39e..67f7c09 100644 --- a/src/.vuepress/locales/ro.js +++ b/src/.vuepress/locales/ro.js @@ -5,7 +5,7 @@ const language = 'ro'; const languageUpper = 'ro'; const languageName = 'Română'; -const enLocale = { +const roLocale = { [`/${language}/`]: { lang: `${language}-${languageUpper}`, title: `Documentație | ${languageName}` @@ -38,7 +38,7 @@ const sidebar = [ } ]; -const enMenus = { +const roMenus = { [`/${language}/`]: { label: languageName, nav: [...defaultNavbar], @@ -51,6 +51,6 @@ const enMenus = { }; module.exports = { - enLocale, - enMenus + roLocale, + roMenus }; From 7633deccd4994cf9b82a513373a8b4020b8a49cf Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Fri, 7 May 2021 13:30:50 +0200 Subject: [PATCH 04/14] fix navbar languages --- src/.vuepress/theme/components/NavLink.vue | 135 +++++----- src/.vuepress/theme/components/NavLinks.vue | 262 +++++++++----------- 2 files changed, 178 insertions(+), 219 deletions(-) diff --git a/src/.vuepress/theme/components/NavLink.vue b/src/.vuepress/theme/components/NavLink.vue index f7e65a4..a690015 100644 --- a/src/.vuepress/theme/components/NavLink.vue +++ b/src/.vuepress/theme/components/NavLink.vue @@ -1,90 +1,77 @@ diff --git a/src/.vuepress/theme/components/NavLinks.vue b/src/.vuepress/theme/components/NavLinks.vue index 2656ae2..0356425 100644 --- a/src/.vuepress/theme/components/NavLinks.vue +++ b/src/.vuepress/theme/components/NavLinks.vue @@ -1,156 +1,128 @@ + + From fb4c65fe9a893f4076c2a1e005365e717be9488e Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Fri, 7 May 2021 13:31:06 +0200 Subject: [PATCH 05/14] complete package.json --- package.json | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index f1b6034..b70d203 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,29 @@ { "name": "inversify.github.io", - "version": "0.0.1", - "description": "", - "main": "index.js", - "authors": { - "name": "", - "email": "" + "version": "1.0.0", + "description": "InversifyJS official website", + "main": "index.html", + "homepage": "inversify.io", + "keywords": [ + "IoC", + "inversify", + "inversion", + "control", + "typescript", + "javascript", + "dependency", + "injection" + ], + "author": "remojansen ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/inversify/inversify.github.io.git" }, - "repository": "/inversify.github.io", "scripts": { "dev": "vuepress dev src", "build": "vuepress build src" }, - "license": "MIT", "devDependencies": { "@vuepress/plugin-back-to-top": "^1.8.2", "@vuepress/plugin-medium-zoom": "^1.8.2", From d80b7f2051af4b6a042135b73c9fce358cf57aea Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Fri, 7 May 2021 13:31:19 +0200 Subject: [PATCH 06/14] add CNAME and ISSUE_TEMPLATE --- CNAME | 1 + ISSUE_TEMPLATE.md | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 CNAME create mode 100644 ISSUE_TEMPLATE.md diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..11b6ad4 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +inversify.io \ No newline at end of file diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..c7b708f --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ +PLEASE DO NOT REPORT THE ISSUE HERE! + +PLEASE USE THE INVERSIFYJS REPO INSTEAD YOU CAN FIND THE REPO AT: + +https://github.com/inversify/InversifyJS/issues + +YOU CAN ALSO FIND US ON GITTER AT: + +https://gitter.im/inversify/InversifyJS + +THANKS! From ef65457f83a160c1b006029429903395c68272f6 Mon Sep 17 00:00:00 2001 From: LeonardSSH Date: Fri, 7 May 2021 13:53:56 +0200 Subject: [PATCH 07/14] add testimonies --- src/.vuepress/theme/components/Home.vue | 34 +++++++++++++++++++++++++ src/en/index.md | 13 ++++++++++ src/es/index.md | 13 ++++++++++ src/index.md | 13 ++++++++++ src/ro/index.md | 13 ++++++++++ 5 files changed, 86 insertions(+) diff --git a/src/.vuepress/theme/components/Home.vue b/src/.vuepress/theme/components/Home.vue index 9e2b225..b982fb6 100644 --- a/src/.vuepress/theme/components/Home.vue +++ b/src/.vuepress/theme/components/Home.vue @@ -37,6 +37,26 @@ +
+

Testimonies

+ +
+
+
+
+

+ + {{ testimony.author }} + + + - Author of {{ testimony.author_of_name }} +

+
"{{ testimony.text }}"
+
+
+
+
+