diff --git a/.codeclimate.yml b/.codeclimate.yml index ff5e07ebb3..86283d1ccb 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -2,9 +2,9 @@ version: "2" plugins: rubocop: enabled: true - channel: "rubocop-0-76" + channel: "rubocop-1-12" config: - file: ".rubocop_styleguide.yml" + file: ".rubocop.yml" scss-lint: enabled: true checks: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 867205b8e4..0059ce138d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,8 +8,53 @@ on: env: DISABLE_KNAPSACK: true TIMEZONE: UTC + COVERAGE: true jobs: + test-controllers-and-serializers: + runs-on: ubuntu-18.04 + services: + postgres: + image: postgres:10 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_DB: open_food_network_test + POSTGRES_USER: ofn + POSTGRES_PASSWORD: f00d + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + + - uses: actions/setup-node@v2 + with: + node-version: '14.15.5' + + - name: Install JS dependencies + run: yarn install --frozen-lockfile + + - name: Set up application.yml + run: cp config/application.yml.example config/application.yml + + - name: Set up database + run: | + bundle exec rake db:create RAILS_ENV=test + bundle exec rake db:schema:load RAILS_ENV=test + + - name: Run controller tests + run: bundle exec rspec --profile -- spec/controllers spec/serializers + + - name: Codecov + uses: codecov/codecov-action@v1.3.1 + test-models: runs-on: ubuntu-18.04 services: @@ -49,9 +94,12 @@ jobs: bundle exec rake db:schema:load RAILS_ENV=test - name: Run tests - run: bundle exec rspec spec/models + run: bundle exec rspec --profile -- spec/models - test-admin-features: + - name: Codecov + uses: codecov/codecov-action@v1.3.1 + + test-admin-features-1: runs-on: ubuntu-18.04 services: postgres: @@ -90,9 +138,12 @@ jobs: bundle exec rake db:schema:load RAILS_ENV=test - name: Run admin feature tests - run: bundle exec rspec --profile -- spec/features/admin/*_spec.rb + run: bundle exec rspec --profile -- spec/features/admin/[a-o0-9]*_spec.rb - test-admin-features-folders: + - name: Codecov + uses: codecov/codecov-action@v1.3.1 + + test-admin-features-2: runs-on: ubuntu-18.04 services: postgres: @@ -131,7 +182,10 @@ jobs: bundle exec rake db:schema:load RAILS_ENV=test - name: Run admin feature tests - run: bundle exec rspec --profile --pattern "spec/features/admin/*/*_spec.rb" + run: bundle exec rspec --profile -- spec/features/admin/[p-z]*_spec.rb + + - name: Codecov + uses: codecov/codecov-action@v1.3.1 test-consumer-features: runs-on: ubuntu-18.04 @@ -174,48 +228,10 @@ jobs: - name: Run consumer feature tests run: bundle exec rspec --profile -- spec/features/consumer - test-controllers: - runs-on: ubuntu-18.04 - services: - postgres: - image: postgres:10 - ports: ["5432:5432"] - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - env: - POSTGRES_DB: open_food_network_test - POSTGRES_USER: ofn - POSTGRES_PASSWORD: f00d - steps: - - uses: actions/checkout@v2 + - name: Codecov + uses: codecov/codecov-action@v1.3.1 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - - uses: actions/setup-node@v2 - with: - node-version: '14.15.5' - - - name: Install JS dependencies - run: yarn install --frozen-lockfile - - - name: Set up application.yml - run: cp config/application.yml.example config/application.yml - - - name: Set up database - run: | - bundle exec rake db:create RAILS_ENV=test - bundle exec rake db:schema:load RAILS_ENV=test - - - name: Run tests - run: bundle exec rspec spec/controllers - - test-other: + test-engines-etc: runs-on: ubuntu-18.04 services: postgres: @@ -256,20 +272,54 @@ jobs: - name: Run JS tests run: RAILS_ENV=test bundle exec rake karma:run - - name: Run all other tests - run: | - bundle exec rspec \ - spec/helpers/ \ - spec/initializers/ \ - spec/jobs/ \ - spec/lib/ \ - spec/mailers/ \ - spec/queries/ \ - spec/requests/ \ - spec/serializers/ \ - spec/services/ \ - spec/validators/ \ - spec/views + # Migration tests need to be run in a separate task. + # See: https://github.com/openfoodfoundation/openfoodnetwork/pull/6924#issuecomment-813056525 + - name: Run migration tests + run: bundle exec rspec --pattern "spec/{migrations}/**/*_spec.rb" - - name: Run engines tests - run: bundle exec rake ofn:specs:engines:rspec + - name: Run all other tests + run: bundle exec rake ofn:specs:run:excluding_folders["models,controllers,serializers,features,lib,migrations"] + + test-the-rest: + runs-on: ubuntu-18.04 + services: + postgres: + image: postgres:10 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_DB: open_food_network_test + POSTGRES_USER: ofn + POSTGRES_PASSWORD: f00d + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + + - uses: actions/setup-node@v2 + with: + node-version: '14.15.5' + + - name: Install JS dependencies + run: yarn install --frozen-lockfile + + - name: Set up application.yml + run: cp config/application.yml.example config/application.yml + + - name: Set up database + run: | + bundle exec rake db:create RAILS_ENV=test + bundle exec rake db:schema:load RAILS_ENV=test + + - name: Run admin feature folders, engines, lib + run: bundle exec rspec --profile --pattern "engines/*/spec/{,/*/**}/*_spec.rb,spec/features/admin/*/*_spec.rb,spec/lib/{,/*/**}/*_spec.rb" + + - name: Codecov + uses: codecov/codecov-action@v1.3.1 diff --git a/.gitignore b/.gitignore index 8c3ebf892c..a2d30566f9 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ coverage /reports/ !/reports/README.md bin/ +/spec/components/stories/**/*.stories.json diff --git a/.rubocop.yml b/.rubocop.yml index b2ddd900b3..f779f8efde 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,8 +10,8 @@ inherit_from: # The automatically generated todo list to ignore all current violations. - .rubocop_todo.yml - # Our Open Food Network style guide. It's used by Code Climate. If you want to see all violations, - # then use only that configuration (like Code Climate): + # Our Open Food Network style guide. If you want to see all violations, + # then use only that configuration: # # bundle exec rubocop -c .rubocop_styleguide.yml # diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 934e12057c..db05464b57 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -21,6 +21,25 @@ Layout/LineLength: Max: 100 Exclude: + - app/controllers/spree/admin/products_controller.rb + - app/controllers/spree/admin/reports_controller.rb + - app/controllers/spree/paypal_controller.rb + - engines/order_management/spec/services/order_management/order/stripe_sca_payment_authorize_spec.rb + - engines/order_management/spec/services/order_management/order/updater_spec.rb + - engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb + - lib/open_food_network/reports/line_items.rb + - spec/controllers/spree/admin/orders/invoices_spec.rb + - spec/controllers/spree/admin/tax_rates_controller_spec.rb + - spec/controllers/user_passwords_controller_spec.rb + - spec/features/admin/configuration/general_settings_spec.rb + - spec/features/consumer/shopping/unit_price_spec.rb + - spec/helpers/admin/orders_helper_spec.rb + - spec/lib/open_food_network/order_cycle_management_report_spec.rb + - spec/lib/stripe/authorize_response_patcher_spec.rb + - spec/services/bulk_invoice_service_spec.rb + - spec/services/content_sanitizer_spec.rb + - spec/services/process_payment_intent_spec.rb + - spec/support/features/datepicker_helper.rb - app/controllers/admin/bulk_line_items_controller.rb - app/controllers/admin/contents_controller.rb - app/controllers/admin/customers_controller.rb @@ -230,7 +249,6 @@ Layout/LineLength: - spec/lib/open_food_network/products_and_inventory_report_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - - spec/lib/open_food_network/user_balance_calculator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb - spec/lib/open_food_network/xero_invoices_report_spec.rb - spec/lib/spree/core/calculated_adjustments_spec.rb @@ -329,6 +347,29 @@ Layout/LineLength: Metrics/AbcSize: Max: 15 Exclude: + - app/controllers/admin/schedules_controller.rb + - app/controllers/checkout_controller.rb + - app/controllers/spree/admin/general_settings_controller.rb + - app/controllers/spree/admin/images_controller.rb + - app/controllers/spree/admin/mail_methods_controller.rb + - app/controllers/spree/admin/shipping_methods_controller.rb + - app/controllers/spree/paypal_controller.rb + - app/helpers/spree/base_helper.rb + - app/jobs/subscription_placement_job.rb + - app/models/order_cycle.rb + - app/models/product_import/unit_converter.rb + - app/models/spree/gateway/pay_pal_express.rb + - app/serializers/api/admin/enterprise_serializer.rb + - app/services/order_factory.rb + - app/services/variants_stock_levels.rb + - engines/order_management/app/services/order_management/subscriptions/form.rb + - lib/open_food_network/enterprise_fee_calculator.rb + - lib/open_food_network/order_grouper.rb + - lib/spree/core/controller_helpers/auth.rb + - lib/spree/core/controller_helpers/common.rb + - lib/spree/core/product_duplicator.rb + - lib/stripe/authorize_response_patcher.rb + - lib/stripe/profile_storer.rb - app/controllers/admin/bulk_line_items_controller.rb - app/controllers/admin/customers_controller.rb - app/controllers/admin/enterprise_fees_controller.rb @@ -468,7 +509,7 @@ Metrics/AbcSize: Metrics/BlockLength: Max: 25 - ExcludedMethods: [ + IgnoredMethods: [ "class_eval", "collection", "context", @@ -482,6 +523,8 @@ Metrics/BlockLength: "scenario" ] Exclude: + - spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb + - spec/features/admin/tag_rules_spec.rb - app/models/spree/order/checkout.rb - app/models/spree/payment/processing.rb - app/models/spree/shipment.rb @@ -514,6 +557,27 @@ Metrics/BlockLength: Metrics/CyclomaticComplexity: Max: 6 Exclude: + - app/controllers/admin/resource_controller.rb + - app/controllers/spree/admin/payment_methods_controller.rb + - app/controllers/spree/admin/payments_controller.rb + - app/controllers/spree/admin/products_controller.rb + - app/controllers/spree/admin/users_controller.rb + - app/models/product_import/entry_validator.rb + - app/models/spree/order_inventory.rb + - app/models/spree/order.rb + - app/models/spree/shipment.rb + - app/models/spree/tax_rate.rb + - app/models/spree/variant.rb + - engines/order_management/app/services/order_management/reports/enterprise_fee_summary/parameters.rb + - lib/active_merchant/billing/gateways/stripe_decorator.rb + - lib/open_food_network/group_buy_report.rb + - lib/open_food_network/order_cycle_form_applicator.rb + - lib/open_food_network/order_cycle_permissions.rb + - lib/open_food_network/payments_report.rb + - lib/spree/core/controller_helpers/common.rb + - lib/stripe/authorize_response_patcher.rb + - lib/stripe/credit_card_clone_destroyer.rb + - spec/support/i18n_translations_checker.rb - app/controllers/admin/enterprise_fees_controller.rb - app/controllers/admin/enterprises_controller.rb - app/controllers/spree/admin/taxons_controller.rb @@ -552,6 +616,18 @@ Metrics/CyclomaticComplexity: Metrics/PerceivedComplexity: Max: 7 Exclude: + - app/controllers/spree/admin/payment_methods_controller.rb + - app/controllers/spree/admin/payments_controller.rb + - app/controllers/spree/admin/users_controller.rb + - app/models/product_import/entry_validator.rb + - app/models/spree/order_inventory.rb + - app/models/spree/shipment.rb + - app/models/spree/variant.rb + - lib/active_merchant/billing/gateways/stripe_decorator.rb + - lib/open_food_network/group_buy_report.rb + - lib/open_food_network/order_cycle_form_applicator.rb + - lib/open_food_network/order_cycle_permissions.rb + - lib/open_food_network/payments_report.rb - app/controllers/admin/enterprises_controller.rb - app/controllers/api/variants_controller.rb - app/controllers/spree/admin/taxons_controller.rb @@ -702,10 +778,18 @@ Metrics/MethodLength: - spec/features/consumer/shopping/variant_overrides_spec.rb - spec/models/product_importer_spec.rb - spec/support/i18n_translations_checker.rb + - app/controllers/admin/bulk_line_items_controller.rb + - app/controllers/spree/paypal_controller.rb + - app/jobs/subscription_placement_job.rb + - app/models/spree/gateway/pay_pal_express.rb Metrics/ClassLength: Max: 100 Exclude: + - app/controllers/admin/customers_controller.rb + - app/controllers/spree/admin/payments_controller.rb + - app/controllers/spree/paypal_controller.rb + - engines/order_management/app/services/order_management/order/updater.rb - app/controllers/admin/enterprises_controller.rb - app/controllers/admin/order_cycles_controller.rb - app/controllers/admin/resource_controller.rb @@ -764,6 +848,7 @@ Metrics/ModuleLength: - app/models/spree/payment/processing.rb - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/order_cycles_controller_spec.rb - spec/controllers/api/orders_controller_spec.rb diff --git a/.rubocop_styleguide.yml b/.rubocop_styleguide.yml index 6a8818ca77..b956e49708 100644 --- a/.rubocop_styleguide.yml +++ b/.rubocop_styleguide.yml @@ -1,11 +1,10 @@ # Our Open Food Network style guide. # -# These are the rules we agreed upon and we work towards. Code Climate uses -# these rules to rate our code and detect new violations. But when you run -# rubocop locally, the default configuration file `.rubocop.yml` loads -# our "todo lists" to ignore all current violations. +# These are the rules we agreed upon and we work towards. AllCops: - TargetRailsVersion: 4.0 + NewCops: disable + SuggestExtensions: false + TargetRailsVersion: 5.0 Exclude: - 'bin/**/*' - 'db/**/*' @@ -183,7 +182,7 @@ Metrics/AbcSize: Metrics/BlockLength: Max: 25 - ExcludedMethods: [ + IgnoredMethods: [ "class_eval", "collection", "context", @@ -217,3 +216,6 @@ Metrics/ParameterLists: Metrics/PerceivedComplexity: Max: 7 + +Naming/PredicateName: + Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index cd62dcf638..6f3bbb554b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,16 +1,227 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 1400` -# on 2020-12-23 22:07:55 +0000 using RuboCop version 0.81.0. +# on 2021-03-25 06:59:27 UTC using RuboCop version 1.12.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. +# Include: **/*.gemfile, **/Gemfile, **/gems.rb +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + +# Offense count: 4 +# Configuration parameters: Include. +# Include: **/*.gemspec +Gemspec/RequiredRubyVersion: + Exclude: + - 'engines/catalog/catalog.gemspec' + - 'engines/dfc_provider/dfc_provider.gemspec' + - 'engines/order_management/order_management.gemspec' + - 'engines/web/web.gemspec' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: with_first_argument, with_fixed_indentation +Layout/ArgumentAlignment: + Exclude: + - 'spec/features/admin/order_cycles/simple_spec.rb' + +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleAlignWith, Severity. +# SupportedStylesAlignWith: start_of_line, begin +Layout/BeginEndAlignment: + Exclude: + - 'app/controllers/application_controller.rb' + - 'app/controllers/spree/admin/reports_controller.rb' + - 'app/jobs/job_logger.rb' + - 'app/models/spree/address.rb' + - 'app/models/spree/credit_card.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleAlignWith. +# SupportedStylesAlignWith: either, start_of_block, start_of_line +Layout/BlockAlignment: + Exclude: + - 'spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb' + - 'spec/features/admin/order_cycles/simple_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/CommentIndentation: + Exclude: + - 'spec/features/admin/order_cycles/simple_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/EmptyLineAfterMagicComment: + Exclude: + - 'spec/features/admin/configuration/tax_rates_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +Layout/EmptyLineBetweenDefs: + Exclude: + - 'app/controllers/api/enterprise_attachment_controller.rb' + - 'spec/controllers/spree/admin/base_controller_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/EmptyLines: + Exclude: + - 'spec/controllers/spree/admin/reports_controller_spec.rb' + +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: AllowAliasSyntax, AllowedMethods. +# AllowedMethods: alias_method, public, protected, private +Layout/EmptyLinesAroundAttributeAccessor: + Exclude: + - 'app/models/spree/shipment.rb' + - 'lib/open_food_network/customers_report.rb' + - 'lib/open_food_network/packing_report.rb' + - 'lib/open_food_network/payments_report.rb' + - 'lib/open_food_network/users_and_enterprises_report.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: + Exclude: + - 'spec/features/admin/payment_method_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets +Layout/FirstArrayElementIndentation: + Exclude: + - 'spec/lib/open_food_network/order_cycle_management_report_spec.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. +# SupportedHashRocketStyles: key, separator, table +# SupportedColonStyles: key, separator, table +# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit +Layout/HashAlignment: + Exclude: + - 'app/controllers/admin/order_cycles_controller.rb' + - 'spec/features/admin/adjustments_spec.rb' + - 'spec/models/spree/adjustment_spec.rb' + - 'spec/models/spree/order_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: normal, indented_internal_methods +Layout/IndentationConsistency: + Exclude: + - 'spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/MultilineBlockLayout: + Exclude: + - 'spec/controllers/spree/orders_controller_spec.rb' + - 'spec/services/process_payment_intent_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineMethodCallBraceLayout: + Exclude: + - 'spec/controllers/spree/orders_controller_spec.rb' + - 'spec/services/process_payment_intent_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +Layout/RescueEnsureAlignment: + Exclude: + - 'app/controllers/application_controller.rb' + - 'app/controllers/spree/admin/reports_controller.rb' + - 'app/models/spree/address.rb' + - 'app/models/spree/credit_card.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/SpaceAroundMethodCallOperator: + Exclude: + - 'spec/controllers/api/orders_controller_spec.rb' + - 'spec/controllers/api/shipments_controller_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBrackets: space, no_space +Layout/SpaceInsideArrayLiteralBrackets: + Exclude: + - 'spec/controllers/spree/admin/reports_controller_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'spec/services/embedded_page_service_spec.rb' + +# Offense count: 10 +# Cop supports --auto-correct. +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'spec/features/admin/order_cycles/simple_spec.rb' + - 'spec/features/consumer/shopping/unit_price_spec.rb' + - 'spec/support/features/datepicker_helper.rb' + - 'spec/support/request/web_helper.rb' + - 'spec/views/spree/orders/edit.html.haml_spec.rb' + +# Offense count: 15 +# Configuration parameters: AllowedMethods. +# AllowedMethods: enums +Lint/ConstantDefinitionInBlock: + Exclude: + - 'lib/tasks/users.rake' + - 'spec/controllers/spree/admin/base_controller_spec.rb' + - 'spec/helpers/serializer_helper_spec.rb' + - 'spec/lib/open_food_network/reports/line_items_spec.rb' + - 'spec/models/spree/ability_spec.rb' + - 'spec/models/spree/gateway_spec.rb' + - 'spec/models/spree/preferences/configuration_spec.rb' + - 'spec/models/spree/preferences/preferable_spec.rb' + - 'spec/validators/date_time_string_validator_spec.rb' + - 'spec/validators/integer_array_validator_spec.rb' + # Offense count: 2 Lint/DuplicateMethods: Exclude: - 'lib/discourse/single_sign_on.rb' +# Offense count: 1 +# Configuration parameters: AllowComments. +Lint/EmptyFile: + Exclude: + - 'spec/lib/open_food_network/enterprise_injection_data_spec.rb' + +# Offense count: 2 +Lint/FloatComparison: + Exclude: + - 'app/models/product_import/entry_validator.rb' + - 'app/models/spree/gateway/pay_pal_express.rb' + # Offense count: 5 Lint/IneffectiveAccessModifier: Exclude: @@ -18,13 +229,41 @@ Lint/IneffectiveAccessModifier: - 'app/models/spree/user.rb' - 'app/services/mail_configuration.rb' +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowedMethods. +# AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal? +Lint/RedundantSafeNavigation: + Exclude: + - 'app/models/spree/payment.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/ScriptPermission: + Exclude: + - '.simplecov' + # Offense count: 2 +# Cop supports --auto-correct. # Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. Lint/UselessAccessModifier: Exclude: - 'app/models/column_preference.rb' - 'app/services/mail_configuration.rb' +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: AllowComments. +Lint/UselessMethodDefinition: + Exclude: + - 'app/controllers/spree/user_registrations_controller.rb' + - 'app/models/spree/gateway.rb' + +# Offense count: 2 +# Configuration parameters: Max, CountKeywordArgs. +Metrics/ParameterLists: + MaxOptionalParameters: 4 + # Offense count: 10 Naming/AccessorMethodName: Exclude: @@ -51,7 +290,7 @@ Naming/MemoizedInstanceVariableName: - 'app/mailers/producer_mailer.rb' - 'lib/open_food_network/address_finder.rb' -# Offense count: 25 +# Offense count: 23 # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros. # NamePrefix: is_, has_, have_ # ForbiddenPrefixes: is_, has_, have_ @@ -59,7 +298,6 @@ Naming/MemoizedInstanceVariableName: # MethodDefinitionMacros: define_method, define_singleton_method Naming/PredicateName: Exclude: - - 'spec/**/*' - 'app/models/enterprise.rb' - 'app/models/enterprise_relationship.rb' - 'app/models/order_cycle.rb' @@ -79,17 +317,28 @@ Naming/PredicateName: - 'lib/open_food_network/packing_report.rb' - 'lib/tasks/data.rake' -# Offense count: 2 -# Configuration parameters: EnforcedStyle. +# Offense count: 30 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. # SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339 Naming/VariableNumber: Exclude: + - 'app/controllers/spree/orders_controller.rb' + - 'app/models/content_configuration.rb' + - 'app/models/preference_sections/main_links_section.rb' + - 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb' + - 'lib/spree/core/controller_helpers/common.rb' + - 'spec/controllers/spree/admin/search_controller_spec.rb' - 'spec/factories/stock_location_factory.rb' + - 'spec/features/admin/reports_spec.rb' + - 'spec/models/spree/stock_item_spec.rb' + - 'spec/requests/api/orders_spec.rb' -# Offense count: 8 +# Offense count: 9 # Cop supports --auto-correct. Rails/ActiveRecordAliases: Exclude: + - 'app/models/spree/gateway/pay_pal_express.rb' - 'spec/controllers/line_items_controller_spec.rb' - 'spec/controllers/spree/orders_controller_spec.rb' - 'spec/features/admin/subscriptions_spec.rb' @@ -102,6 +351,31 @@ Rails/ApplicationController: Exclude: - 'engines/dfc_provider/app/controllers/dfc_provider/api/base_controller.rb' +# Offense count: 6 +# Cop supports --auto-correct. +Rails/ApplicationJob: + Exclude: + - 'app/jobs/bulk_invoice_job.rb' + - 'app/jobs/confirm_order_job.rb' + - 'app/jobs/heartbeat_job.rb' + - 'app/jobs/order_cycle_notification_job.rb' + - 'app/jobs/subscription_confirm_job.rb' + - 'app/jobs/subscription_placement_job.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Rails/ApplicationMailer: + Exclude: + - 'app/mailers/spree/base_mailer.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. +Rails/Blank: + Exclude: + - 'app/services/content_sanitizer.rb' + - 'lib/stripe/authorize_response_patcher.rb' + # Offense count: 3 # Configuration parameters: EnforcedStyle. # SupportedStyles: strict, flexible @@ -147,14 +421,6 @@ Rails/FindBy: - 'app/models/product_import/spreadsheet_data.rb' - 'app/models/spree/user.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/FindEach: - Exclude: - - 'app/models/spree/shipment.rb' - # Offense count: 11 # Configuration parameters: Include. # Include: app/models/**/*.rb @@ -189,20 +455,19 @@ Rails/HasManyOrHasOneDependent: - 'app/models/spree/shipment.rb' - 'app/models/spree/shipping_category.rb' - 'app/models/spree/shipping_method.rb' + - 'app/models/spree/stock_item.rb' - 'app/models/spree/taxonomy.rb' - 'app/models/spree/user.rb' - 'app/models/spree/variant.rb' - 'app/models/subscription.rb' -# Offense count: 84 +# Offense count: 58 # Configuration parameters: Include. # Include: app/helpers/**/*.rb Rails/HelperInstanceVariable: Exclude: - 'app/helpers/admin/injection_helper.rb' - - 'app/helpers/angular_form_builder.rb' - 'app/helpers/application_helper.rb' - - 'app/helpers/enterprises_helper.rb' - 'app/helpers/injection_helper.rb' - 'app/helpers/order_cycles_helper.rb' - 'app/helpers/shared_helper.rb' @@ -210,7 +475,31 @@ Rails/HelperInstanceVariable: - 'app/helpers/spree/admin/orders_helper.rb' - 'app/helpers/spree/orders_helper.rb' -# Offense count: 33 +# Offense count: 38 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/InverseOf: + Exclude: + - 'app/models/concerns/line_item_based_adjustment_handling.rb' + - 'app/models/customer.rb' + - 'app/models/enterprise.rb' + - 'app/models/enterprise_fee.rb' + - 'app/models/order_cycle.rb' + - 'app/models/spree/adjustment.rb' + - 'app/models/spree/country.rb' + - 'app/models/spree/credit_card.rb' + - 'app/models/spree/line_item.rb' + - 'app/models/spree/option_type.rb' + - 'app/models/spree/order.rb' + - 'app/models/spree/payment.rb' + - 'app/models/spree/product.rb' + - 'app/models/spree/shipment.rb' + - 'app/models/spree/taxonomy.rb' + - 'app/models/spree/user.rb' + - 'app/models/spree/variant.rb' + - 'app/models/subscription.rb' + +# Offense count: 35 # Configuration parameters: Include. # Include: app/controllers/**/*.rb Rails/LexicallyScopedActionFilter: @@ -234,7 +523,7 @@ Rails/LexicallyScopedActionFilter: - 'app/controllers/spree/users_controller.rb' - 'app/controllers/user_passwords_controller.rb' -# Offense count: 14 +# Offense count: 13 Rails/OutputSafety: Exclude: - 'app/controllers/spree/admin/reports_controller.rb' @@ -246,29 +535,45 @@ Rails/OutputSafety: - 'app/helpers/spree/reports_helper.rb' - 'app/serializers/api/product_serializer.rb' - 'lib/spree/money.rb' - - 'lib/spree/money_decorator.rb' - 'spec/features/admin/order_print_ticket_spec.rb' # Offense count: 2 +# Cop supports --auto-correct. +Rails/PluralizationGrammar: + Exclude: + - 'spec/queries/complete_orders_with_balance_spec.rb' + +# Offense count: 3 +# Cop supports --auto-correct. # Configuration parameters: Include. # Include: **/Rakefile, **/*.rake Rails/RakeEnvironment: Exclude: - - 'lib/capistrano/tasks/**/*.rake' - 'lib/tasks/specs.rake' -# Offense count: 11 +# Offense count: 14 +# Cop supports --auto-correct. +Rails/RedundantForeignKey: + Exclude: + - 'app/models/customer.rb' + - 'app/models/enterprise.rb' + - 'app/models/enterprise_fee.rb' + - 'app/models/enterprise_group.rb' + - 'app/models/spree/order.rb' + - 'app/models/spree/shipping_method.rb' + - 'app/models/spree/user.rb' + - 'app/models/subscription.rb' + +# Offense count: 4 Rails/ReflectionClassName: Exclude: - 'app/models/customer.rb' - - 'app/models/distributor_shipping_method.rb' - 'app/models/enterprise_role.rb' - 'app/models/spree/order.rb' - - 'app/models/subscription.rb' -# Offense count: 252 -# Configuration parameters: Blacklist, Whitelist. -# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters +# Offense count: 284 +# Configuration parameters: ForbiddenMethods, AllowedMethods. +# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all Rails/SkipsModelValidations: Exclude: - 'app/controllers/admin/resource_controller.rb' @@ -276,16 +581,16 @@ Rails/SkipsModelValidations: - 'app/controllers/spree/admin/shipping_methods_controller.rb' - 'app/controllers/spree/admin/taxons_controller.rb' - 'app/controllers/spree/credit_cards_controller.rb' - - 'app/controllers/spree/orders_controller.rb' - 'app/jobs/subscription_confirm_job.rb' - 'app/jobs/subscription_placement_job.rb' + - 'app/models/concerns/line_item_stock_changes.rb' - 'app/models/enterprise.rb' - 'app/models/enterprise_relationship.rb' - 'app/models/product_import/inventory_reset_strategy.rb' - 'app/models/proxy_order.rb' - 'app/models/spree/address.rb' - - 'app/models/spree/adjustment.rb' - 'app/models/spree/credit_card.rb' + - 'app/models/spree/gateway/pay_pal_express.rb' - 'app/models/spree/inventory_unit.rb' - 'app/models/spree/order.rb' - 'app/models/spree/payment.rb' @@ -299,13 +604,15 @@ Rails/SkipsModelValidations: - 'app/models/subscription.rb' - 'app/models/variant_override.rb' - 'app/services/order_factory.rb' - - 'engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb' + - 'app/services/process_payment_intent.rb' + - 'engines/order_management/app/services/order_management/order/updater.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' - 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb' - 'lib/spree/core/calculated_adjustments.rb' - 'lib/tasks/data/anonymize_data.rake' - 'lib/tasks/sample_data/product_factory.rb' - 'lib/tasks/users.rake' + - 'spec/controllers/admin/customers_controller_spec.rb' - 'spec/controllers/admin/subscription_line_items_controller_spec.rb' - 'spec/controllers/admin/variant_overrides_controller_spec.rb' - 'spec/controllers/api/order_cycles_controller_spec.rb' @@ -315,12 +622,13 @@ Rails/SkipsModelValidations: - 'spec/controllers/api/variants_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' - 'spec/controllers/enterprises_controller_spec.rb' - - 'spec/controllers/spree/admin/orders_controller_spec.rb' + - 'spec/controllers/spree/admin/orders/invoices_spec.rb' - 'spec/controllers/spree/admin/overview_controller_spec.rb' - 'spec/controllers/spree/admin/payment_methods_controller_spec.rb' - 'spec/controllers/spree/credit_cards_controller_spec.rb' - 'spec/factories.rb' - 'spec/factories/order_factory.rb' + - 'spec/factories/shipment_factory.rb' - 'spec/features/admin/bulk_order_management_spec.rb' - 'spec/features/admin/bulk_product_update_spec.rb' - 'spec/features/admin/configuration/tax_rates_spec.rb' @@ -332,6 +640,7 @@ Rails/SkipsModelValidations: - 'spec/features/consumer/shopping/checkout_spec.rb' - 'spec/features/consumer/shopping/products_spec.rb' - 'spec/features/consumer/shopping/shopping_spec.rb' + - 'spec/features/consumer/shopping/unit_price_spec.rb' - 'spec/helpers/enterprises_helper_spec.rb' - 'spec/helpers/order_cycles_helper_spec.rb' - 'spec/jobs/subscription_placement_job_spec.rb' @@ -341,6 +650,7 @@ Rails/SkipsModelValidations: - 'spec/lib/open_food_network/products_and_inventory_report_spec.rb' - 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb' - 'spec/lib/stripe/credit_card_cloner_spec.rb' + - 'spec/lib/tasks/data/remove_transient_data_spec.rb' - 'spec/models/concerns/variant_stock_spec.rb' - 'spec/models/enterprise_relationship_spec.rb' - 'spec/models/exchange_spec.rb' @@ -352,6 +662,8 @@ Rails/SkipsModelValidations: - 'spec/models/spree/tax_category_spec.rb' - 'spec/models/spree/variant_spec.rb' - 'spec/models/tag_rule/discount_order_spec.rb' + - 'spec/queries/customers_with_balance_spec.rb' + - 'spec/queries/outstanding_balance_spec.rb' - 'spec/serializers/api/admin/subscription_line_item_serializer_spec.rb' - 'spec/services/cache_service_spec.rb' - 'spec/services/order_cart_reset_spec.rb' @@ -359,11 +671,24 @@ Rails/SkipsModelValidations: - 'spec/services/order_cycle_distributed_products_spec.rb' - 'spec/services/order_factory_spec.rb' - 'spec/services/order_syncer_spec.rb' + - 'spec/services/process_payment_intent_spec.rb' - 'spec/services/product_tag_rules_filterer_spec.rb' - 'spec/services/products_renderer_spec.rb' - 'spec/support/request/shop_workflow.rb' - 'spec/views/spree/shared/_order_details.html.haml_spec.rb' +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: strict, flexible +Rails/TimeZone: + Exclude: + - 'app/models/spree/gateway/pay_pal_express.rb' + - 'spec/controllers/spree/credit_cards_controller_spec.rb' + - 'spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb' + - 'spec/features/admin/order_cycles/simple_spec.rb' + - 'spec/services/customer_order_cancellation_spec.rb' + # Offense count: 5 # Configuration parameters: Include. # Include: app/models/**/*.rb @@ -375,23 +700,50 @@ Rails/UniqueValidationWithoutIndex: - 'app/models/spree/tax_category.rb' - 'app/models/spree/zone.rb' -# Offense count: 2 +# Offense count: 3 # Configuration parameters: Environments. # Environments: development, test, production Rails/UnknownEnv: Exclude: + - 'app/controllers/spree/admin/payment_methods_controller.rb' - 'app/models/spree/app_configuration.rb' - 'lib/spree/core/controller_helpers/ssl.rb' +# Offense count: 15 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: separated, grouped +Style/AccessorGrouping: + Exclude: + - 'app/controllers/admin/resource_controller.rb' + - 'app/models/customer.rb' + - 'app/models/product_import/spreadsheet_entry.rb' + - 'app/models/spree/line_item.rb' + - 'app/services/action_callbacks.rb' + - 'app/services/cart_service.rb' + - 'lib/discourse/single_sign_on.rb' + # Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AllowOnConstant. Style/CaseEquality: Exclude: - 'app/helpers/angular_form_helper.rb' - 'spec/models/spree/payment_spec.rb' -# Offense count: 29 +# Offense count: 5 # Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle. +Style/CaseLikeIf: + Exclude: + - 'app/controllers/admin/order_cycles_controller.rb' + - 'app/controllers/spree/orders_controller.rb' + - 'app/models/calculator/weight.rb' + - 'app/models/spree/payment/processing.rb' + - 'lib/active_merchant/billing/gateways/stripe_payment_intents.rb' + +# Offense count: 26 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. # SupportedStyles: nested, compact Style/ClassAndModuleChildren: Exclude: @@ -420,26 +772,53 @@ Style/ClassAndModuleChildren: - 'spec/controllers/spree/admin/base_controller_spec.rb' - 'spec/models/spree/payment_method_spec.rb' +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: IgnoredMethods. +# IgnoredMethods: ==, equal?, eql? +Style/ClassEqualityComparison: + Exclude: + - 'app/controllers/spree/admin/payments_controller.rb' + - 'app/models/tag_rule/discount_order.rb' + - 'spec/lib/open_food_network/group_buy_report_spec.rb' + - 'spec/support/delayed_job_helper.rb' + # Offense count: 3 Style/ClassVars: Exclude: - 'lib/open_food_network/rack_request_blocker.rb' - 'lib/spree/core/delegate_belongs_to.rb' -# Offense count: 4 -# Configuration parameters: EnforcedStyle. +# Offense count: 1 +# Cop supports --auto-correct. +Style/ExpandPathArguments: + Exclude: + - 'config.ru' + +# Offense count: 8 +# Cop supports --auto-correct. +Style/ExplicitBlockArgument: + Exclude: + - 'app/helpers/groups_helper.rb' + - 'app/services/cache_service.rb' + - 'app/services/current_order_locker.rb' + - 'spec/support/embedded_pages_helper.rb' + - 'spec/support/performance_helper.rb' + - 'spec/support/request/shop_workflow.rb' + +# Offense count: 2 +# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, IgnoredMethods. # SupportedStyles: annotated, template, unannotated Style/FormatStringToken: - Exclude: - - 'lib/open_food_network/sales_tax_report.rb' - - 'spec/features/admin/bulk_order_management_spec.rb' + EnforcedStyle: unannotated -# Offense count: 365 +# Offense count: 354 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: Exclude: + - '.simplecov' - 'app/controllers/admin/bulk_line_items_controller.rb' - 'app/controllers/admin/column_preferences_controller.rb' - 'app/controllers/admin/contents_controller.rb' @@ -480,7 +859,6 @@ Style/FrozenStringLiteralComment: - 'app/controllers/api/taxonomies_controller.rb' - 'app/controllers/api/taxons_controller.rb' - 'app/controllers/api/variants_controller.rb' - - 'app/controllers/base_controller.rb' - 'app/controllers/cart_controller.rb' - 'app/controllers/discourse_sso_controller.rb' - 'app/controllers/enterprises_controller.rb' @@ -522,7 +900,6 @@ Style/FrozenStringLiteralComment: - 'app/controllers/spree/admin/users_controller.rb' - 'app/controllers/spree/admin/variants_controller.rb' - 'app/controllers/spree/admin/zones_controller.rb' - - 'app/controllers/spree/credit_cards_controller.rb' - 'app/controllers/spree/orders_controller.rb' - 'app/controllers/spree/users_controller.rb' - 'app/controllers/stripe/callbacks_controller.rb' @@ -557,12 +934,9 @@ Style/FrozenStringLiteralComment: - 'app/helpers/spree/admin/payments_helper.rb' - 'app/helpers/spree/admin/taxons_helper.rb' - 'app/helpers/spree/admin/zones_helper.rb' - - 'app/helpers/spree/api/api_helpers.rb' - 'app/helpers/spree/orders_helper.rb' - 'app/helpers/spree/reports_helper.rb' - 'app/helpers/spree_currency_helper.rb' - - 'app/jobs/heartbeat_job.rb' - - 'app/jobs/manager_invitation_job.rb' - 'app/jobs/subscription_confirm_job.rb' - 'app/jobs/subscription_placement_job.rb' - 'app/mailers/enterprise_mailer.rb' @@ -624,7 +998,6 @@ Style/FrozenStringLiteralComment: - 'app/models/tag_rule/filter_payment_methods.rb' - 'app/models/tag_rule/filter_products.rb' - 'app/models/tag_rule/filter_shipping_methods.rb' - - 'app/models/variant_override.rb' - 'app/serializers/api/address_serializer.rb' - 'app/serializers/api/adjustment_serializer.rb' - 'app/serializers/api/cached_enterprise_serializer.rb' @@ -645,7 +1018,6 @@ Style/FrozenStringLiteralComment: - 'app/serializers/api/order_cycle_serializer.rb' - 'app/serializers/api/order_detailed_serializer.rb' - 'app/serializers/api/order_serializer.rb' - - 'app/serializers/api/orders_by_distributor_serializer.rb' - 'app/serializers/api/payment_method_serializer.rb' - 'app/serializers/api/payment_serializer.rb' - 'app/serializers/api/product_serializer.rb' @@ -661,7 +1033,6 @@ Style/FrozenStringLiteralComment: - 'app/serializers/api/uncached_enterprise_serializer.rb' - 'app/serializers/api/user_serializer.rb' - 'app/serializers/api/variant_serializer.rb' - - 'app/services/action_callbacks.rb' - 'app/services/bulk_invoice_service.rb' - 'app/services/cart_service.rb' - 'app/services/create_order_cycle.rb' @@ -719,7 +1090,7 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/app/services/reports/renderers/base.rb' - 'engines/order_management/app/services/reports/report_data/base.rb' - 'engines/web/app/controllers/web/angular_templates_controller.rb' - - 'engines/web/app/controllers/web/api/cookies_consent_controller.rb' + - 'engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb' - 'engines/web/app/controllers/web/application_controller.rb' - 'engines/web/app/helpers/web/cookies_policy_helper.rb' - 'engines/web/lib/web/cookies_consent.rb' @@ -750,7 +1121,6 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report.rb' - 'lib/open_food_network/packing_report.rb' - 'lib/open_food_network/paperclippable.rb' - - 'lib/open_food_network/payments_report.rb' - 'lib/open_food_network/permissions.rb' - 'lib/open_food_network/products_and_inventory_report.rb' - 'lib/open_food_network/products_and_inventory_report_base.rb' @@ -765,12 +1135,9 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/scope_variants_for_search.rb' - 'lib/open_food_network/spree_api_key_loader.rb' - 'lib/open_food_network/tag_rule_applicator.rb' - - 'lib/open_food_network/user_balance_calculator.rb' - 'lib/open_food_network/users_and_enterprises_report.rb' - 'lib/open_food_network/xero_invoices_report.rb' - - 'lib/spree/api/controller_setup.rb' - 'lib/spree/authentication_helpers.rb' - - 'lib/spree/money_decorator.rb' - 'lib/stripe/account_connector.rb' - 'lib/stripe/profile_storer.rb' - 'lib/stripe/webhook_handler.rb' @@ -796,8 +1163,24 @@ Style/FrozenStringLiteralComment: - 'lib/tasks/sample_data/user_factory.rb' - 'lib/tasks/specs.rake' - 'lib/tasks/users.rake' + - 'spec/features/consumer/shopping/unit_price_spec.rb' + - 'spec/helpers/terms_and_conditions_helper_spec.rb' + - 'spec/initializers/feature_toggles_spec.rb' + - 'spec/lib/open_food_network/reports/line_items_spec.rb' + - 'spec/models/concerns/balance_spec.rb' + - 'spec/services/order_data_masker_spec.rb' -# Offense count: 39 +# Offense count: 6 +# Cop supports --auto-correct. +Style/GlobalStdStream: + Exclude: + - 'lib/tasks/data.rake' + - 'lib/tasks/missing_payments.rake' + - 'lib/tasks/sample_data/logging.rb' + - 'lib/tasks/subscriptions/debug.rake' + - 'lib/tasks/subscriptions/test.rake' + +# Offense count: 38 # Configuration parameters: MinBodyLength. Style/GuardClause: Exclude: @@ -808,7 +1191,6 @@ Style/GuardClause: - 'app/controllers/application_controller.rb' - 'app/controllers/home_controller.rb' - 'app/controllers/spree/orders_controller.rb' - - 'app/controllers/spree/paypal_controller_decorator.rb' - 'app/models/enterprise.rb' - 'app/models/enterprise_group.rb' - 'app/models/producer_property.rb' @@ -823,6 +1205,39 @@ Style/GuardClause: - 'spec/support/request/distribution_helper.rb' - 'spec/support/request/shop_workflow.rb' +# Offense count: 10 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: braces, no_braces +Style/HashAsLastArrayItem: + Exclude: + - 'app/controllers/admin/enterprises_controller.rb' + - 'app/controllers/admin/subscriptions_controller.rb' + - 'app/services/exchange_products_renderer.rb' + - 'app/services/permitted_attributes/checkout.rb' + - 'app/services/permitted_attributes/order_cycle.rb' + - 'app/services/permitted_attributes/product.rb' + - 'lib/open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report.rb' + - 'lib/open_food_network/xero_invoices_report.rb' + +# Offense count: 1 +# Configuration parameters: MinBranchesCount. +Style/HashLikeCase: + Exclude: + - 'app/models/enterprise.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. +# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys +Style/HashSyntax: + Exclude: + - 'spec/features/admin/order_cycles/simple_spec.rb' + - 'spec/features/consumer/account/cards_spec.rb' + - 'spec/features/consumer/account/payments_spec.rb' + - 'spec/features/consumer/account/settings_spec.rb' + - 'spec/features/consumer/account_spec.rb' + # Offense count: 3 Style/MissingRespondToMissing: Exclude: @@ -836,13 +1251,12 @@ Style/MixinUsage: - 'lib/open_food_network/orders_and_fulfillments_report.rb' - 'spec/lib/open_food_network/packing_report_spec.rb' -# Offense count: 42 +# Offense count: 41 # Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. +# Configuration parameters: EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison Style/NumericPredicate: Exclude: - - 'spec/**/*' - 'app/controllers/spree/admin/payment_methods_controller.rb' - 'app/controllers/spree/orders_controller.rb' - 'app/helpers/checkout_helper.rb' @@ -864,12 +1278,103 @@ Style/NumericPredicate: - 'lib/open_food_network/rack_request_blocker.rb' - 'lib/open_food_network/sales_tax_report.rb' - 'lib/open_food_network/xero_invoices_report.rb' - - 'lib/spree/money_decorator.rb' - 'lib/tasks/sample_data.rake' -# Offense count: 243 +# Offense count: 26 +# Configuration parameters: AllowedMethods. +# AllowedMethods: respond_to_missing? +Style/OptionalBooleanParameter: + Exclude: + - 'app/controllers/admin/subscriptions_controller.rb' + - 'app/mailers/spree/order_mailer.rb' + - 'app/mailers/spree/shipment_mailer.rb' + - 'app/models/enterprise_relationship.rb' + - 'app/models/product_import/entry_processor.rb' + - 'app/models/spree/preferences/file_configuration.rb' + - 'app/models/spree/shipment.rb' + - 'app/services/cart_service.rb' + - 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb' + - 'engines/order_management/app/services/order_management/stock/estimator.rb' + - 'lib/open_food_network/customers_report.rb' + - 'lib/open_food_network/order_and_distributor_report.rb' + - 'lib/open_food_network/order_cycle_management_report.rb' + - 'lib/open_food_network/orders_and_fulfillments_report.rb' + - 'lib/open_food_network/packing_report.rb' + - 'lib/open_food_network/payments_report.rb' + - 'lib/open_food_network/products_and_inventory_report_base.rb' + - 'lib/open_food_network/users_and_enterprises_report.rb' + - 'lib/open_food_network/xero_invoices_report.rb' + - 'lib/spree/core/calculated_adjustments.rb' + - 'lib/spree/core/controller_helpers/order.rb' + - 'lib/spree/core/delegate_belongs_to.rb' + - 'spec/support/request/web_helper.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +Style/RedundantAssignment: + Exclude: + - 'app/models/spree/payment.rb' + - 'app/models/spree/taxon.rb' + - 'lib/open_food_network/order_grouper.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +Style/RedundantBegin: + Exclude: + - 'lib/open_food_network/enterprise_injection_data.rb' + - 'lib/open_food_network/order_cycle_permissions.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Style/RedundantFileExtensionInRequire: + Exclude: + - 'engines/catalog/spec/spec_helper.rb' + - 'engines/dfc_provider/spec/spec_helper.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantInterpolation: + Exclude: + - 'spec/initializers/feature_toggles_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Style/RedundantRegexpCharacterClass: + Exclude: + - 'app/models/spree/order.rb' + - 'lib/stripe/authorize_response_patcher.rb' + +# Offense count: 11 +# Cop supports --auto-correct. +Style/RedundantRegexpEscape: + Exclude: + - 'app/models/spree/order.rb' + - 'engines/web/config/routes.rb' + - 'lib/spree/localized_number.rb' + - 'lib/stripe/authorize_response_patcher.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'spec/support/features/datepicker_helper.rb' + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, AllowInnerSlashes. +# SupportedStyles: slashes, percent_r, mixed +Style/RegexpLiteral: + Exclude: + - 'spec/features/consumer/account/cards_spec.rb' + - 'spec/features/consumer/account/payments_spec.rb' + - 'spec/features/consumer/account/settings_spec.rb' + - 'spec/features/consumer/account_spec.rb' + +# Offense count: 240 Style/Send: Exclude: + - 'engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb' - 'spec/controllers/admin/subscriptions_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' - 'spec/controllers/spree/admin/base_controller_spec.rb' @@ -907,17 +1412,90 @@ Style/Send: - 'spec/services/variant_units/option_value_namer_spec.rb' - 'spec/spec_helper.rb' - 'spec/support/localized_number_helper.rb' - - 'spec/support/matchers/delegate_matchers.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Style/SingleArgumentDig: + Exclude: + - 'app/services/checkout/form_data_adapter.rb' + - 'lib/active_merchant/billing/gateways/stripe_payment_intents.rb' + +# Offense count: 10 +# Cop supports --auto-correct. +# Configuration parameters: AllowModifier. +Style/SoleNestedConditional: + Exclude: + - 'Rakefile' + - 'app/controllers/checkout_controller.rb' + - 'app/models/product_import/spreadsheet_entry.rb' + - 'app/models/spree/address.rb' + - 'app/models/spree/preferences/store.rb' + - 'app/services/order_syncer.rb' + - 'app/services/order_workflow.rb' + - 'lib/spree/core/controller_helpers/order.rb' + - 'spec/support/matchers/select2_matchers.rb' + +# Offense count: 45 +# Cop supports --auto-correct. +Style/StringConcatenation: + Exclude: + - 'app/controllers/admin/stripe_connect_settings_controller.rb' + - 'app/helpers/discourse_helper.rb' + - 'app/helpers/enterprises_helper.rb' + - 'app/helpers/spree/admin/base_helper.rb' + - 'app/mailers/spree/user_mailer.rb' + - 'app/models/enterprise.rb' + - 'app/models/spree/credit_card.rb' + - 'app/models/spree/line_item.rb' + - 'app/models/spree/payment_method.rb' + - 'app/models/spree/tax_rate.rb' + - 'app/serializers/api/cached_enterprise_serializer.rb' + - 'app/serializers/api/enterprise_shopfront_list_serializer.rb' + - 'app/services/embedded_page_service.rb' + - 'app/services/products_renderer.rb' + - 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb' + - 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb' + - 'lib/spree/api/controller_setup.rb' + - 'lib/spree/core/environment_extension.rb' + - 'spec/controllers/user_confirmations_controller_spec.rb' + - 'spec/features/admin/bulk_order_management_spec.rb' + - 'spec/features/admin/products_spec.rb' + - 'spec/features/consumer/account_spec.rb' + - 'spec/features/consumer/authentication_spec.rb' + - 'spec/features/consumer/shopping/shopping_spec.rb' + - 'spec/lib/open_food_network/order_grouper_spec.rb' + - 'spec/models/spree/line_item_spec.rb' + - 'spec/models/spree/product_spec.rb' + - 'spec/models/spree/variant_spec.rb' + - 'spec/requests/embedded_shopfronts_headers_spec.rb' + - 'spec/services/embedded_page_service_spec.rb' + - 'spec/support/api_helper.rb' + - 'spec/support/features/datepicker_helper.rb' # Offense count: 1 +# Cop supports --auto-correct. Style/StructInheritance: Exclude: - 'lib/open_food_network/enterprise_fee_applicator.rb' # Offense count: 2 # Cop supports --auto-correct. -# Configuration parameters: IgnoredMethods. +# Configuration parameters: AllowMethodsWithArguments, IgnoredMethods. # IgnoredMethods: respond_to, define_method Style/SymbolProc: Exclude: - 'app/models/spree/preferences/preferable.rb' + +# Offense count: 19 +# Cop supports --auto-correct. +Style/WhileUntilModifier: + Exclude: + - 'spec/controllers/admin/subscriptions_controller_spec.rb' + - 'spec/controllers/line_items_controller_spec.rb' + - 'spec/controllers/spree/admin/orders_controller_spec.rb' + - 'spec/controllers/spree/orders_controller_spec.rb' + - 'spec/factories/order_factory.rb' + - 'spec/features/admin/payments_stripe_spec.rb' + - 'spec/jobs/subscription_placement_job_spec.rb' + - 'spec/models/proxy_order_spec.rb' + - 'spec/models/spree/line_item_spec.rb' diff --git a/.ruby-version b/.ruby-version index 79a614418f..ecd7ee50cb 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.4 +2.5.8 diff --git a/.simplecov b/.simplecov index ed6f826b48..d60a2ab165 100644 --- a/.simplecov +++ b/.simplecov @@ -1,8 +1,6 @@ #!/bin/env ruby SimpleCov.start 'rails' do - minimum_coverage 54 - add_filter '/bin/' add_filter '/config/' add_filter '/jobs/application_job.rb' @@ -15,4 +13,8 @@ SimpleCov.start 'rails' do add_filter '/script' add_filter '/log' add_filter '/db' + add_filter '/lib/tasks/sample_data/' end + +require 'codecov' +SimpleCov.formatter = SimpleCov::Formatter::Codecov diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 0000000000..f539363b64 --- /dev/null +++ b/.storybook/main.js @@ -0,0 +1,7 @@ +module.exports = { + stories: ['../spec/components/stories/**/*.stories.json'], + addons: [ + '@storybook/addon-docs', + '@storybook/addon-controls', + ], +}; diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 0000000000..1fce9472e7 --- /dev/null +++ b/.storybook/preview-head.html @@ -0,0 +1,2 @@ + + diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 0000000000..bf6bae9465 --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,5 @@ +export const parameters = { + server: { + url: `http://localhost:3000/rails/stories`, + }, +}; diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index db5ed0a65b..f244d9ca45 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -6,12 +6,13 @@ This is a general guide to setting up an Open Food Network **development environ The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](docker/README.md). Otherwise, for a local setup you will need: -* Ruby 2.3.7 and bundler +* Ruby 2.4.4 and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file) * PostgreSQL database * Chrome (for testing) The following guides will provide OS-specific step-by-step instructions to get these requirements installed: - [Ubuntu Setup Guide][ubuntu] +- [Debian Setup Guide][debian] - [OSX Setup Guide][osx] If you are likely to need to manage multiple version of ruby on your local machine, we recommend version managers such as [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/). @@ -20,7 +21,7 @@ For those new to Rails, the following tutorial will help get you up to speed wit ### Get it -If you're planning on contributing code to the project (which we [LOVE](CONTRIBUTING.md)), it is a good idea to begin by forking this repo using the `Fork` button in the top-right corner of this screen. You should then be able to use `git clone` to copy your fork onto your local machine. +So you have set up your local environment according to the requirements listed above. If you're planning on contributing code to the project (which we [LOVE](CONTRIBUTING.md)), it is a good idea to begin by forking this repo using the `Fork` button in the top-right corner of this screen. You should then be able to use `git clone` to copy your fork onto your local machine: git clone https://github.com/YOUR_GITHUB_USERNAME_HERE/openfoodnetwork @@ -116,6 +117,7 @@ If these commands succeed, you should be able to [continue the setup process](#g [developer-wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki [osx]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X [ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu +[debian]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Debian [wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki [zeus]: https://github.com/burke/zeus [rubocop]: https://rubocop.readthedocs.io/en/latest/ diff --git a/Gemfile b/Gemfile index c2456a9f19..a4a9aa0de4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ # frozen_string_literal: true source 'https://rubygems.org' -ruby "2.4.4" +ruby "2.5.8" git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'rails', '~> 5.0.0' @@ -15,7 +15,7 @@ gem 'sass', '<= 4.7.1' gem 'sass-rails', '< 6.0.0' gem 'i18n' -gem 'i18n-js', '~> 3.8.1' +gem 'i18n-js', '~> 3.8.2' gem 'rails-i18n' gem 'rails_safe_tasks', '~> 1.0' @@ -31,7 +31,7 @@ gem 'web', path: './engines/web' gem 'activerecord-postgresql-adapter' gem 'pg', '~> 0.21.0' -gem 'acts_as_list', '0.9.19' +gem 'acts_as_list', '1.0.4' gem 'cancancan', '~> 1.15.0' gem 'ffaker' gem 'highline', '2.0.3' # Necessary for the install generator @@ -48,7 +48,7 @@ gem 'devise' gem 'devise-encryptable' gem 'devise-token_authenticatable' gem 'jwt', '~> 2.2' -gem 'oauth2', '~> 1.4.4' # Used for Stripe Connect +gem 'oauth2', '~> 1.4.7' # Used for Stripe Connect gem 'daemons' gem 'delayed_job_active_record' @@ -83,7 +83,7 @@ gem 'roadie-rails', '~> 1.3.0' gem 'combine_pdf' gem 'wicked_pdf' -gem 'wkhtmltopdf-binary', '0.12.5' # We need to upgrade our CI before we can bump this :/ +gem 'wkhtmltopdf-binary' gem 'immigrant' gem 'roo', '~> 2.8.3' @@ -95,7 +95,7 @@ gem 'test-unit', '~> 3.4' gem 'coffee-rails', '~> 4.2.2' gem 'compass-rails' -gem 'mini_racer', '0.3.1' +gem 'mini_racer', '0.4.0' gem 'uglifier', '>= 1.0.3' @@ -113,6 +113,12 @@ gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', branch: 'ofn-rails-4' gem 'good_migrations' +gem 'flipper' +gem 'flipper-active_record' +gem 'flipper-ui' + +gem "view_component", require: "view_component/engine" + group :production, :staging do gem 'ddtrace' gem 'unicorn-worker-killer' @@ -125,7 +131,7 @@ group :test, :development do gem 'bullet' gem 'capybara' gem 'database_cleaner', require: false - gem "factory_bot_rails", '5.2.0', require: false + gem "factory_bot_rails", '6.1.0', require: false gem 'fuubar', '~> 2.5.1' gem 'json_spec', '~> 1.1.4' gem 'knapsack' @@ -141,6 +147,7 @@ group :test, :development do end group :test do + gem 'codecov', require: false gem 'simplecov', require: false gem 'test-prof' gem 'webmock' @@ -159,6 +166,8 @@ group :development do gem 'spring' gem 'spring-commands-rspec' + gem "view_component_storybook", require: "view_component/storybook/engine" + # 1.0.9 fixed openssl issues on macOS https://github.com/eventmachine/eventmachine/issues/602 # While we don't require this gem directly, no dependents forced the upgrade to a version # greater than 1.0.9, so we just required the latest available version here. diff --git a/Gemfile.lock b/Gemfile.lock index 08fc203dce..e87b355eff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,7 +77,7 @@ GEM activejob (5.0.7.2) activesupport (= 5.0.7.2) globalid (>= 0.3.6) - activemerchant (1.107.4) + activemerchant (1.119.0) activesupport (>= 4.2) builder (>= 2.1.2, < 4.0.0) i18n (>= 0.6.9) @@ -105,8 +105,8 @@ GEM tzinfo (~> 1.1) acts-as-taggable-on (7.0.0) activerecord (>= 5.0, < 6.2) - acts_as_list (0.9.19) - activerecord (>= 3.0) + acts_as_list (1.0.4) + activerecord (>= 4.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) andand (1.3.3) @@ -114,7 +114,7 @@ GEM railties (>= 4.2, < 7) sprockets (>= 3.0, < 5) tilt - angular_rails_csrf (4.2.0) + angular_rails_csrf (4.5.0) railties (>= 3, < 7) angularjs-file-upload-rails (2.4.1) angularjs-rails (1.5.5) @@ -130,7 +130,7 @@ GEM json (~> 1.4) nokogiri (~> 1) bcrypt (3.1.16) - bugsnag (6.19.0) + bugsnag (6.20.0) concurrent-ruby (~> 1.0) builder (3.2.4) bullet (6.1.4) @@ -138,13 +138,13 @@ GEM uniform_notifier (~> 1.11) byebug (11.1.3) cancancan (1.15.0) - capybara (3.32.2) + capybara (3.35.3) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.5) + regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) childprocess (3.0.0) chronic (0.10.2) @@ -152,6 +152,8 @@ GEM climate_control (0.2.0) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) + codecov (0.5.1) + simplecov (>= 0.15, < 0.22) coderay (1.1.3) coffee-rails (4.2.2) coffee-script (>= 2.2.0) @@ -187,12 +189,13 @@ GEM daemons (1.3.1) dalli (2.7.11) database_cleaner (1.99.0) - ddtrace (0.46.0) + ddtrace (0.48.0) + ffi (~> 1.0) msgpack debugger-linecache (1.2.0) delayed_job (4.1.9) activesupport (>= 3.0, < 6.2) - delayed_job_active_record (4.1.5) + delayed_job_active_record (4.1.6) activerecord (>= 3.0, < 6.2) delayed_job (>= 3.0, < 5) delayed_job_web (1.4.4) @@ -211,22 +214,35 @@ GEM devise-token_authenticatable (1.1.0) devise (>= 4.0.0, < 5.0.0) diff-lcs (1.4.4) - docile (1.3.4) + docile (1.3.5) + erubi (1.10.0) erubis (2.7.0) eventmachine (1.2.7) excon (0.79.0) execjs (2.7.0) - factory_bot (5.2.0) - activesupport (>= 4.2.0) - factory_bot_rails (5.2.0) - factory_bot (~> 5.2.0) - railties (>= 4.2.0) - faraday (1.0.1) + factory_bot (6.1.0) + activesupport (>= 5.0.0) + factory_bot_rails (6.1.0) + factory_bot (~> 6.1.0) + railties (>= 5.0.0) + faraday (1.3.0) + faraday-net_http (~> 1.0) multipart-post (>= 1.2, < 3) - ffaker (2.16.0) + ruby2_keywords + faraday-net_http (1.0.1) + ffaker (2.18.0) ffi (1.15.0) figaro (1.2.0) thor (>= 0.14.0, < 2) + flipper (0.20.4) + flipper-active_record (0.20.4) + activerecord (>= 5.0, < 7) + flipper (~> 0.20.4) + flipper-ui (0.20.4) + erubi (>= 1.0.0, < 2.0.0) + flipper (~> 0.20.4) + rack (>= 1.4, < 3) + rack-protection (>= 1.5.3, < 2.2.0) fog-aws (2.0.1) fog-core (~> 1.38) fog-json (~> 1.0) @@ -252,7 +268,7 @@ GEM fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - geocoder (1.6.6) + geocoder (1.6.7) get_process_mem (0.2.7) ffi (~> 1.0) globalid (0.4.2) @@ -266,9 +282,9 @@ GEM tilt hashdiff (1.0.1) highline (2.0.3) - i18n (1.8.9) + i18n (1.8.10) concurrent-ruby (~> 1.0) - i18n-js (3.8.1) + i18n-js (3.8.2) i18n (>= 0.6.6) immigrant (0.3.6) activerecord (>= 3.0) @@ -300,13 +316,13 @@ GEM kaminari-core (= 1.2.1) kaminari-core (1.2.1) kgio (2.11.3) - knapsack (1.20.0) + knapsack (1.22.0) rake launchy (2.4.3) addressable (~> 2.3) letter_opener (1.7.0) launchy (~> 2.2) - libv8 (8.4.255.0) + libv8-node (15.14.0.0) loofah (2.9.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) @@ -316,10 +332,10 @@ GEM mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2020.1104) - mini_mime (1.0.2) - mini_portile2 (2.4.0) - mini_racer (0.3.1) - libv8 (~> 8.4.255) + mini_mime (1.0.3) + mini_portile2 (2.5.0) + mini_racer (0.4.0) + libv8-node (~> 15.14.0.0) minitest (5.14.4) monetize (1.11.0) money (~> 6.12) @@ -332,9 +348,10 @@ GEM mustermann (1.1.1) ruby2_keywords (~> 0.0.1) nio4r (2.5.2) - nokogiri (1.10.10) - mini_portile2 (~> 2.4.0) - oauth2 (1.4.4) + nokogiri (1.11.2) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) + oauth2 (1.4.7) faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) @@ -353,7 +370,7 @@ GEM parallel (1.20.1) paranoia (2.4.3) activerecord (>= 4.0, < 6.2) - parser (3.0.0.0) + parser (3.0.1.0) ast (~> 2.4.1) paypal-sdk-core (0.3.4) multi_json (~> 1.0) @@ -371,6 +388,7 @@ GEM byebug (~> 11.0) pry (~> 0.13.0) public_suffix (4.0.6) + racc (1.5.2) rack (2.2.3) rack-mini-profiler (2.3.1) rack (>= 1.2.0) @@ -425,13 +443,13 @@ GEM rb-inotify (0.10.1) ffi (~> 1.0) redcarpet (3.5.1) - regexp_parser (1.8.2) + regexp_parser (2.1.1) request_store (1.5.0) rack (>= 1.4) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) - rexml (3.2.4) + rexml (3.2.5) roadie (3.5.1) css_parser (~> 1.4) nokogiri (~> 1.8) @@ -477,7 +495,7 @@ GEM rswag-ui (2.4.0) actionpack (>= 3.1, < 7.0) railties (>= 3.1, < 7.0) - rubocop (1.11.0) + rubocop (1.13.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -511,10 +529,12 @@ GEM rubyzip (>= 1.2.2) shoulda-matchers (4.5.1) activesupport (>= 4.2.0) - simplecov (0.18.5) + simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) + simplecov_json_formatter (0.1.2) sinatra (2.1.0) mustermann (~> 1.0) rack (~> 2.2) @@ -540,8 +560,8 @@ GEM stringex (2.8.5) stripe (5.30.0) temple (0.8.2) - test-prof (0.11.3) - test-unit (3.4.0) + test-prof (1.0.2) + test-unit (3.4.1) power_assert thor (0.20.3) thread_safe (0.3.6) @@ -552,23 +572,27 @@ GEM uglifier (4.2.0) execjs (>= 0.3.0, < 3) unicode-display_width (2.0.0) - unicorn (5.8.0) + unicorn (6.0.0) kgio (~> 2.6) raindrops (~> 0.7) unicorn-rails (2.2.1) rack unicorn - unicorn-worker-killer (0.4.4) + unicorn-worker-killer (0.4.5) get_process_mem (~> 0) - unicorn (>= 4, < 6) + unicorn (>= 4, < 7) uniform_notifier (1.14.1) + view_component (2.28.0) + activesupport (>= 5.0.0, < 7.0) + view_component_storybook (0.8.0) + view_component (>= 2.2) warden (1.2.9) rack (>= 2.0.9) webdrivers (4.6.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (>= 3.0, < 4.0) - webmock (3.12.1) + webmock (3.12.2) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -579,7 +603,7 @@ GEM chronic (>= 0.6.3) wicked_pdf (2.1.0) activesupport - wkhtmltopdf-binary (0.12.5) + wkhtmltopdf-binary (0.12.6.5) xml-simple (1.1.8) xpath (3.2.0) nokogiri (~> 1.8) @@ -595,7 +619,7 @@ DEPENDENCIES activerecord-postgresql-adapter activerecord-session_store acts-as-taggable-on (~> 7.0) - acts_as_list (= 0.9.19) + acts_as_list (= 1.0.4) andand angular-rails-templates (>= 0.3.0) angular_rails_csrf @@ -611,6 +635,7 @@ DEPENDENCIES cancancan (~> 1.15.0) capybara catalog! + codecov coffee-rails (~> 4.2.2) combine_pdf compass-rails @@ -628,9 +653,12 @@ DEPENDENCIES devise-token_authenticatable dfc_provider! eventmachine (>= 1.2.3) - factory_bot_rails (= 5.2.0) + factory_bot_rails (= 6.1.0) ffaker figaro + flipper + flipper-active_record + flipper-ui fog-aws (>= 0.6.0) foundation-icons-sass-rails foundation-rails (= 5.5.2.1) @@ -641,7 +669,7 @@ DEPENDENCIES haml highline (= 2.0.3) i18n - i18n-js (~> 3.8.1) + i18n-js (~> 3.8.2) immigrant jquery-migrate-rails jquery-rails (= 4.4.0) @@ -652,9 +680,9 @@ DEPENDENCIES kaminari (~> 1.2.1) knapsack letter_opener (>= 1.4.1) - mini_racer (= 0.3.1) + mini_racer (= 0.4.0) monetize (~> 1.11) - oauth2 (~> 1.4.4) + oauth2 (~> 1.4.7) ofn-qz! order_management! paper_trail (~> 10.3.1) @@ -698,15 +726,17 @@ DEPENDENCIES uglifier (>= 1.0.3) unicorn-rails unicorn-worker-killer + view_component + view_component_storybook web! webdrivers webmock whenever wicked_pdf - wkhtmltopdf-binary (= 0.12.5) + wkhtmltopdf-binary RUBY VERSION - ruby 2.4.4p296 + ruby 2.5.8p224 BUNDLED WITH 1.17.3 diff --git a/README.md b/README.md index a3d0ffedcf..378a245cf7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Build Status](https://semaphoreci.com/api/v1/openfoodfoundation/openfoodnetwork-2/branches/master/badge.svg)](https://semaphoreci.com/openfoodfoundation/openfoodnetwork-2) -[![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) [![Build](https://github.com/openfoodfoundation/openfoodnetwork/actions/workflows/build.yml/badge.svg)](https://github.com/openfoodfoundation/openfoodnetwork/actions/workflows/build.yml) +[![codecov](https://codecov.io/gh/openfoodfoundation/openfoodnetwork/branch/master/graph/badge.svg?token=FBSOod4qiu)](https://codecov.io/gh/openfoodfoundation/openfoodnetwork) +[![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) # Open Food Network @@ -34,7 +34,7 @@ We also have a [Super Admin Guide][super-admin-guide] to help with configuration ## Testing -If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite] and download the [ZenHub browser extension][zenhub] to view the development pipeline. +If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite] and download the [ZenHub browser extension][zenhub] to view the development pipeline. Also, do have a look in our [Welcome New QAs board](https://github.com/openfoodfoundation/openfoodnetwork/projects/31) for some good first issues, both on manual and automated testing (RSpec/Capybara). We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. BrowserStack provides open source projects with unlimited and free of charge accounts. A big thanks to them! diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 6f0dc8bbd4..f28f55565a 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -52,6 +52,9 @@ //= require admin/spree/handlebar_extensions // OFN specific +//= require ../shared/shared +//= require_tree ../shared/directives +//= require_tree ../templates/shared //= require_tree ../templates/admin //= require ./admin_ofn //= require ./customers/customers diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 4e2bd45d70..f2d8f9ddcf 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -147,7 +147,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout if confirm("Are you sure?") $http( method: "DELETE" - url: "/api/products/" + product.id + url: "/api/v0/products/" + product.id ).success (data) -> $scope.products.splice $scope.products.indexOf(product), 1 DirtyProducts.deleteProduct product.id @@ -162,7 +162,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout if confirm(t("are_you_sure")) $http( method: "DELETE" - url: "/api/products/" + product.permalink_live + "/variants/" + variant.id + url: "/api/v0/products/" + product.permalink_live + "/variants/" + variant.id ).success (data) -> $scope.removeVariant(product, variant) else diff --git a/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee b/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee index ba37f0518f..7e7a8206c4 100644 --- a/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee +++ b/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee @@ -1,7 +1,7 @@ angular.module('admin.enterpriseFees').directive 'spreeDeleteResource', -> (scope, element, attrs) -> if scope.enterprise_fee.id - url = '/api/enterprise_fees/' + scope.enterprise_fee.id + url = '/api/v0/enterprise_fees/' + scope.enterprise_fee.id html = '' #var html = 'Delete Delete'; element.append html diff --git a/app/assets/javascripts/admin/index_utils/services/resources.js.coffee b/app/assets/javascripts/admin/index_utils/services/resources.js.coffee index 65dad204d4..58664b6895 100644 --- a/app/assets/javascripts/admin/index_utils/services/resources.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/resources.js.coffee @@ -1,5 +1,5 @@ angular.module("admin.indexUtils").factory "resources", ($resource) -> - LineItem = $resource '/api/orders/:order_number/line_items/:line_item_id.json', + LineItem = $resource '/api/v0/orders/:order_number/line_items/:line_item_id.json', { order_number: '@order_number', line_item_id: '@line_item_id'}, 'update': { method: 'PUT' } Customer = $resource '/admin/customers/:customer_id.json', diff --git a/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee b/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee index f21698da33..79e0dd6ce6 100644 --- a/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee @@ -1,5 +1,5 @@ angular.module('admin.orderCycles').factory('ExchangeProduct', ($resource) -> - ExchangeProductResource = $resource('/api/exchanges/:exchange_id/products.json', {}, { + ExchangeProductResource = $resource('/api/v0/exchanges/:exchange_id/products.json', {}, { 'index': { method: 'GET' } 'variant_count': { method: 'GET', params: { action_name: "variant_count" }} }) diff --git a/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee index b5ef2847b4..196ca47319 100644 --- a/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee @@ -9,7 +9,7 @@ angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUni if $scope.product.variant_unit == 'items' $scope.variant_unit_with_scale = 'items' else - $scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale + $scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale.replace(/\.0$/, ''); $scope.setFields = -> if $scope.variant_unit_with_scale == 'items' diff --git a/app/assets/javascripts/admin/products/controllers/units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/units_controller.js.coffee index a84f048580..df4cb42df4 100644 --- a/app/assets/javascripts/admin/products/controllers/units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/controllers/units_controller.js.coffee @@ -1,12 +1,13 @@ angular.module("admin.products") - .controller "unitsCtrl", ($scope, VariantUnitManager, OptionValueNamer) -> + .controller "unitsCtrl", ($scope, VariantUnitManager, OptionValueNamer, UnitPrices) -> $scope.product = { master: {} } $scope.product.master.product = $scope.product $scope.placeholder_text = "" - $scope.$watchCollection '[product.variant_unit_with_scale, product.master.unit_value_with_description]', -> + $scope.$watchCollection '[product.variant_unit_with_scale, product.master.unit_value_with_description, product.price, product.variant_unit_name]', -> $scope.processVariantUnitWithScale() $scope.processUnitValueWithDescription() + $scope.processUnitPrice() $scope.placeholder_text = new OptionValueNamer($scope.product.master).name() $scope.variant_unit_options = VariantUnitManager.variantUnitOptions() @@ -32,6 +33,14 @@ angular.module("admin.products") $scope.product.master.unit_value *= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale $scope.product.master.unit_description = match[3] + $scope.processUnitPrice = -> + price = $scope.product.price + scale = $scope.product.variant_unit_scale + unit_type = $scope.product.variant_unit + unit_value = $scope.product.master.unit_value + variant_unit_name = $scope.product.variant_unit_name + $scope.unit_price = UnitPrices.displayableUnitPrice(price, scale, unit_type, unit_value, variant_unit_name) + $scope.hasVariants = (product) -> Object.keys(product.variants).length > 0 diff --git a/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee index 2cceef9f1d..33c01542ff 100644 --- a/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee @@ -1,8 +1,24 @@ -angular.module("admin.products").controller "variantUnitsCtrl", ($scope, VariantUnitManager, $timeout) -> +angular.module("admin.products").controller "variantUnitsCtrl", ($scope, VariantUnitManager, $timeout, UnitPrices) -> $scope.unitName = (scale, type) -> VariantUnitManager.getUnitName(scale, type) + $scope.$watchCollection "[unit_value_human, variant.price]", -> + $scope.processUnitPrice() + + $scope.processUnitPrice = -> + if ($scope.variant) + price = $scope.variant.price + scale = $scope.scale + unit_type = angular.element("#product_variant_unit").val() + if (unit_type != "items") + $scope.updateValue() + unit_value = $scope.unit_value + else + unit_value = 1 + variant_unit_name = angular.element("#product_variant_unit_name").val() + $scope.unit_price = UnitPrices.displayableUnitPrice(price, scale, unit_type, unit_value, variant_unit_name) + $scope.scale = angular.element('#product_variant_unit_scale').val() $scope.updateValue = -> @@ -11,4 +27,6 @@ angular.module("admin.products").controller "variantUnitsCtrl", ($scope, Variant variant_unit_value = angular.element('#variant_unit_value').val() $scope.unit_value_human = variant_unit_value / $scope.scale + + $timeout -> $scope.processUnitPrice() $timeout -> $scope.updateValue() diff --git a/app/assets/javascripts/admin/products/products.js.coffee b/app/assets/javascripts/admin/products/products.js.coffee index cbca5abfcc..e8c02e9763 100644 --- a/app/assets/javascripts/admin/products/products.js.coffee +++ b/app/assets/javascripts/admin/products/products.js.coffee @@ -1 +1 @@ -angular.module("admin.products", ["textAngular", "admin.utils"]) +angular.module("admin.products", ["textAngular", "admin.utils", "OFNShared"]) diff --git a/app/assets/javascripts/admin/products/services/product_image_service.js.coffee b/app/assets/javascripts/admin/products/services/product_image_service.js.coffee index 8b0f273e8b..3d36d0a914 100644 --- a/app/assets/javascripts/admin/products/services/product_image_service.js.coffee +++ b/app/assets/javascripts/admin/products/services/product_image_service.js.coffee @@ -8,7 +8,7 @@ angular.module("ofn.admin").factory "ProductImageService", (FileUploader, SpreeA autoUpload: true configure: (product) => - @imageUploader.url = "/api/product_images/#{product.id}" + @imageUploader.url = "/api/v0/product_images/#{product.id}" @imagePreview = product.image_url @imageUploader.onSuccessItem = (image, response) => product.thumb_url = response.thumb_url diff --git a/app/assets/javascripts/admin/products/services/unit_prices.js.coffee b/app/assets/javascripts/admin/products/services/unit_prices.js.coffee new file mode 100644 index 0000000000..183c1576c4 --- /dev/null +++ b/app/assets/javascripts/admin/products/services/unit_prices.js.coffee @@ -0,0 +1,32 @@ +angular.module("admin.products").factory "UnitPrices", (VariantUnitManager, localizeCurrencyFilter) -> + class UnitPrices + @displayableUnitPrice: (price, scale, unit_type, unit_value, variant_unit_name) -> + if price && !isNaN(price) && unit_type && unit_value + value = localizeCurrencyFilter(UnitPrices.price(price, scale, unit_type, unit_value, variant_unit_name)) + unit = UnitPrices.unit(scale, unit_type, variant_unit_name) + return value + " / " + unit + return null + + @price: (price, scale, unit_type, unit_value) -> + price / @denominator(scale, unit_type, unit_value) + + @denominator: (scale, unit_type, unit_value) -> + unit = @unit(scale, unit_type) + if unit == "lb" + unit_value / 453.6 + else if unit == "kg" + unit_value / 1000 + else + unit_value + + @unit: (scale, unit_type, variant_unit_name = '') -> + if variant_unit_name.length > 0 + variant_unit_name + else if unit_type == "items" + "item" + else if VariantUnitManager.systemOfMeasurement(scale, unit_type) == "imperial" + "lb" + else if unit_type == "weight" + "kg" + else if unit_type == "volume" + "L" \ No newline at end of file diff --git a/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee b/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee index 7875347ac8..31a3a14bd9 100644 --- a/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee +++ b/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee @@ -67,3 +67,9 @@ angular.module("admin.products").factory "VariantUnitManager", (availableUnits) scaleSystem = @units[unitType][scale]['system'] (parseFloat(scale) for scale, scaleInfo of @units[unitType] when scaleInfo['system'] == scaleSystem).sort (a, b) -> a - b + + @systemOfMeasurement: (scale, unitType) -> + if @units[unitType][scale] + @units[unitType][scale]['system'] + else + 'custom' diff --git a/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee index e7e773a42a..f3d2128e20 100644 --- a/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee +++ b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee @@ -9,12 +9,12 @@ angular.module("admin.resources").factory 'EnterpriseResource', ($resource) -> 'update': method: 'PUT' 'removeLogo': - url: '/api/enterprises/:id/logo.json' + url: '/api/v0/enterprises/:id/logo.json' method: 'DELETE' 'removePromoImage': - url: '/api/enterprises/:id/promo_image.json' + url: '/api/v0/enterprises/:id/promo_image.json' method: 'DELETE' 'removeTermsAndConditions': - url: '/api/enterprises/:id/terms_and_conditions.json' + url: '/api/v0/enterprises/:id/terms_and_conditions.json' method: 'DELETE' }) diff --git a/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee index 534833d1c9..a6642072ab 100644 --- a/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee +++ b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee @@ -1,17 +1,17 @@ angular.module("admin.resources").factory 'OrderResource', ($resource) -> $resource('/admin/orders/:id/:action.json', {}, { 'index': - url: '/api/orders.json' + url: '/api/v0/orders.json' method: 'GET' 'update': method: 'PUT' 'capture': - url: '/api/orders/:id/capture.json' + url: '/api/v0/orders/:id/capture.json' method: 'PUT' params: id: '@id' 'ship': - url: '/api/orders/:id/ship.json' + url: '/api/v0/orders/:id/ship.json' method: 'PUT' params: id: '@id' diff --git a/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee index b630c1f8cd..7d842d8eed 100644 --- a/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee +++ b/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee @@ -1,6 +1,6 @@ angular.module("admin.resources").factory 'ProductResource', ($resource) -> $resource('/admin/product/:id/:action.json', {}, { 'index': - url: '/api/products/bulk_products.json' + url: '/api/v0/products/bulk_products.json' method: 'GET' }) diff --git a/app/assets/javascripts/admin/services/bulk_products.js.coffee b/app/assets/javascripts/admin/services/bulk_products.js.coffee index 72e9715c9e..1c33fcb6cf 100644 --- a/app/assets/javascripts/admin/services/bulk_products.js.coffee +++ b/app/assets/javascripts/admin/services/bulk_products.js.coffee @@ -10,8 +10,8 @@ angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetche angular.extend(@pagination, data.pagination) cloneProduct: (product) -> - $http.post("/api/products/" + product.id + "/clone").success (data) => - dataFetcher("/api/products/" + data.id + "?template=bulk_show").then (newProduct) => + $http.post("/api/v0/products/" + product.id + "/clone").success (data) => + dataFetcher("/api/v0/products/" + data.id + "?template=bulk_show").then (newProduct) => @unpackProduct newProduct @insertProductAfter(product, newProduct) diff --git a/app/assets/javascripts/admin/tag_rules/controllers/tag_rules_controller.js.coffee b/app/assets/javascripts/admin/tag_rules/controllers/tag_rules_controller.js.coffee index 7576baf59d..315e0edb98 100644 --- a/app/assets/javascripts/admin/tag_rules/controllers/tag_rules_controller.js.coffee +++ b/app/assets/javascripts/admin/tag_rules/controllers/tag_rules_controller.js.coffee @@ -23,8 +23,6 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil preferred_customer_tags: (tag.text for tag in tagGroup.tags).join(",") type: "TagRule::#{ruleType}" switch ruleType - when "DiscountOrder" - newRule.calculator = { preferred_flat_percent: 0 } when "FilterShippingMethods" newRule.peferred_shipping_method_tags = [] newRule.preferred_matched_shipping_methods_visibility = "visible" diff --git a/app/assets/javascripts/admin/tag_rules/directives/new_rule_dialog.js.coffee b/app/assets/javascripts/admin/tag_rules/directives/new_rule_dialog.js.coffee index 8ac7cfb68c..85af4bca7a 100644 --- a/app/assets/javascripts/admin/tag_rules/directives/new_rule_dialog.js.coffee +++ b/app/assets/javascripts/admin/tag_rules/directives/new_rule_dialog.js.coffee @@ -8,7 +8,6 @@ angular.module("admin.tagRules").directive 'newTagRuleDialog', ($compile, $templ template = $compile($templateCache.get('admin/new_tag_rule_dialog.html'))(scope) scope.ruleTypes = [ - # { id: "DiscountOrder", name: 'Apply a discount to orders' } { id: "FilterProducts", name: t('js.tag_rules.show_hide_variants') } { id: "FilterShippingMethods", name: t('js.tag_rules.show_hide_shipping') } { id: "FilterPaymentMethods", name: t('js.tag_rules.show_hide_payment') } diff --git a/app/assets/javascripts/admin/utils/services/status_message.js.coffee b/app/assets/javascripts/admin/utils/services/status_message.js.coffee index 0d752cdcd9..42b549dd4c 100644 --- a/app/assets/javascripts/admin/utils/services/status_message.js.coffee +++ b/app/assets/javascripts/admin/utils/services/status_message.js.coffee @@ -1,11 +1,11 @@ -angular.module("admin.utils").factory "StatusMessage", ($timeout) -> +angular.module("admin.utils").factory "StatusMessage", -> new class StatusMessage types: - progress: {timeout: false, style: {color: '#ff9906'}} - alert: {timeout: 5000, style: {color: 'grey'}} - notice: {timeout: false, style: {color: 'grey'}} - success: {timeout: 5000, style: {color: '#9fc820'}} - failure: {timeout: false, style: {color: '#da5354'}} + progress: {style: {color: '#ff9906'}} + alert: {style: {color: 'grey'}} + notice: {style: {color: 'grey'}} + success: {style: {color: '#9fc820'}} + failure: {style: {color: '#da5354'}} statusMessage: text: "" @@ -25,13 +25,7 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) -> display: (type, text) -> @statusMessage.text = text @statusMessage.style = @types[type].style - $timeout.cancel @statusMessage.timeout if @statusMessage.timeout - timeout = @types[type].timeout - if timeout - @statusMessage.timeout = $timeout => - @clear() - , timeout, true - null # So we don't return weird timeouts + null clear: -> @statusMessage.text = '' diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index b890d2ffd5..51dc72be08 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -42,7 +42,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.fetchProducts() $scope.fetchProducts = -> - url = "/api/products/overridable?page=::page::;per_page=100" + url = "/api/v0/products/overridable?page=::page::;per_page=100" PagedFetcher.fetch url, $scope.addProducts $scope.addProducts = (data) -> diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index 66ac04511d..c6bfec6563 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -20,6 +20,8 @@ #= require ../shared/ng-infinite-scroll.min.js #= require ../shared/angular-local-storage.js #= require ../shared/angular-slideables.js +#= require ../shared/shared +#= require_tree ../shared/directives #= require angularjs-file-upload #= require i18n/translations diff --git a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee index f96d2d454f..4f1d935aec 100644 --- a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee @@ -24,7 +24,7 @@ Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, CurrentHub, $http, $scope.shopfront_loading = true $scope.toggle_tab(event) - $http.get("/api/shops/" + $scope.hub.id) + $http.get("/api/v0/shops/" + $scope.hub.id) .success (data) -> $scope.shopfront_loading = false $scope.hub = data diff --git a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee index 3aa5045bee..230592a7a6 100644 --- a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee @@ -24,7 +24,7 @@ Darkswarm.controller "ProducerNodeCtrl", ($scope, HashNavigation, $anchorScroll, $scope.shopfront_loading = true $scope.toggle_tab(event) - $http.get("/api/shops/" + $scope.producer.id) + $http.get("/api/v0/shops/" + $scope.producer.id) .success (data) -> $scope.shopfront_loading = false $scope.producer = data diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 453f05a2c3..86bc4ef0f2 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -10,7 +10,8 @@ window.Darkswarm = angular.module("Darkswarm", [ 'uiGmapgoogle-maps', 'duScroll', 'angularFileUpload', - 'angularSlideables' + 'angularSlideables', + 'OFNShared' ]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) -> $httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest' $httpProvider.defaults.headers.common['Accept'] = "application/json, text/javascript, */*" diff --git a/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee b/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee index 183d828d03..dce6d4c5e5 100644 --- a/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee @@ -3,7 +3,15 @@ Darkswarm.directive "bodyScroll", ($rootScope, BodyScroll) -> scope: true link: (scope, elem, attrs) -> $rootScope.$on "toggleBodyScroll", -> - if BodyScroll.disabled - elem.addClass "disable-scroll" + if BodyScroll.disabled && document.body.scrollHeight > document.body.clientHeight + document.body.style.top = "-#{window.scrollY}px" + document.body.style.position = 'fixed' + document.body.style.overflowY = 'scroll' + document.body.style.width = '100%' else - elem.removeClass "disable-scroll" + scrollY = parseInt(document.body.style.top) * -1 + document.body.style.position = '' + document.body.style.top = '' + document.body.style.overflowY = '' + document.body.style.width = '' + window.scrollTo(0, scrollY) if scrollY diff --git a/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee b/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee index d23d365087..4fe5d1a799 100644 --- a/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee @@ -4,4 +4,5 @@ Darkswarm.directive "shopVariantWithUnitPrice", -> templateUrl: 'shop_variant_with_unit_price.html' scope: variant: '=' + show_unit_price: '=showunitprice' controller: 'ShopVariantCtrl' diff --git a/app/assets/javascripts/darkswarm/services/customer.js.coffee b/app/assets/javascripts/darkswarm/services/customer.js.coffee index fa3b1b532f..7bad3a7b89 100644 --- a/app/assets/javascripts/darkswarm/services/customer.js.coffee +++ b/app/assets/javascripts/darkswarm/services/customer.js.coffee @@ -1,5 +1,5 @@ angular.module("Darkswarm").factory 'Customer', ($resource, $injector, Messages) -> - Customer = $resource('/api/customers/:id/:action.json', {}, { + Customer = $resource('/api/v0/customers/:id/:action.json', {}, { 'index': method: 'GET' isArray: true diff --git a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee index c8cd64e93a..13cd140cc4 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee @@ -8,5 +8,5 @@ Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) -> autoUpload: true configure: (enterprise) => - @imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image" + @imageUploader.url = "/api/v0/enterprises/#{enterprise.id}/update_image" @imageUploader.onSuccessItem = (image, response) => @imageSrc = response diff --git a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee index 37dafef776..4eab4d79ac 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee @@ -5,7 +5,7 @@ Darkswarm.factory "EnterpriseModal", ($modal, $rootScope, $http)-> scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1 - $http.get("/api/shops/" + enterprise.id).success (data) -> + $http.get("/api/v0/shops/" + enterprise.id).success (data) -> scope.enterprise = data $modal.open(templateUrl: "enterprise_modal.html", scope: scope) .error (data) -> diff --git a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee index 4d1bda61c8..2db0cedba5 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee @@ -18,7 +18,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, Loading.message = t('creating') + " " + @enterprise.name $http( method: "POST" - url: "/api/enterprises" + url: "/api/v0/enterprises" data: enterprise: @prepare() use_geocoder: @useGeocoder() @@ -43,7 +43,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, Loading.message = t('updating') + " " + @enterprise.name $http( method: "PUT" - url: "/api/enterprises/#{@enterprise.id}" + url: "/api/v0/enterprises/#{@enterprise.id}" data: enterprise: @prepare() use_geocoder: @useGeocoder() diff --git a/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee b/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee index ba8d5266fe..b8dd81d42c 100644 --- a/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee @@ -1,21 +1,21 @@ Darkswarm.factory 'OrderCycleResource', ($resource) -> - $resource('/api/order_cycles/:id.json', {}, { + $resource('/api/v0/order_cycles/:id.json', {}, { 'products': method: 'GET' isArray: true - url: '/api/order_cycles/:id/products.json' + url: '/api/v0/order_cycles/:id/products.json' params: id: '@id' 'taxons': method: 'GET' isArray: true - url: '/api/order_cycles/:id/taxons.json' + url: '/api/v0/order_cycles/:id/taxons.json' params: id: '@id' 'properties': method: 'GET' isArray: true - url: '/api/order_cycles/:id/properties.json' + url: '/api/v0/order_cycles/:id/properties.json' params: id: '@id' }) diff --git a/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee index 2726b25496..946eb21832 100644 --- a/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee +++ b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee @@ -1,7 +1,7 @@ Darkswarm.factory 'ShopsResource', ($resource) -> - $resource('/api/shops/:id.json', {}, { + $resource('/api/v0/shops/:id.json', {}, { 'closed_shops': method: 'GET' isArray: true - url: '/api/shops/closed_shops.json' + url: '/api/v0/shops/closed_shops.json' }) diff --git a/app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee b/app/assets/javascripts/shared/directives/question_mark_tooltip.js.coffee similarity index 63% rename from app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee rename to app/assets/javascripts/shared/directives/question_mark_tooltip.js.coffee index e93a9779fe..3b5793d379 100644 --- a/app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee +++ b/app/assets/javascripts/shared/directives/question_mark_tooltip.js.coffee @@ -1,17 +1,19 @@ -Darkswarm.directive "questionMarkWithTooltip", ($tooltip)-> + +OFNShared.directive "questionMarkWithTooltip", ($tooltip)-> # We use the $tooltip service from Angular foundation to give us boilerplate # Subsequently we patch the scope, template and restrictions tooltip = $tooltip 'questionMarkWithTooltip', 'questionMarkWithTooltip', 'click' tooltip.scope = context: "=" - tooltip.templateUrl = "question_mark_with_tooltip_icon.html" + key: "=" + tooltip.templateUrl = "shared/question_mark_with_tooltip_icon.html" tooltip.replace = true tooltip.restrict = 'E' tooltip # This is automatically referenced via naming convention in $tooltip -Darkswarm.directive 'questionMarkWithTooltipPopup', -> +OFNShared.directive 'questionMarkWithTooltipPopup', -> restrict: 'EA' replace: true - templateUrl: 'question_mark_with_tooltip.html' + templateUrl: 'shared/question_mark_with_tooltip.html' scope: false diff --git a/app/assets/javascripts/shared/shared.js.coffee b/app/assets/javascripts/shared/shared.js.coffee new file mode 100644 index 0000000000..fffd667d1e --- /dev/null +++ b/app/assets/javascripts/shared/shared.js.coffee @@ -0,0 +1,4 @@ +window.OFNShared = angular.module("OFNShared", [ + "mm.foundation" +]).config ($httpProvider) -> + $httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*" diff --git a/app/assets/javascripts/templates/bulk_buy_modal.html.haml b/app/assets/javascripts/templates/bulk_buy_modal.html.haml index 05868dab77..385fe23bef 100644 --- a/app/assets/javascripts/templates/bulk_buy_modal.html.haml +++ b/app/assets/javascripts/templates/bulk_buy_modal.html.haml @@ -2,12 +2,21 @@ .columns.small-12 %h3{"ng-bind" => "::variant.extended_name"} -.row.variant-bulk-buy-price-summary - .columns.small-6 - .variant-unit {{ ::variant.unit_to_display }} - .columns.small-6 +.flex.variant-bulk-buy-price-summary{style: "justify-content: space-around;"} + .variant-unit + {{ ::variant.unit_to_display }} + .div {{ variant.line_item.total_price | localizeCurrency }} + .unit-price{"ng-if": "show_unit_price"} + %question-mark-with-tooltip{"question-mark-with-tooltip": "_", + "question-mark-with-tooltip-append-to-body": "true", + "question-mark-with-tooltip-placement": "top", + "question-mark-with-tooltip-animation": true, + style: "margin-right: 5px", + key: "'js.shopfront.unit_price_tooltip'"} + {{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }} + .row .columns.small-12.medium-6 .variant-bulk-buy-quantity-label diff --git a/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml b/app/assets/javascripts/templates/shared/question_mark_with_tooltip.html.haml similarity index 82% rename from app/assets/javascripts/templates/question_mark_with_tooltip.html.haml rename to app/assets/javascripts/templates/shared/question_mark_with_tooltip.html.haml index 75a697fe12..9c68ca47c4 100644 --- a/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml +++ b/app/assets/javascripts/templates/shared/question_mark_with_tooltip.html.haml @@ -1,6 +1,6 @@ .joyride-tip-guide.question-mark-tooltip{class: "{{ context }}", ng: {class: "{ in: tt_isOpen, fade: tt_animation }", show: "tt_isOpen"}} .background{ng: {click: "tt_isOpen = false"}} .joyride-content-wrapper - {{ "js.shopfront.unit_price_tooltip" | t }} + {{ key | t }} %span.joyride-nub.bottom \ No newline at end of file diff --git a/app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml b/app/assets/javascripts/templates/shared/question_mark_with_tooltip_icon.html.haml similarity index 100% rename from app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml rename to app/assets/javascripts/templates/shared/question_mark_with_tooltip_icon.html.haml diff --git a/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml index 4a3d2d7211..382839712d 100644 --- a/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml +++ b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml @@ -12,8 +12,9 @@ %question-mark-with-tooltip{"question-mark-with-tooltip" => "_", "question-mark-with-tooltip-append-to-body" => "true", "question-mark-with-tooltip-placement" => "top", - "question-mark-with-tooltip-animation" => true} - {{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }} + "question-mark-with-tooltip-animation" => true, + key: "'js.shopfront.unit_price_tooltip'"} + {{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }} .medium-2.large-2.columns.total-price %span{"ng-class" => "{filled: variant.line_item.total_price}"} diff --git a/app/assets/stylesheets/admin/all.scss b/app/assets/stylesheets/admin/all.scss index 12635372f3..bafa929c49 100644 --- a/app/assets/stylesheets/admin/all.scss +++ b/app/assets/stylesheets/admin/all.scss @@ -48,3 +48,6 @@ @import 'components/*'; @import 'pages/*'; @import '*'; + +@import "../shared/question-mark-icon"; +@import "question-mark-tooltip"; diff --git a/app/assets/stylesheets/admin/question-mark-tooltip.scss b/app/assets/stylesheets/admin/question-mark-tooltip.scss new file mode 100644 index 0000000000..8247a5b5b8 --- /dev/null +++ b/app/assets/stylesheets/admin/question-mark-tooltip.scss @@ -0,0 +1,18 @@ +.joyride-tip-guide { + background: $color-3; + color: $white; + font-family: inherit; + font-weight: $font-weight-normal; + position: absolute; + z-index: 101; + padding: 5px 15px; + + .joyride-nub.bottom { + border: 10px solid; + display: block; + height: 0; + position: absolute; + width: 0; + } +} + diff --git a/app/assets/stylesheets/darkswarm/_shop-inputs.scss b/app/assets/stylesheets/darkswarm/_shop-inputs.scss index e9bc97eb86..8f21540a8d 100644 --- a/app/assets/stylesheets/darkswarm/_shop-inputs.scss +++ b/app/assets/stylesheets/darkswarm/_shop-inputs.scss @@ -117,6 +117,13 @@ button.bulk-buy-add.variant-quantity { } } +// Hide number arrows on Chrome, Safari, Edge, Opera +.variant-quantity::-webkit-outer-spin-button, +.variant-quantity::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + .variant-bulk-buy-price-summary { color: $disabled-med; margin-bottom: 1em; diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index 7698726035..2a7eefd1e9 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -21,3 +21,5 @@ ofn-modal { display: block; } + +@import "../shared/question-mark-icon"; diff --git a/app/assets/stylesheets/darkswarm/ui.scss b/app/assets/stylesheets/darkswarm/ui.scss index c13c51f024..b2177013cc 100644 --- a/app/assets/stylesheets/darkswarm/ui.scss +++ b/app/assets/stylesheets/darkswarm/ui.scss @@ -165,7 +165,3 @@ a.button.large { .flex { display: flex; } - -.disable-scroll { - overflow: hidden; -} diff --git a/app/assets/stylesheets/darkswarm/question-mark-icon.scss b/app/assets/stylesheets/shared/question-mark-icon.scss similarity index 86% rename from app/assets/stylesheets/darkswarm/question-mark-icon.scss rename to app/assets/stylesheets/shared/question-mark-icon.scss index 82728f2ea2..0f4901a98f 100644 --- a/app/assets/stylesheets/darkswarm/question-mark-icon.scss +++ b/app/assets/stylesheets/shared/question-mark-icon.scss @@ -1,3 +1,5 @@ +@import "variables/variables"; + .unit-price { display: flex; align-items: center; @@ -26,14 +28,27 @@ background-image: none; background-color: $teal-500; + &:focus { + outline: 0; + } + &::before { @include icon-font; content: ""; color: $white; + vertical-align: super; } } } +// Question mark icon into a field +.field .question-mark-icon { + width: 15px; + min-width: 15px; + height: 15px; + margin-left: 2px; +} + .joyride-tip-guide.question-mark-tooltip { width: 16rem; max-width: 65%; @@ -41,6 +56,7 @@ margin-left: -7.4rem; margin-top: -0.1rem; background-color: transparent; + z-index: $modal-zIndex + 1; .background { position: fixed; diff --git a/app/assets/stylesheets/shared/variables/variables.scss b/app/assets/stylesheets/shared/variables/variables.scss new file mode 100644 index 0000000000..866a20d160 --- /dev/null +++ b/app/assets/stylesheets/shared/variables/variables.scss @@ -0,0 +1,28 @@ +$padding-small: 0.5rem; +$radius-small: 0.25em; +$white: #fff; +$dynamic-blue: #3d8dd1; +$teal-500: #0096ad; + +/* Defined in foundation-rails components/_reveal.scss */ +$modal-zIndex: 1005; + +@font-face { + font-family: 'OFN'; + src: font-url('OFN-v2.eot'); + src: font-url('OFN-v2.eot') format('embedded-opentype'), + font-url('OFN-v2.woff') format('woff'), + font-url('OFN-v2.ttf') format('truetype'), + font-url('OFN-v2.svg') format('svg'); + font-weight: normal; + font-style: normal; +} + +@mixin icon-font { + font-family: "OFN"; + display: inline-block; + font-weight: normal; + font-style: normal; + font-variant: normal; + text-transform: none; +} diff --git a/app/components/distributor_title_component.rb b/app/components/distributor_title_component.rb new file mode 100644 index 0000000000..bd2c78c7ab --- /dev/null +++ b/app/components/distributor_title_component.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class DistributorTitleComponent < ViewComponent::Base + def initialize(name:) + @name = name + end +end diff --git a/app/components/distributor_title_component/distributor_title_component.html.haml b/app/components/distributor_title_component/distributor_title_component.html.haml new file mode 100644 index 0000000000..218f0570aa --- /dev/null +++ b/app/components/distributor_title_component/distributor_title_component.html.haml @@ -0,0 +1 @@ +%h3= @name diff --git a/app/components/example_component.rb b/app/components/example_component.rb new file mode 100644 index 0000000000..ec57557e2a --- /dev/null +++ b/app/components/example_component.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class ExampleComponent < ViewComponent::Base + def initialize(title:) + @title = title + end +end diff --git a/app/components/example_component/example_component.html.haml b/app/components/example_component/example_component.html.haml new file mode 100644 index 0000000000..d0ac42c229 --- /dev/null +++ b/app/components/example_component/example_component.html.haml @@ -0,0 +1 @@ +%h1 #{@title} diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 4a2f4242e9..e655b0ae8e 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -18,21 +18,13 @@ module Admin format.html format.json do render json: @collection, - each_serializer: index_each_serializer, + each_serializer: ::Api::Admin::CustomerWithBalanceSerializer, tag_rule_mapping: tag_rule_mapping, customer_tags: customer_tags_by_id end end end - def index_each_serializer - if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, spree_current_user) - ::Api::Admin::CustomerWithBalanceSerializer - else - ::Api::Admin::CustomerWithCalculatedBalanceSerializer - end - end - def show render_as_json @customer, ams_prefix: params[:ams_prefix] end @@ -53,15 +45,12 @@ module Admin # copy of Admin::ResourceController without flash notice def destroy - invoke_callbacks(:destroy, :before) if @object.destroy - invoke_callbacks(:destroy, :after) respond_with(@object) do |format| format.html { redirect_to location_after_destroy } format.js { render partial: "spree/admin/shared/destroy" } end else - invoke_callbacks(:destroy, :fails) respond_with(@object) do |format| format.html { redirect_to location_after_destroy } format.json { render json: { errors: @object.errors.full_messages }, status: :conflict } @@ -73,21 +62,18 @@ module Admin def collection if json_request? && params[:enterprise_id].present? - customers_relation. - includes(:bill_address, :ship_address, user: :credit_cards) + CustomersWithBalance.new(managed_enterprise_id).query. + includes( + :enterprise, + { bill_address: [:state, :country] }, + { ship_address: [:state, :country] }, + user: :credit_cards + ) else Customer.where('1=0') end end - def customers_relation - if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, spree_current_user) - CustomersWithBalance.new(managed_enterprise_id).query - else - Customer.of(managed_enterprise_id) - end - end - def managed_enterprise_id @managed_enterprise_id ||= Enterprise.managed_by(spree_current_user). select('enterprises.id').find_by(id: params[:enterprise_id]) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 86b521cb1c..9470807f6e 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -48,12 +48,11 @@ module Admin end def update - invoke_callbacks(:update, :before) tag_rules_attributes = params[object_name].delete :tag_rules_attributes update_tag_rules(tag_rules_attributes) if tag_rules_attributes.present? update_enterprise_notifications + if @object.update(enterprise_params) - invoke_callbacks(:update, :after) flash[:success] = flash_message_for(@object, :successfully_updated) respond_with(@object) do |format| format.html { redirect_to location_after_save } @@ -61,7 +60,6 @@ module Admin format.json { render_as_json @object, ams_prefix: 'index', spree_current_user: spree_current_user } end else - invoke_callbacks(:update, :fails) respond_with(@object) do |format| format.json { render json: { errors: @object.errors.messages }, status: :unprocessable_entity } end @@ -219,7 +217,6 @@ module Admin tag_rules_attributes.select{ |_i, attrs| attrs[:type].present? }.each do |_i, attrs| rule = @object.tag_rules.find_by(id: attrs.delete(:id)) || attrs[:type].constantize.new(enterprise: @object) - create_calculator_for(rule, attrs) if rule.type == "TagRule::DiscountOrder" && rule.calculator.nil? rule.update(attrs.permit(PermittedAttributes::TagRules.attributes)) end diff --git a/app/controllers/admin/resource_controller.rb b/app/controllers/admin/resource_controller.rb index b316046b4b..3510093c0d 100644 --- a/app/controllers/admin/resource_controller.rb +++ b/app/controllers/admin/resource_controller.rb @@ -1,5 +1,3 @@ -require 'action_callbacks' - module Admin class ResourceController < Spree::Admin::BaseController helper_method :new_object_url, :edit_object_url, :object_url, :collection_url @@ -11,7 +9,6 @@ module Admin respond_to :js, except: [:show, :index] def new - invoke_callbacks(:new_action, :before) respond_with(@object) do |format| format.html { render layout: !request.xhr? } format.js { render layout: false } @@ -26,32 +23,26 @@ module Admin end def update - invoke_callbacks(:update, :before) if @object.update(permitted_resource_params) - invoke_callbacks(:update, :after) flash[:success] = flash_message_for(@object, :successfully_updated) respond_with(@object) do |format| format.html { redirect_to location_after_save } format.js { render layout: false } end else - invoke_callbacks(:update, :fails) respond_with(@object) end end def create - invoke_callbacks(:create, :before) @object.attributes = permitted_resource_params if @object.save - invoke_callbacks(:create, :after) flash[:success] = flash_message_for(@object, :successfully_created) respond_with(@object) do |format| format.html { redirect_to location_after_save } format.js { render layout: false } end else - invoke_callbacks(:create, :fails) respond_with(@object) end end @@ -67,16 +58,13 @@ module Admin end def destroy - invoke_callbacks(:destroy, :before) if @object.destroy - invoke_callbacks(:destroy, :after) flash[:success] = flash_message_for(@object, :successfully_removed) respond_with(@object) do |format| format.html { redirect_to collection_url } format.js { render partial: "spree/admin/shared/destroy" } end else - invoke_callbacks(:destroy, :fails) respond_with(@object) do |format| format.html { redirect_to collection_url } end @@ -92,7 +80,6 @@ module Admin class << self attr_accessor :parent_data - attr_accessor :callbacks def belongs_to(model_name, options = {}) @parent_data ||= {} @@ -100,26 +87,6 @@ module Admin @parent_data[:model_class] = model_name.to_s.classify.constantize @parent_data[:find_by] = options[:find_by] || :id end - - def new_action - @callbacks ||= {} - @callbacks[:new_action] ||= ActionCallbacks.new - end - - def create - @callbacks ||= {} - @callbacks[:create] ||= ActionCallbacks.new - end - - def update - @callbacks ||= {} - @callbacks[:update] ||= ActionCallbacks.new - end - - def destroy - @callbacks ||= {} - @callbacks[:destroy] ||= ActionCallbacks.new - end end def model_class @@ -212,17 +179,6 @@ module Admin collection_url end - def invoke_callbacks(action, callback_type) - callbacks = self.class.callbacks || {} - return if callbacks[action].nil? - - case callback_type.to_sym - when :before then callbacks[action].before_methods.each { |method| __send__ method } - when :after then callbacks[action].after_methods.each { |method| __send__ method } - when :fails then callbacks[action].fails_methods.each { |method| __send__ method } - end - end - # URL helpers def new_object_url(options = {}) if parent_data.present? diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 8d375b3979..c88af92c32 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -9,7 +9,8 @@ module Admin before_action :editable_order_cycle_ids_for_create, only: [:create] before_action :editable_order_cycle_ids_for_update, only: [:update] before_action :check_dependent_subscriptions, only: [:destroy] - update.after :sync_subscriptions_for_update + + after_action :sync_subscriptions_for_update, only: :update respond_to :json @@ -120,7 +121,7 @@ module Admin end def sync_subscriptions_for_update - return unless params[:schedule][:order_cycle_ids] + return unless params[:schedule][:order_cycle_ids] && @object.errors.blank? sync_subscriptions end diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb deleted file mode 100644 index 3ec78c85d4..0000000000 --- a/app/controllers/api/base_controller.rb +++ /dev/null @@ -1,103 +0,0 @@ -# Base controller for OFN's API -require_dependency 'spree/api/controller_setup' -require "spree/core/controller_helpers/ssl" - -module Api - class BaseController < ActionController::Metal - include RawParams - include ActionController::StrongParameters - include ActionController::RespondWith - include Spree::Api::ControllerSetup - include Spree::Core::ControllerHelpers::SSL - include ::ActionController::Head - include ::ActionController::ConditionalGet - include ActionView::Layouts - - layout false - - attr_accessor :current_api_user - - before_action :set_content_type - before_action :authenticate_user - - rescue_from Exception, with: :error_during_processing - rescue_from CanCan::AccessDenied, with: :unauthorized - rescue_from ActiveRecord::RecordNotFound, with: :not_found - - helper Spree::Api::ApiHelpers - - ssl_allowed - - # Include these because we inherit from ActionController::Metal - # rather than ActionController::Base and these are required for AMS - include ActionController::Serialization - include ActionController::UrlFor - include Rails.application.routes.url_helpers - - use_renderers :json - check_authorization - - def respond_with_conflict(json_hash) - render json: json_hash, status: :conflict - end - - private - - # Use logged in user (spree_current_user) for API authentication (current_api_user) - def authenticate_user - return if @current_api_user = spree_current_user - - if api_key.blank? - # An anonymous user - @current_api_user = Spree.user_class.new - return - end - - return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s) - - invalid_api_key - end - - def set_content_type - headers["Content-Type"] = "application/json" - end - - def error_during_processing(exception) - Bugsnag.notify(exception) - - render(json: { exception: exception.message }, - status: :unprocessable_entity) && return - end - - def current_ability - Spree::Ability.new(current_api_user) - end - - def api_key - request.headers["X-Spree-Token"] || params[:token] - end - helper_method :api_key - - def invalid_resource!(resource) - @resource = resource - render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"), - errors: @resource.errors }, - status: :unprocessable_entity) - end - - def invalid_api_key - render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") }, - status: :unauthorized) && return - end - - def unauthorized - render(json: { error: I18n.t(:unauthorized, scope: "spree.api") }, - status: :unauthorized) && return - end - - def not_found - render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") }, - status: :not_found) && return - end - end -end diff --git a/app/controllers/api/customers_controller.rb b/app/controllers/api/customers_controller.rb deleted file mode 100644 index 7cb702a824..0000000000 --- a/app/controllers/api/customers_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Api - class CustomersController < Api::BaseController - skip_authorization_check only: :index - - def index - @customers = current_api_user.customers - render json: @customers, each_serializer: CustomerSerializer - end - - def update - @customer = Customer.find(params[:id]) - authorize! :update, @customer - - client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges] - - if @customer.update(customer_params) - add_recurring_payment_info(client_secret) - render json: @customer, serializer: CustomerSerializer, status: :ok - else - invalid_resource!(@customer) - end - end - - private - - def add_recurring_payment_info(client_secret) - return unless client_secret - - @customer.gateway_recurring_payment_client_secret = client_secret - @customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id - end - - def customer_params - params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges) - end - end -end diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb deleted file mode 100644 index d9b619ab8e..0000000000 --- a/app/controllers/api/enterprise_attachment_controller.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require 'api/admin/enterprise_serializer' - -module Api - class EnterpriseAttachmentController < Api::BaseController - class MissingImplementationError < StandardError; end - class UnknownEnterpriseAuthorizationActionError < StandardError; end - - before_action :load_enterprise - - respond_to :json - - def destroy - return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message) unless @enterprise.public_send("#{attachment_name}?") - - @enterprise.update!(attachment_name => nil) - render json: @enterprise, serializer: Admin::EnterpriseSerializer, spree_current_user: spree_current_user - end - - protected - - def attachment_name - raise MissingImplementationError, "Method attachment_name should be defined" - end - - def enterprise_authorize_action - raise MissingImplementationError, "Method enterprise_authorize_action should be defined" - end - - def load_enterprise - @enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s) - raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank? - - authorize!(enterprise_authorize_action, @enterprise) - end - - def destroy_attachment_does_not_exist_error_message - I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist") - end - end -end diff --git a/app/controllers/api/enterprise_fees_controller.rb b/app/controllers/api/enterprise_fees_controller.rb deleted file mode 100644 index 3252961f97..0000000000 --- a/app/controllers/api/enterprise_fees_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Api - class EnterpriseFeesController < Api::BaseController - respond_to :json - - def destroy - authorize! :destroy, enterprise_fee - - if enterprise_fee.destroy - render plain: I18n.t(:successfully_removed), status: :no_content - else - render plain: enterprise_fee.errors.full_messages.first, status: :forbidden - end - end - - private - - def enterprise_fee - @enterprise_fee ||= EnterpriseFee.find_by id: params[:id] - end - end -end diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb deleted file mode 100644 index 76ad7782c2..0000000000 --- a/app/controllers/api/enterprises_controller.rb +++ /dev/null @@ -1,82 +0,0 @@ -module Api - class EnterprisesController < Api::BaseController - include GeocodeEnterpriseAddress - - before_action :override_owner, only: [:create, :update] - before_action :check_type, only: :update - before_action :override_sells, only: [:create, :update] - before_action :override_visible, only: [:create, :update] - respond_to :json - - def create - authorize! :create, Enterprise - - # params[:user_ids] breaks the enterprise creation - # We remove them from params and save them after creating the enterprise - user_ids = enterprise_params.delete(:user_ids) - @enterprise = Enterprise.new(enterprise_params) - if @enterprise.save - geocode_address_if_use_geocoder - @enterprise.user_ids = user_ids - render json: @enterprise.id, status: :created - else - invalid_resource!(@enterprise) - end - end - - def update - @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) - authorize! :update, @enterprise - - if @enterprise.update(enterprise_params) - geocode_address_if_use_geocoder - render json: @enterprise.id, status: :ok - else - invalid_resource!(@enterprise) - end - end - - def update_image - @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) - authorize! :update, @enterprise - - if params[:logo] && @enterprise.update( logo: params[:logo] ) - render plain: @enterprise.logo.url(:medium), status: :ok - elsif params[:promo] && @enterprise.update( promo_image: params[:promo] ) - render plain: @enterprise.promo_image.url(:medium), status: :ok - else - invalid_resource!(@enterprise) - end - end - - private - - def override_owner - enterprise_params[:owner_id] = current_api_user.id - end - - def check_type - enterprise_params.delete :type unless current_api_user.admin? - end - - def override_sells - has_hub = current_api_user.owned_enterprises.is_hub.any? - new_enterprise_is_producer = !!enterprise_params[:is_primary_producer] - - enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer - 'any' - else - 'unspecified' - end - end - - def override_visible - enterprise_params[:visible] = false - end - - def enterprise_params - @enterprise_params ||= PermittedAttributes::Enterprise.new(params).call. - to_h.with_indifferent_access - end - end -end diff --git a/app/controllers/api/exchange_products_controller.rb b/app/controllers/api/exchange_products_controller.rb deleted file mode 100644 index b43321841c..0000000000 --- a/app/controllers/api/exchange_products_controller.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -# This controller lists products that can be added to an exchange -# -# Pagination is optional and can be required by using param[:page] -module Api - class ExchangeProductsController < Api::BaseController - include PaginationData - DEFAULT_PER_PAGE = 100 - - skip_authorization_check only: [:index] - - # If exchange_id is present in the URL: - # Lists Products that can be added to that Exchange - # - # If exchange_id is not present in the URL: - # Lists Products of the Enterprise given that can be added to the given Order Cycle - # In this case parameters are: enterprise_id, order_cycle_id and incoming - # (order_cycle_id is not necessary for incoming exchanges) - def index - if exchange_params[:exchange_id].present? - load_data_from_exchange - else - load_data_from_other_params - end - - render_variant_count && return if params[:action_name] == "variant_count" - - render_paginated_products paginated_products - end - - private - - def render_variant_count - render plain: { - count: variants.count - }.to_json - end - - def variants - renderer.exchange_variants(@incoming, @enterprise) - end - - def products - renderer.exchange_products(@incoming, @enterprise) - end - - def renderer - @renderer ||= ExchangeProductsRenderer. - new(@order_cycle, spree_current_user) - end - - def paginated_products - return products unless pagination_required? - - products. - page(params[:page]). - per(params[:per_page] || DEFAULT_PER_PAGE) - end - - def load_data_from_exchange - exchange = Exchange.find_by(id: exchange_params[:exchange_id]) - - @order_cycle = exchange.order_cycle - @incoming = exchange.incoming - @enterprise = exchange.sender - end - - def load_data_from_other_params - @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id]) - - # This will be a string (eg "true") when it arrives via params, but we want a boolean - @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming] - - if exchange_params[:order_cycle_id] - @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id]) - elsif !@incoming - raise "order_cycle_id is required to list products for new outgoing exchange" - end - end - - def render_paginated_products(paginated_products) - serialized_products = ActiveModel::ArraySerializer.new( - paginated_products, - each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer, - order_cycle: @order_cycle - ) - - render json: { - products: serialized_products, - pagination: pagination_data(paginated_products) - } - end - - def exchange_params - params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming). - to_h.with_indifferent_access - end - end -end diff --git a/app/controllers/api/logos_controller.rb b/app/controllers/api/logos_controller.rb deleted file mode 100644 index 0c4b4c2f45..0000000000 --- a/app/controllers/api/logos_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Api - class LogosController < Api::EnterpriseAttachmentController - private - - def attachment_name - :logo - end - - def enterprise_authorize_action - case action_name.to_sym - when :destroy - :remove_logo - end - end - end -end diff --git a/app/controllers/api/order_cycles_controller.rb b/app/controllers/api/order_cycles_controller.rb deleted file mode 100644 index c40ec641b2..0000000000 --- a/app/controllers/api/order_cycles_controller.rb +++ /dev/null @@ -1,101 +0,0 @@ -module Api - class OrderCyclesController < Api::BaseController - include EnterprisesHelper - include ApiActionCaching - - skip_authorization_check - skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties] - - caches_action :taxons, :properties, - expires_in: CacheService::FILTERS_EXPIRY, - cache_path: proc { |controller| controller.request.url } - - def products - return render_no_products unless order_cycle.open? - - products = ProductsRenderer.new( - distributor, - order_cycle, - customer, - search_params - ).products_json - - render plain: products - rescue ProductsRenderer::NoProducts - render_no_products - end - - def taxons - taxons = Spree::Taxon. - joins(:products). - where(spree_products: { id: distributed_products }). - select('DISTINCT spree_taxons.*') - - render plain: ActiveModel::ArraySerializer.new( - taxons, each_serializer: Api::TaxonSerializer - ).to_json - end - - def properties - render plain: ActiveModel::ArraySerializer.new( - product_properties | producer_properties, each_serializer: Api::PropertySerializer - ).to_json - end - - private - - def render_no_products - render status: :not_found, json: {} - end - - def product_properties - Spree::Property. - joins(:products). - where(spree_products: { id: distributed_products }). - select('DISTINCT spree_properties.*') - end - - def producer_properties - producers = Enterprise. - joins(:supplied_products). - where(spree_products: { id: distributed_products }) - - Spree::Property. - joins(:producer_properties). - where(producer_properties: { producer_id: producers }). - select('DISTINCT spree_properties.*') - end - - def search_params - permitted_search_params = params.slice :q, :page, :per_page - - if permitted_search_params.key? :q - permitted_search_params[:q].slice!(*permitted_ransack_params) - end - - permitted_search_params - end - - def permitted_ransack_params - [:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont, - :properties_id_or_supplier_properties_id_in_any, - :primary_taxon_id_in_any] - end - - def distributor - @distributor ||= Enterprise.find_by(id: params[:distributor]) - end - - def order_cycle - @order_cycle ||= OrderCycle.find_by(id: params[:id]) - end - - def customer - @current_api_user.andand.customer_of(distributor) || nil - end - - def distributed_products - OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation - end - end -end diff --git a/app/controllers/api/orders_controller.rb b/app/controllers/api/orders_controller.rb deleted file mode 100644 index a0a4a0c013..0000000000 --- a/app/controllers/api/orders_controller.rb +++ /dev/null @@ -1,67 +0,0 @@ -module Api - class OrdersController < Api::BaseController - include PaginationData - - def show - authorize! :read, order - render json: order, serializer: Api::OrderDetailedSerializer, current_order: order - end - - def index - authorize! :admin, Spree::Order - - orders = SearchOrders.new(params, current_api_user).orders - - render json: { - orders: serialized_orders(orders), - pagination: pagination_data(orders) - } - end - - def ship - authorize! :admin, order - - if order.ship - render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok - else - render json: { error: I18n.t('api.orders.failed_to_update') }, status: :unprocessable_entity - end - end - - def capture - authorize! :admin, order - - pending_payment = order.pending_payments.first - - return payment_capture_failed unless order.payment_required? && pending_payment - - if pending_payment.capture! - render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok - else - payment_capture_failed - end - rescue Spree::Core::GatewayError => e - error_during_processing(e) - end - - private - - def payment_capture_failed - render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity - end - - def serialized_orders(orders) - ActiveModel::ArraySerializer.new( - orders, - each_serializer: Api::Admin::OrderSerializer - ) - end - - def order - @order ||= Spree::Order. - where(number: params[:id]). - includes(line_items: { variant: [:product, :stock_items, :default_price] }). - first! - end - end -end diff --git a/app/controllers/api/product_images_controller.rb b/app/controllers/api/product_images_controller.rb deleted file mode 100644 index e688a03e6e..0000000000 --- a/app/controllers/api/product_images_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Api - class ProductImagesController < Api::BaseController - respond_to :json - - def update_product_image - @product = Spree::Product.find(params[:product_id]) - authorize! :update, @product - - if @product.images.first.nil? - @image = Spree::Image.create(attachment: params[:file], viewable_id: @product.master.id, viewable_type: 'Spree::Variant') - render json: @image, serializer: ImageSerializer, status: :created - else - @image = @product.images.first - @image.update(attachment: params[:file]) - render json: @image, serializer: ImageSerializer, status: :ok - end - end - end -end diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb deleted file mode 100644 index d8fab1067a..0000000000 --- a/app/controllers/api/products_controller.rb +++ /dev/null @@ -1,159 +0,0 @@ -require 'open_food_network/permissions' -require 'spree/core/product_duplicator' - -module Api - class ProductsController < Api::BaseController - include PaginationData - respond_to :json - DEFAULT_PER_PAGE = 15 - - before_action :set_default_available_on, only: :create - - skip_authorization_check only: [:show, :bulk_products, :overridable] - - def show - @product = find_product(params[:id]) - render json: @product, serializer: Api::Admin::ProductSerializer - end - - def create - authorize! :create, Spree::Product - @product = Spree::Product.new(product_params) - - begin - if @product.save - render json: @product, serializer: Api::Admin::ProductSerializer, status: :created - else - invalid_resource!(@product) - end - rescue ActiveRecord::RecordNotUnique - @product.permalink = nil - retry - end - end - - def update - authorize! :update, Spree::Product - @product = find_product(params[:id]) - if @product.update(product_params) - render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok - else - invalid_resource!(@product) - end - end - - def destroy - authorize! :delete, Spree::Product - @product = find_product(params[:id]) - authorize! :delete, @product - @product.destroy - render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content - end - - def bulk_products - product_query = OpenFoodNetwork::Permissions. - new(current_api_user). - editable_products. - merge(product_scope) - - if params[:import_date].present? - product_query = product_query. - imported_on(params[:import_date]). - group_by_products_id - end - - @products = product_query. - ransack(query_params_with_defaults). - result. - page(params[:page] || 1). - per(params[:per_page] || DEFAULT_PER_PAGE) - - render_paged_products @products - end - - def overridable - producer_ids = OpenFoodNetwork::Permissions.new(current_api_user). - variant_override_producers.by_name.select('enterprises.id') - - @products = paged_products_for_producers producer_ids - - render_paged_products @products, ::Api::Admin::ProductSimpleSerializer - end - - # POST /api/products/:product_id/clone - # - def clone - authorize! :create, Spree::Product - original_product = find_product(params[:product_id]) - authorize! :update, original_product - - @product = original_product.duplicate - - render json: @product, serializer: Api::Admin::ProductSerializer, status: :created - end - - private - - def find_product(id) - product_scope.find_by!(permalink: id.to_s) - rescue ActiveRecord::RecordNotFound - product_scope.find(id) - end - - def product_scope - if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present? - scope = Spree::Product - if params[:show_deleted] - scope = scope.with_deleted - end - else - scope = Spree::Product.active - end - - scope.includes(product_query_includes) - end - - def product_query_includes - [ - master: [:images], - variants: [:default_price, :stock_locations, :stock_items, :variant_overrides, - { option_values: :option_type }] - ] - end - - def paged_products_for_producers(producer_ids) - Spree::Product.where(nil). - merge(product_scope). - includes(variants: [:product, :default_price, :stock_items]). - where(supplier_id: producer_ids). - by_producer.by_name. - ransack(params[:q]).result. - page(params[:page]).per(params[:per_page]) - end - - def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer) - serialized_products = ActiveModel::ArraySerializer.new( - products, - each_serializer: product_serializer - ) - - render json: { - products: serialized_products, - pagination: pagination_data(products) - } - end - - def query_params_with_defaults - (params[:q] || {}).reverse_merge(s: 'created_at desc') - end - - def product_params - @product_params ||= - params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h - end - - def set_default_available_on - product_params[:available_on] ||= Time.zone.now - end - end -end diff --git a/app/controllers/api/promo_images_controller.rb b/app/controllers/api/promo_images_controller.rb deleted file mode 100644 index 9cdb799931..0000000000 --- a/app/controllers/api/promo_images_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Api - class PromoImagesController < Api::EnterpriseAttachmentController - private - - def attachment_name - :promo_image - end - - def enterprise_authorize_action - case action_name.to_sym - when :destroy - :remove_promo_image - end - end - end -end diff --git a/app/controllers/api/shipments_controller.rb b/app/controllers/api/shipments_controller.rb deleted file mode 100644 index b9a5f4340b..0000000000 --- a/app/controllers/api/shipments_controller.rb +++ /dev/null @@ -1,112 +0,0 @@ -require 'open_food_network/scope_variant_to_hub' - -module Api - class ShipmentsController < Api::BaseController - respond_to :json - - before_action :find_order - before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove] - - def create - variant = scoped_variant(params[:variant_id]) - quantity = params[:quantity].to_i - @shipment = get_or_create_shipment(params[:stock_location_id]) - - @order.contents.add(variant, quantity, nil, @shipment) - - @shipment.refresh_rates - @shipment.save! - - render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok - end - - def update - authorize! :read, Spree::Shipment - @shipment = @order.shipments.find_by!(number: params[:id]) - params[:shipment] ||= [] - unlock = params[:shipment].delete(:unlock) - - if unlock == 'yes' - @shipment.fee_adjustment.open - end - - @shipment.update(shipment_params[:shipment]) - - if unlock == 'yes' - @shipment.fee_adjustment.close - end - - render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok - end - - def ready - authorize! :read, Spree::Shipment - unless @shipment.ready? - if @shipment.can_ready? - @shipment.ready! - else - render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") }, - status: :unprocessable_entity) && return - end - end - render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok - end - - def ship - authorize! :read, Spree::Shipment - unless @shipment.shipped? - @shipment.ship! - end - render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok - end - - def add - variant = scoped_variant(params[:variant_id]) - quantity = params[:quantity].to_i - - @order.contents.add(variant, quantity, nil, @shipment) - - render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok - end - - def remove - variant = scoped_variant(params[:variant_id]) - quantity = params[:quantity].to_i - - @order.contents.remove(variant, quantity, @shipment) - @shipment.reload if @shipment.persisted? - - render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok - end - - private - - def find_order - @order = Spree::Order.find_by!(number: params[:order_id]) - authorize! :read, @order - end - - def find_and_update_shipment - @shipment = @order.shipments.find_by!(number: params[:id]) - @shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present? - @shipment.reload - end - - def scoped_variant(variant_id) - variant = Spree::Variant.find(variant_id) - OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant) - variant - end - - def get_or_create_shipment(stock_location_id) - @order.shipment || @order.shipments.create(stock_location_id: stock_location_id) - end - - def shipment_params - params.permit( - [:id, :order_id, :variant_id, :quantity, - { shipment: [:tracking, :selected_shipping_rate_id] }] - ) - end - end -end diff --git a/app/controllers/api/shops_controller.rb b/app/controllers/api/shops_controller.rb deleted file mode 100644 index 377e849378..0000000000 --- a/app/controllers/api/shops_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Api - class ShopsController < BaseController - respond_to :json - skip_authorization_check only: [:show, :closed_shops] - - def show - enterprise = Enterprise.find_by(id: params[:id]) - - render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok - end - - def closed_shops - @active_distributor_ids = [] - @earliest_closing_times = [] - - serialized_closed_shops = ActiveModel::ArraySerializer.new( - ShopsListService.new.closed_shops, - each_serializer: Api::EnterpriseSerializer, - data: OpenFoodNetwork::EnterpriseInjectionData.new - ) - - render json: serialized_closed_shops - end - end -end diff --git a/app/controllers/api/states_controller.rb b/app/controllers/api/states_controller.rb deleted file mode 100644 index 0ad0b991d4..0000000000 --- a/app/controllers/api/states_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module Api - class StatesController < Api::BaseController - respond_to :json - - skip_authorization_check - - def index - render json: states, each_serializer: Api::StateSerializer, status: :ok - end - - def show - @state = scope.find(params[:id]) - render json: @state, serializer: Api::StateSerializer, status: :ok - end - - private - - def scope - if params[:country_id] - @country = Spree::Country.find(params[:country_id]) - @country.states - else - Spree::State.all - end - end - - def states - states = scope.ransack(params[:q]).result. - includes(:country).order('name ASC') - - if pagination? - states = states.page(params[:page]).per(params[:per_page]) - end - - states - end - - def pagination? - params[:page] || params[:per_page] - end - end -end diff --git a/app/controllers/api/statuses_controller.rb b/app/controllers/api/statuses_controller.rb deleted file mode 100644 index 24714b6a0d..0000000000 --- a/app/controllers/api/statuses_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Api - class StatusesController < ::BaseController - respond_to :json - - def job_queue - render json: { alive: job_queue_alive? } - end - - private - - def job_queue_alive? - Spree::Config.last_job_queue_heartbeat_at.present? && - Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago - end - end -end diff --git a/app/controllers/api/taxonomies_controller.rb b/app/controllers/api/taxonomies_controller.rb deleted file mode 100644 index 356d84d676..0000000000 --- a/app/controllers/api/taxonomies_controller.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Api - class TaxonomiesController < Api::BaseController - respond_to :json - - skip_authorization_check only: :jstree - - def jstree - @taxonomy = Spree::Taxonomy.find(params[:id]) - render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer - end - end -end diff --git a/app/controllers/api/taxons_controller.rb b/app/controllers/api/taxons_controller.rb deleted file mode 100644 index 491cf75954..0000000000 --- a/app/controllers/api/taxons_controller.rb +++ /dev/null @@ -1,76 +0,0 @@ -module Api - class TaxonsController < Api::BaseController - respond_to :json - - skip_authorization_check only: [:index, :show, :jstree] - - def index - @taxons = if taxonomy - taxonomy.root.children - elsif params[:ids] - Spree::Taxon.where(id: raw_params[:ids].split(",")) - else - Spree::Taxon.ransack(raw_params[:q]).result - end - render json: @taxons, each_serializer: Api::TaxonSerializer - end - - def jstree - @taxon = taxon - render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer - end - - def create - authorize! :create, Spree::Taxon - @taxon = Spree::Taxon.new(taxon_params) - @taxon.taxonomy_id = params[:taxonomy_id] - taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id]) - - if taxonomy.nil? - @taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api') - invalid_resource!(@taxon) && return - end - - @taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id) - - if @taxon.save - render json: @taxon, serializer: Api::TaxonSerializer, status: :created - else - invalid_resource!(@taxon) - end - end - - def update - authorize! :update, Spree::Taxon - if taxon.update(taxon_params) - render json: taxon, serializer: Api::TaxonSerializer, status: :ok - else - invalid_resource!(taxon) - end - end - - def destroy - authorize! :delete, Spree::Taxon - taxon.destroy - render json: taxon, serializer: Api::TaxonSerializer, status: :no_content - end - - private - - def taxonomy - return if params[:taxonomy_id].blank? - - @taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id]) - end - - def taxon - @taxon ||= taxonomy.taxons.find(params[:id]) - end - - def taxon_params - return if params[:taxon].blank? - - params.require(:taxon).permit([:name, :parent_id]) - end - end -end diff --git a/app/controllers/api/terms_and_conditions_controller.rb b/app/controllers/api/terms_and_conditions_controller.rb deleted file mode 100644 index d49721c04a..0000000000 --- a/app/controllers/api/terms_and_conditions_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Api - class TermsAndConditionsController < Api::EnterpriseAttachmentController - private - - def attachment_name - :terms_and_conditions - end - - def enterprise_authorize_action - case action_name.to_sym - when :destroy - :remove_terms_and_conditions - end - end - end -end diff --git a/app/controllers/api/v0/base_controller.rb b/app/controllers/api/v0/base_controller.rb new file mode 100644 index 0000000000..676d32e183 --- /dev/null +++ b/app/controllers/api/v0/base_controller.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +# Base controller for OFN's API +require_dependency 'spree/api/controller_setup' +require "spree/core/controller_helpers/ssl" + +module Api + module V0 + class BaseController < ActionController::Metal + include RawParams + include ActionController::StrongParameters + include ActionController::RespondWith + include Spree::Api::ControllerSetup + include Spree::Core::ControllerHelpers::SSL + include ::ActionController::Head + include ::ActionController::ConditionalGet + include ActionView::Layouts + + layout false + + attr_accessor :current_api_user + + before_action :set_content_type + before_action :authenticate_user + + rescue_from Exception, with: :error_during_processing + rescue_from CanCan::AccessDenied, with: :unauthorized + rescue_from ActiveRecord::RecordNotFound, with: :not_found + + ssl_allowed + + # Include these because we inherit from ActionController::Metal + # rather than ActionController::Base and these are required for AMS + include ActionController::Serialization + include ActionController::UrlFor + include Rails.application.routes.url_helpers + + use_renderers :json + check_authorization + + def respond_with_conflict(json_hash) + render json: json_hash, status: :conflict + end + + private + + # Use logged in user (spree_current_user) for API authentication (current_api_user) + def authenticate_user + return if @current_api_user = spree_current_user + + if api_key.blank? + # An anonymous user + @current_api_user = Spree.user_class.new + return + end + + return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s) + + invalid_api_key + end + + def set_content_type + headers["Content-Type"] = "application/json" + end + + def error_during_processing(exception) + Bugsnag.notify(exception) + + render(json: { exception: exception.message }, + status: :unprocessable_entity) && return + end + + def current_ability + Spree::Ability.new(current_api_user) + end + + def api_key + request.headers["X-Spree-Token"] || params[:token] + end + helper_method :api_key + + def invalid_resource!(resource) + @resource = resource + render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"), + errors: @resource.errors }, + status: :unprocessable_entity) + end + + def invalid_api_key + render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") }, + status: :unauthorized) && return + end + + def unauthorized + render(json: { error: I18n.t(:unauthorized, scope: "spree.api") }, + status: :unauthorized) && return + end + + def not_found + render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") }, + status: :not_found) && return + end + end + end +end diff --git a/app/controllers/api/v0/customers_controller.rb b/app/controllers/api/v0/customers_controller.rb new file mode 100644 index 0000000000..a10b65bed7 --- /dev/null +++ b/app/controllers/api/v0/customers_controller.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Api + module V0 + class CustomersController < Api::V0::BaseController + skip_authorization_check only: :index + + def index + @customers = current_api_user.customers + render json: @customers, each_serializer: CustomerSerializer + end + + def update + @customer = Customer.find(params[:id]) + authorize! :update, @customer + + client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges] + + if @customer.update(customer_params) + add_recurring_payment_info(client_secret) + render json: @customer, serializer: CustomerSerializer, status: :ok + else + invalid_resource!(@customer) + end + end + + private + + def add_recurring_payment_info(client_secret) + return unless client_secret + + @customer.gateway_recurring_payment_client_secret = client_secret + @customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id + end + + def customer_params + params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges) + end + end + end +end diff --git a/app/controllers/api/v0/enterprise_attachment_controller.rb b/app/controllers/api/v0/enterprise_attachment_controller.rb new file mode 100644 index 0000000000..6e183371a1 --- /dev/null +++ b/app/controllers/api/v0/enterprise_attachment_controller.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'api/admin/enterprise_serializer' + +module Api + module V0 + class EnterpriseAttachmentController < Api::V0::BaseController + class MissingImplementationError < StandardError; end + + class UnknownEnterpriseAuthorizationActionError < StandardError; end + + before_action :load_enterprise + + respond_to :json + + def destroy + unless @enterprise.public_send("#{attachment_name}?") + return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message) + end + + @enterprise.update!(attachment_name => nil) + render json: @enterprise, + serializer: Admin::EnterpriseSerializer, + spree_current_user: spree_current_user + end + + protected + + def attachment_name + raise MissingImplementationError, "Method attachment_name should be defined" + end + + def enterprise_authorize_action + raise MissingImplementationError, "Method enterprise_authorize_action should be defined" + end + + def load_enterprise + @enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s) + raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank? + + authorize!(enterprise_authorize_action, @enterprise) + end + + def destroy_attachment_does_not_exist_error_message + I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist") + end + end + end +end diff --git a/app/controllers/api/v0/enterprise_fees_controller.rb b/app/controllers/api/v0/enterprise_fees_controller.rb new file mode 100644 index 0000000000..45957672a7 --- /dev/null +++ b/app/controllers/api/v0/enterprise_fees_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Api + module V0 + class EnterpriseFeesController < Api::V0::BaseController + respond_to :json + + def destroy + authorize! :destroy, enterprise_fee + + if enterprise_fee.destroy + render plain: I18n.t(:successfully_removed), status: :no_content + else + render plain: enterprise_fee.errors.full_messages.first, status: :forbidden + end + end + + private + + def enterprise_fee + @enterprise_fee ||= EnterpriseFee.find_by id: params[:id] + end + end + end +end diff --git a/app/controllers/api/v0/enterprises_controller.rb b/app/controllers/api/v0/enterprises_controller.rb new file mode 100644 index 0000000000..804808f53b --- /dev/null +++ b/app/controllers/api/v0/enterprises_controller.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Api + module V0 + class EnterprisesController < Api::V0::BaseController + include GeocodeEnterpriseAddress + + before_action :override_owner, only: [:create, :update] + before_action :check_type, only: :update + before_action :override_sells, only: [:create, :update] + before_action :override_visible, only: [:create, :update] + respond_to :json + + def create + authorize! :create, Enterprise + + # params[:user_ids] breaks the enterprise creation + # We remove them from params and save them after creating the enterprise + user_ids = enterprise_params.delete(:user_ids) + @enterprise = Enterprise.new(enterprise_params) + if @enterprise.save + geocode_address_if_use_geocoder + @enterprise.user_ids = user_ids + render json: @enterprise.id, status: :created + else + invalid_resource!(@enterprise) + end + end + + def update + @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) + authorize! :update, @enterprise + + if @enterprise.update(enterprise_params) + geocode_address_if_use_geocoder + render json: @enterprise.id, status: :ok + else + invalid_resource!(@enterprise) + end + end + + def update_image + @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) + authorize! :update, @enterprise + + if params[:logo] && @enterprise.update( logo: params[:logo] ) + render plain: @enterprise.logo.url(:medium), status: :ok + elsif params[:promo] && @enterprise.update( promo_image: params[:promo] ) + render plain: @enterprise.promo_image.url(:medium), status: :ok + else + invalid_resource!(@enterprise) + end + end + + private + + def override_owner + enterprise_params[:owner_id] = current_api_user.id + end + + def check_type + enterprise_params.delete :type unless current_api_user.admin? + end + + def override_sells + has_hub = current_api_user.owned_enterprises.is_hub.any? + new_enterprise_is_producer = !!enterprise_params[:is_primary_producer] + + enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer + 'any' + else + 'unspecified' + end + end + + def override_visible + enterprise_params[:visible] = false + end + + def enterprise_params + @enterprise_params ||= PermittedAttributes::Enterprise.new(params).call. + to_h.with_indifferent_access + end + end + end +end diff --git a/app/controllers/api/v0/exchange_products_controller.rb b/app/controllers/api/v0/exchange_products_controller.rb new file mode 100644 index 0000000000..fde6abf174 --- /dev/null +++ b/app/controllers/api/v0/exchange_products_controller.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +# This controller lists products that can be added to an exchange +# +# Pagination is optional and can be required by using param[:page] +module Api + module V0 + class ExchangeProductsController < Api::V0::BaseController + include PaginationData + DEFAULT_PER_PAGE = 100 + + skip_authorization_check only: [:index] + + # If exchange_id is present in the URL: + # Lists Products that can be added to that Exchange + # + # If exchange_id is not present in the URL: + # Lists Products of the Enterprise given that can be added to the given Order Cycle + # In this case parameters are: enterprise_id, order_cycle_id and incoming + # (order_cycle_id is not necessary for incoming exchanges) + def index + if exchange_params[:exchange_id].present? + load_data_from_exchange + else + load_data_from_other_params + end + + render_variant_count && return if params[:action_name] == "variant_count" + + render_paginated_products paginated_products + end + + private + + def render_variant_count + render plain: { + count: variants.count + }.to_json + end + + def variants + renderer.exchange_variants(@incoming, @enterprise) + end + + def products + renderer.exchange_products(@incoming, @enterprise) + end + + def renderer + @renderer ||= ExchangeProductsRenderer. + new(@order_cycle, spree_current_user) + end + + def paginated_products + return products unless pagination_required? + + products. + page(params[:page]). + per(params[:per_page] || DEFAULT_PER_PAGE) + end + + def load_data_from_exchange + exchange = Exchange.find_by(id: exchange_params[:exchange_id]) + + @order_cycle = exchange.order_cycle + @incoming = exchange.incoming + @enterprise = exchange.sender + end + + def load_data_from_other_params + @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id]) + + # This will be a string (eg "true") when it arrives via params, but we want a boolean + @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming] + + if exchange_params[:order_cycle_id] + @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id]) + elsif !@incoming + raise "order_cycle_id is required to list products for new outgoing exchange" + end + end + + def render_paginated_products(paginated_products) + serialized_products = ActiveModel::ArraySerializer.new( + paginated_products, + each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer, + order_cycle: @order_cycle + ) + + render json: { + products: serialized_products, + pagination: pagination_data(paginated_products) + } + end + + def exchange_params + params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming). + to_h.with_indifferent_access + end + end + end +end diff --git a/app/controllers/api/v0/logos_controller.rb b/app/controllers/api/v0/logos_controller.rb new file mode 100644 index 0000000000..0e710d8bf2 --- /dev/null +++ b/app/controllers/api/v0/logos_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V0 + class LogosController < Api::V0::EnterpriseAttachmentController + private + + def attachment_name + :logo + end + + def enterprise_authorize_action + case action_name.to_sym + when :destroy + :remove_logo + end + end + end + end +end diff --git a/app/controllers/api/v0/order_cycles_controller.rb b/app/controllers/api/v0/order_cycles_controller.rb new file mode 100644 index 0000000000..88241b23a4 --- /dev/null +++ b/app/controllers/api/v0/order_cycles_controller.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module Api + module V0 + class OrderCyclesController < Api::V0::BaseController + include EnterprisesHelper + include ApiActionCaching + + skip_authorization_check + skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties] + + caches_action :taxons, :properties, + expires_in: CacheService::FILTERS_EXPIRY, + cache_path: proc { |controller| controller.request.url } + + def products + return render_no_products unless order_cycle.open? + + products = ProductsRenderer.new( + distributor, + order_cycle, + customer, + search_params + ).products_json + + render plain: products + rescue ProductsRenderer::NoProducts + render_no_products + end + + def taxons + taxons = Spree::Taxon. + joins(:products). + where(spree_products: { id: distributed_products }). + select('DISTINCT spree_taxons.*') + + render plain: ActiveModel::ArraySerializer.new( + taxons, each_serializer: Api::TaxonSerializer + ).to_json + end + + def properties + render plain: ActiveModel::ArraySerializer.new( + product_properties | producer_properties, each_serializer: Api::PropertySerializer + ).to_json + end + + private + + def render_no_products + render status: :not_found, json: {} + end + + def product_properties + Spree::Property. + joins(:products). + where(spree_products: { id: distributed_products }). + select('DISTINCT spree_properties.*') + end + + def producer_properties + producers = Enterprise. + joins(:supplied_products). + where(spree_products: { id: distributed_products }) + + Spree::Property. + joins(:producer_properties). + where(producer_properties: { producer_id: producers }). + select('DISTINCT spree_properties.*') + end + + def search_params + permitted_search_params = params.slice :q, :page, :per_page + + if permitted_search_params.key? :q + permitted_search_params[:q].slice!(*permitted_ransack_params) + end + + permitted_search_params + end + + def permitted_ransack_params + [:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont, + :properties_id_or_supplier_properties_id_in_any, + :primary_taxon_id_in_any] + end + + def distributor + @distributor ||= Enterprise.find_by(id: params[:distributor]) + end + + def order_cycle + @order_cycle ||= OrderCycle.find_by(id: params[:id]) + end + + def customer + @current_api_user.andand.customer_of(distributor) || nil + end + + def distributed_products + OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation + end + end + end +end diff --git a/app/controllers/api/v0/orders_controller.rb b/app/controllers/api/v0/orders_controller.rb new file mode 100644 index 0000000000..48a40e13cc --- /dev/null +++ b/app/controllers/api/v0/orders_controller.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Api + module V0 + class OrdersController < Api::V0::BaseController + include PaginationData + + def show + authorize! :read, order + render json: order, serializer: Api::OrderDetailedSerializer, current_order: order + end + + def index + authorize! :admin, Spree::Order + + orders = SearchOrders.new(params, current_api_user).orders + + render json: { + orders: serialized_orders(orders), + pagination: pagination_data(orders) + } + end + + def ship + authorize! :admin, order + + if order.ship + render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok + else + render json: { error: I18n.t('api.orders.failed_to_update') }, + status: :unprocessable_entity + end + end + + def capture + authorize! :admin, order + + pending_payment = order.pending_payments.first + + return payment_capture_failed unless order.payment_required? && pending_payment + + if pending_payment.capture! + render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok + else + payment_capture_failed + end + rescue Spree::Core::GatewayError => e + error_during_processing(e) + end + + private + + def payment_capture_failed + render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity + end + + def serialized_orders(orders) + ActiveModel::ArraySerializer.new( + orders, + each_serializer: Api::Admin::OrderSerializer + ) + end + + def order + @order ||= Spree::Order. + where(number: params[:id]). + includes(line_items: { variant: [:product, :stock_items, :default_price] }). + first! + end + end + end +end diff --git a/app/controllers/api/v0/product_images_controller.rb b/app/controllers/api/v0/product_images_controller.rb new file mode 100644 index 0000000000..fbceddb4fe --- /dev/null +++ b/app/controllers/api/v0/product_images_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Api + module V0 + class ProductImagesController < Api::V0::BaseController + respond_to :json + + def update_product_image + @product = Spree::Product.find(params[:product_id]) + authorize! :update, @product + + if @product.images.first.nil? + @image = Spree::Image.create( + attachment: params[:file], + viewable_id: @product.master.id, + viewable_type: 'Spree::Variant' + ) + render json: @image, serializer: ImageSerializer, status: :created + else + @image = @product.images.first + @image.update(attachment: params[:file]) + render json: @image, serializer: ImageSerializer, status: :ok + end + end + end + end +end diff --git a/app/controllers/api/v0/products_controller.rb b/app/controllers/api/v0/products_controller.rb new file mode 100644 index 0000000000..571b16b3e0 --- /dev/null +++ b/app/controllers/api/v0/products_controller.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +require 'open_food_network/permissions' +require 'spree/core/product_duplicator' + +module Api + module V0 + class ProductsController < Api::V0::BaseController + include PaginationData + respond_to :json + DEFAULT_PER_PAGE = 15 + + before_action :set_default_available_on, only: :create + + skip_authorization_check only: [:show, :bulk_products, :overridable] + + def show + @product = find_product(params[:id]) + render json: @product, serializer: Api::Admin::ProductSerializer + end + + def create + authorize! :create, Spree::Product + @product = Spree::Product.new(product_params) + + begin + if @product.save + render json: @product, serializer: Api::Admin::ProductSerializer, status: :created + else + invalid_resource!(@product) + end + rescue ActiveRecord::RecordNotUnique + @product.permalink = nil + retry + end + end + + def update + authorize! :update, Spree::Product + @product = find_product(params[:id]) + if @product.update(product_params) + render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok + else + invalid_resource!(@product) + end + end + + def destroy + authorize! :delete, Spree::Product + @product = find_product(params[:id]) + authorize! :delete, @product + @product.destroy + render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content + end + + def bulk_products + product_query = OpenFoodNetwork::Permissions. + new(current_api_user). + editable_products. + merge(product_scope) + + if params[:import_date].present? + product_query = product_query. + imported_on(params[:import_date]). + group_by_products_id + end + + @products = product_query. + ransack(query_params_with_defaults). + result. + page(params[:page] || 1). + per(params[:per_page] || DEFAULT_PER_PAGE) + + render_paged_products @products + end + + def overridable + producer_ids = OpenFoodNetwork::Permissions.new(current_api_user). + variant_override_producers.by_name.select('enterprises.id') + + @products = paged_products_for_producers producer_ids + + render_paged_products @products, ::Api::Admin::ProductSimpleSerializer + end + + # POST /api/products/:product_id/clone + # + def clone + authorize! :create, Spree::Product + original_product = find_product(params[:product_id]) + authorize! :update, original_product + + @product = original_product.duplicate + + render json: @product, serializer: Api::Admin::ProductSerializer, status: :created + end + + private + + def find_product(id) + product_scope.find_by!(permalink: id.to_s) + rescue ActiveRecord::RecordNotFound + product_scope.find(id) + end + + def product_scope + if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present? + scope = Spree::Product + if params[:show_deleted] + scope = scope.with_deleted + end + else + scope = Spree::Product.active + end + + scope.includes(product_query_includes) + end + + def product_query_includes + [ + master: [:images], + variants: [:default_price, :stock_locations, :stock_items, :variant_overrides, + { option_values: :option_type }] + ] + end + + def paged_products_for_producers(producer_ids) + Spree::Product.where(nil). + merge(product_scope). + includes(variants: [:product, :default_price, :stock_items]). + where(supplier_id: producer_ids). + by_producer.by_name. + ransack(params[:q]).result. + page(params[:page]).per(params[:per_page]) + end + + def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer) + serialized_products = ActiveModel::ArraySerializer.new( + products, + each_serializer: product_serializer + ) + + render json: { + products: serialized_products, + pagination: pagination_data(products) + } + end + + def query_params_with_defaults + (params[:q] || {}).reverse_merge(s: 'created_at desc') + end + + def product_params + @product_params ||= + params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h + end + + def set_default_available_on + product_params[:available_on] ||= Time.zone.now + end + end + end +end diff --git a/app/controllers/api/v0/promo_images_controller.rb b/app/controllers/api/v0/promo_images_controller.rb new file mode 100644 index 0000000000..13822324ff --- /dev/null +++ b/app/controllers/api/v0/promo_images_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V0 + class PromoImagesController < Api::V0::EnterpriseAttachmentController + private + + def attachment_name + :promo_image + end + + def enterprise_authorize_action + case action_name.to_sym + when :destroy + :remove_promo_image + end + end + end + end +end diff --git a/app/controllers/api/v0/shipments_controller.rb b/app/controllers/api/v0/shipments_controller.rb new file mode 100644 index 0000000000..c885d1c221 --- /dev/null +++ b/app/controllers/api/v0/shipments_controller.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require 'open_food_network/scope_variant_to_hub' + +module Api + module V0 + class ShipmentsController < Api::V0::BaseController + respond_to :json + + before_action :find_order + before_action :refuse_changing_cancelled_orders, only: [:add, :remove] + before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove] + + def create + variant = scoped_variant(params[:variant_id]) + quantity = params[:quantity].to_i + @shipment = get_or_create_shipment(params[:stock_location_id]) + + @order.contents.add(variant, quantity, nil, @shipment) + + @shipment.refresh_rates + @shipment.save! + + render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok + end + + def update + authorize! :read, Spree::Shipment + @shipment = @order.shipments.find_by!(number: params[:id]) + params[:shipment] ||= [] + unlock = params[:shipment].delete(:unlock) + + if unlock == 'yes' + @shipment.fee_adjustment.open + end + + @shipment.update(shipment_params[:shipment]) + + if unlock == 'yes' + @shipment.fee_adjustment.close + end + + render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok + end + + def ready + authorize! :read, Spree::Shipment + unless @shipment.ready? + if @shipment.can_ready? + @shipment.ready! + else + render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") }, + status: :unprocessable_entity) && return + end + end + render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok + end + + def ship + authorize! :read, Spree::Shipment + unless @shipment.shipped? + @shipment.ship! + end + render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok + end + + def add + variant = scoped_variant(params[:variant_id]) + quantity = params[:quantity].to_i + + @order.contents.add(variant, quantity, nil, @shipment) + @order.recreate_all_fees! + + render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok + end + + def remove + variant = scoped_variant(params[:variant_id]) + quantity = params[:quantity].to_i + + @order.contents.remove(variant, quantity, @shipment) + @order.recreate_all_fees! + @shipment.reload if @shipment.persisted? + + render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok + end + + private + + def find_order + @order = Spree::Order.find_by!(number: params[:order_id]) + authorize! :read, @order + end + + def find_and_update_shipment + @shipment = @order.shipments.find_by!(number: params[:id]) + @shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present? + @shipment.reload + end + + def refuse_changing_cancelled_orders + render status: :unprocessable_entity if @order.canceled? + end + + def scoped_variant(variant_id) + variant = Spree::Variant.find(variant_id) + OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant) + variant + end + + def get_or_create_shipment(stock_location_id) + @order.shipment || @order.shipments.create(stock_location_id: stock_location_id) + end + + def shipment_params + params.permit( + [:id, :order_id, :variant_id, :quantity, + { shipment: [:tracking, :selected_shipping_rate_id] }] + ) + end + end + end +end diff --git a/app/controllers/api/v0/shops_controller.rb b/app/controllers/api/v0/shops_controller.rb new file mode 100644 index 0000000000..a76a506a85 --- /dev/null +++ b/app/controllers/api/v0/shops_controller.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Api + module V0 + class ShopsController < BaseController + respond_to :json + skip_authorization_check only: [:show, :closed_shops] + + def show + enterprise = Enterprise.find_by(id: params[:id]) + + render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok + end + + def closed_shops + @active_distributor_ids = [] + @earliest_closing_times = [] + + serialized_closed_shops = ActiveModel::ArraySerializer.new( + ShopsListService.new.closed_shops, + each_serializer: Api::EnterpriseSerializer, + data: OpenFoodNetwork::EnterpriseInjectionData.new + ) + + render json: serialized_closed_shops + end + end + end +end diff --git a/app/controllers/api/v0/states_controller.rb b/app/controllers/api/v0/states_controller.rb new file mode 100644 index 0000000000..c64a077f76 --- /dev/null +++ b/app/controllers/api/v0/states_controller.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Api + module V0 + class StatesController < Api::V0::BaseController + respond_to :json + + skip_authorization_check + + def index + render json: states, each_serializer: Api::StateSerializer, status: :ok + end + + def show + @state = scope.find(params[:id]) + render json: @state, serializer: Api::StateSerializer, status: :ok + end + + private + + def scope + if params[:country_id] + @country = Spree::Country.find(params[:country_id]) + @country.states + else + Spree::State.all + end + end + + def states + states = scope.ransack(params[:q]).result. + includes(:country).order('name ASC') + + if pagination? + states = states.page(params[:page]).per(params[:per_page]) + end + + states + end + + def pagination? + params[:page] || params[:per_page] + end + end + end +end diff --git a/app/controllers/api/v0/statuses_controller.rb b/app/controllers/api/v0/statuses_controller.rb new file mode 100644 index 0000000000..17a0eaa3cf --- /dev/null +++ b/app/controllers/api/v0/statuses_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V0 + class StatusesController < ::BaseController + respond_to :json + + def job_queue + render json: { alive: job_queue_alive? } + end + + private + + def job_queue_alive? + Spree::Config.last_job_queue_heartbeat_at.present? && + Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago + end + end + end +end diff --git a/app/controllers/api/v0/taxonomies_controller.rb b/app/controllers/api/v0/taxonomies_controller.rb new file mode 100644 index 0000000000..bf6077a9e1 --- /dev/null +++ b/app/controllers/api/v0/taxonomies_controller.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Api + module V0 + class TaxonomiesController < Api::V0::BaseController + respond_to :json + + skip_authorization_check only: :jstree + + def jstree + @taxonomy = Spree::Taxonomy.find(params[:id]) + render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer + end + end + end +end diff --git a/app/controllers/api/v0/taxons_controller.rb b/app/controllers/api/v0/taxons_controller.rb new file mode 100644 index 0000000000..b3e74d0dac --- /dev/null +++ b/app/controllers/api/v0/taxons_controller.rb @@ -0,0 +1,78 @@ +module Api + module V0 + class TaxonsController < Api::V0::BaseController + respond_to :json + + skip_authorization_check only: [:index, :show, :jstree] + + def index + @taxons = if taxonomy + taxonomy.root.children + elsif params[:ids] + Spree::Taxon.where(id: raw_params[:ids].split(",")) + else + Spree::Taxon.ransack(raw_params[:q]).result + end + render json: @taxons, each_serializer: Api::TaxonSerializer + end + + def jstree + @taxon = taxon + render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer + end + + def create + authorize! :create, Spree::Taxon + @taxon = Spree::Taxon.new(taxon_params) + @taxon.taxonomy_id = params[:taxonomy_id] + taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id]) + + if taxonomy.nil? + @taxon.errors.add(:taxonomy_id, I18n.t(:invalid_taxonomy_id, scope: 'spree.api')) + invalid_resource!(@taxon) && return + end + + @taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id) + + if @taxon.save + render json: @taxon, serializer: Api::TaxonSerializer, status: :created + else + invalid_resource!(@taxon) + end + end + + def update + authorize! :update, Spree::Taxon + if taxon.update(taxon_params) + render json: taxon, serializer: Api::TaxonSerializer, status: :ok + else + invalid_resource!(taxon) + end + end + + def destroy + authorize! :delete, Spree::Taxon + taxon.destroy + render json: taxon, serializer: Api::TaxonSerializer, status: :no_content + end + + private + + def taxonomy + return if params[:taxonomy_id].blank? + + @taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id]) + end + + def taxon + @taxon ||= taxonomy.taxons.find(params[:id]) + end + + def taxon_params + return if params[:taxon].blank? + + params.require(:taxon).permit([:name, :parent_id]) + end + end + end +end diff --git a/app/controllers/api/v0/terms_and_conditions_controller.rb b/app/controllers/api/v0/terms_and_conditions_controller.rb new file mode 100644 index 0000000000..e5089c5c2e --- /dev/null +++ b/app/controllers/api/v0/terms_and_conditions_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V0 + class TermsAndConditionsController < Api::V0::EnterpriseAttachmentController + private + + def attachment_name + :terms_and_conditions + end + + def enterprise_authorize_action + case action_name.to_sym + when :destroy + :remove_terms_and_conditions + end + end + end + end +end diff --git a/app/controllers/api/v0/variants_controller.rb b/app/controllers/api/v0/variants_controller.rb new file mode 100644 index 0000000000..e1846ebe32 --- /dev/null +++ b/app/controllers/api/v0/variants_controller.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Api + module V0 + class VariantsController < Api::V0::BaseController + respond_to :json + + skip_authorization_check only: [:index, :show] + before_action :product + + def index + @variants = scope.includes(option_values: :option_type).ransack(params[:q]).result + render json: @variants, each_serializer: Api::VariantSerializer + end + + def show + @variant = scope.includes(option_values: :option_type).find(params[:id]) + render json: @variant, serializer: Api::VariantSerializer + end + + def create + authorize! :create, Spree::Variant + @variant = scope.new(variant_params) + if @variant.save + render json: @variant, serializer: Api::VariantSerializer, status: :created + else + invalid_resource!(@variant) + end + end + + def update + authorize! :update, Spree::Variant + @variant = scope.find(params[:id]) + if @variant.update(variant_params) + render json: @variant, serializer: Api::VariantSerializer, status: :ok + else + invalid_resource!(@product) + end + end + + def destroy + authorize! :delete, Spree::Variant + @variant = scope.find(params[:id]) + authorize! :delete, @variant + + VariantDeleter.new.delete(@variant) + render json: @variant, serializer: Api::VariantSerializer, status: :no_content + end + + private + + def product + @product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id] + end + + def scope + if @product + variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted] + @product.variants_including_master.with_deleted + else + @product.variants_including_master + end + else + variants = Spree::Variant.where(nil) + if current_api_user.has_spree_role?("admin") + unless params[:show_deleted] + variants = Spree::Variant.active + end + else + variants = variants.active + end + end + variants + end + + def variant_params + params.require(:variant).permit(PermittedAttributes::Variant.attributes) + end + end + end +end diff --git a/app/controllers/api/variants_controller.rb b/app/controllers/api/variants_controller.rb deleted file mode 100644 index 47b12e1e92..0000000000 --- a/app/controllers/api/variants_controller.rb +++ /dev/null @@ -1,77 +0,0 @@ -module Api - class VariantsController < Api::BaseController - respond_to :json - - skip_authorization_check only: [:index, :show] - before_action :product - - def index - @variants = scope.includes(option_values: :option_type).ransack(params[:q]).result - render json: @variants, each_serializer: Api::VariantSerializer - end - - def show - @variant = scope.includes(option_values: :option_type).find(params[:id]) - render json: @variant, serializer: Api::VariantSerializer - end - - def create - authorize! :create, Spree::Variant - @variant = scope.new(variant_params) - if @variant.save - render json: @variant, serializer: Api::VariantSerializer, status: :created - else - invalid_resource!(@variant) - end - end - - def update - authorize! :update, Spree::Variant - @variant = scope.find(params[:id]) - if @variant.update(variant_params) - render json: @variant, serializer: Api::VariantSerializer, status: :ok - else - invalid_resource!(@product) - end - end - - def destroy - authorize! :delete, Spree::Variant - @variant = scope.find(params[:id]) - authorize! :delete, @variant - - VariantDeleter.new.delete(@variant) - render json: @variant, serializer: Api::VariantSerializer, status: :no_content - end - - private - - def product - @product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id] - end - - def scope - if @product - variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted] - @product.variants_including_master.with_deleted - else - @product.variants_including_master - end - else - variants = Spree::Variant.where(nil) - if current_api_user.has_spree_role?("admin") - unless params[:show_deleted] - variants = Spree::Variant.active - end - else - variants = variants.active - end - end - variants - end - - def variant_params - params.require(:variant).permit(PermittedAttributes::Variant.attributes) - end - end -end diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 1b8cd07d67..a1c69500bf 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -14,7 +14,7 @@ class CheckoutController < ::BaseController # We need pessimistic locking to avoid race conditions. # Otherwise we fail on duplicate indexes or end up with negative stock. - prepend_around_action CurrentOrderLocker, only: :update + prepend_around_action CurrentOrderLocker, only: [:edit, :update] prepend_before_action :check_hub_ready_for_checkout prepend_before_action :check_order_cycle_expiry diff --git a/app/controllers/spree/admin/adjustments_controller.rb b/app/controllers/spree/admin/adjustments_controller.rb index d596ed9b16..d5729a3477 100644 --- a/app/controllers/spree/admin/adjustments_controller.rb +++ b/app/controllers/spree/admin/adjustments_controller.rb @@ -5,6 +5,7 @@ module Spree prepend_before_action :set_included_tax, only: [:create, :update] before_action :set_order_id, only: [:create, :update] + before_action :skip_changing_canceled_orders, only: [:create, :update] after_action :update_order, only: [:create, :update, :destroy] before_action :set_default_tax_rate, only: :edit before_action :enable_updates, only: :update @@ -17,7 +18,12 @@ module Spree end def collection - parent.adjustments.eligible | parent.shipment_adjustments.shipping + order_adjustments = parent.adjustments.where.not(originator_type: 'EnterpriseFee') + admin_adjustments = parent.adjustments.admin + payment_fees = parent.all_adjustments.payment_fee.eligible + shipping_fees = parent.all_adjustments.shipping + + order_adjustments.or(admin_adjustments) | payment_fees.or(shipping_fees) end def find_resource @@ -28,6 +34,13 @@ module Spree @adjustment.order_id = parent.id end + def skip_changing_canceled_orders + return unless @order.canceled? + + flash[:error] = t("admin.adjustments.skipped_changing_canceled_order") + redirect_to admin_order_adjustments_path(@order) if @order.canceled? + end + # Choose a default tax rate to show on the edit form. The adjustment stores its included # tax in dollars, but doesn't store the source of the tax (ie. TaxRate that generated it). # We guess which tax rate here, choosing: diff --git a/app/controllers/spree/admin/general_settings_controller.rb b/app/controllers/spree/admin/general_settings_controller.rb index 7c2ef6e695..dd5fbbc51f 100644 --- a/app/controllers/spree/admin/general_settings_controller.rb +++ b/app/controllers/spree/admin/general_settings_controller.rb @@ -3,7 +3,7 @@ module Spree class GeneralSettingsController < Spree::Admin::BaseController def edit @preferences_general = [:site_name, :default_seo_title, :default_meta_keywords, - :default_meta_description, :site_url, :bugherd_api_key] + :default_meta_description, :site_url] @preferences_security = [:allow_ssl_in_production, :allow_ssl_in_staging, :allow_ssl_in_development_and_test] @preferences_currency = [:display_currency, :hide_cents] diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb index e5bc415bc5..bb4e1943d1 100644 --- a/app/controllers/spree/admin/orders_controller.rb +++ b/app/controllers/spree/admin/orders_controller.rb @@ -38,11 +38,12 @@ module Spree @order.recreate_all_fees! unless order_params.present? && @order.update(order_params) && @order.line_items.present? - if @order.line_items.empty? + if @order.line_items.empty? && !params[:suppress_error_msg] @order.errors.add(:line_items, Spree.t('errors.messages.blank')) end - return redirect_to(spree.edit_admin_order_path(@order), - flash: { error: @order.errors.full_messages.join(', ') }) + + flash[:error] = @order.errors.full_messages.join(', ') if @order.errors.present? + return redirect_to spree.edit_admin_order_path(@order) end if @order.complete? @@ -89,7 +90,7 @@ module Spree end def print - render InvoiceRenderer.new.args(@order) + render_with_wicked_pdf InvoiceRenderer.new.args(@order) end def print_ticket diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index 9cfd7c2492..0544f94faa 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -5,7 +5,6 @@ module Spree before_action :load_data before_action :validate_payment_method_provider, only: [:create] before_action :load_hubs, only: [:new, :edit, :update] - create.before :load_hubs respond_to :html @@ -15,14 +14,12 @@ module Spree @payment_method = payment_method_class.constantize.new(base_params) @object = @payment_method - invoke_callbacks(:create, :before) + load_hubs if @payment_method.save - invoke_callbacks(:create, :after) flash[:success] = Spree.t(:successfully_created, resource: Spree.t(:payment_method)) redirect_to spree.edit_admin_payment_method_path(@payment_method) else - invoke_callbacks(:create, :fails) respond_with(@payment_method) end end @@ -31,8 +28,6 @@ module Spree restrict_stripe_account_change force_environment - invoke_callbacks(:update, :before) - if @payment_method.type.to_s != payment_method_class @payment_method.update_columns( type: payment_method_class, @@ -42,11 +37,9 @@ module Spree end if @payment_method.update(update_params) - invoke_callbacks(:update, :after) flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:payment_method)) redirect_to spree.edit_admin_payment_method_path(@payment_method) else - invoke_callbacks(:update, :fails) respond_with(@payment_method) end end diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index 0860d5a5a5..6dfd8d629a 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -38,7 +38,6 @@ module Spree end end rescue Paperclip::Errors::NotIdentifiedByImageMagickError - invoke_callbacks(:create, :fails) @object.errors.add(:base, t('spree.admin.products.image_upload_error')) respond_with(@object) end @@ -80,7 +79,7 @@ module Spree product_set.collection.each { |p| authorize! :update, p } if product_set.save - redirect_to main_app.bulk_products_api_products_path(bulk_index_query) + redirect_to main_app.bulk_products_api_v0_products_path(bulk_index_query) elsif product_set.errors.present? render json: { errors: product_set.errors }, status: :bad_request else diff --git a/app/controllers/spree/admin/return_authorizations_controller.rb b/app/controllers/spree/admin/return_authorizations_controller.rb index ac229acf83..094dd37d4a 100644 --- a/app/controllers/spree/admin/return_authorizations_controller.rb +++ b/app/controllers/spree/admin/return_authorizations_controller.rb @@ -3,8 +3,7 @@ module Spree class ReturnAuthorizationsController < ::Admin::ResourceController belongs_to 'spree/order', find_by: :number - update.after :associate_inventory_units - create.after :associate_inventory_units + after_action :associate_inventory_units, only: [:create, :update] def fire @return_authorization.public_send("#{params[:e]}!") diff --git a/app/controllers/spree/admin/shipping_methods_controller.rb b/app/controllers/spree/admin/shipping_methods_controller.rb index 1ede5fe867..027603bff6 100644 --- a/app/controllers/spree/admin/shipping_methods_controller.rb +++ b/app/controllers/spree/admin/shipping_methods_controller.rb @@ -79,13 +79,14 @@ module Spree def load_data @available_zones = Zone.order(:name) + @tax_categories = Spree::TaxCategory.order(:name) @calculators = ShippingMethod.calculators.sort_by(&:name) end def permitted_resource_params params.require(:shipping_method).permit( :name, :description, :display_on, :require_ship_address, :tag_list, :calculator_type, - distributor_ids: [], + :tax_category_id, distributor_ids: [], calculator_attributes: PermittedAttributes::Calculator.attributes ) end diff --git a/app/controllers/spree/admin/tax_settings_controller.rb b/app/controllers/spree/admin/tax_settings_controller.rb index 564a090da4..7ebeec543b 100644 --- a/app/controllers/spree/admin/tax_settings_controller.rb +++ b/app/controllers/spree/admin/tax_settings_controller.rb @@ -14,11 +14,7 @@ module Spree private def preferences_params - params.require(:preferences).permit( - :products_require_tax_category, - :shipment_inc_vat, - :shipping_tax_rate, - ) + params.require(:preferences).permit(:products_require_tax_category) end end end diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index 30ebca12ca..032e3aed56 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -102,7 +102,6 @@ module Spree # handling raise from Admin::ResourceController#destroy def user_destroy_with_orders_error - invoke_callbacks(:destroy, :fails) render status: :forbidden, text: Spree.t(:error_user_destroy_with_orders) end diff --git a/app/controllers/spree/admin/variants_controller.rb b/app/controllers/spree/admin/variants_controller.rb index 2177080a8f..c11c89b5af 100644 --- a/app/controllers/spree/admin/variants_controller.rb +++ b/app/controllers/spree/admin/variants_controller.rb @@ -4,9 +4,9 @@ module Spree module Admin class VariantsController < ::Admin::ResourceController helper 'spree/products' - belongs_to 'spree/product', find_by: :permalink - new_action.before :new_before + + before_action :assign_default_attributes, only: :new def index @url_filters = ::ProductFilters.new.extract(request.query_parameters) @@ -84,7 +84,7 @@ module Spree @object.save end - def new_before + def assign_default_attributes @object.attributes = @object.product.master. attributes.except('id', 'created_at', 'deleted_at', 'sku', 'is_master') # Shallow Clone of the default price to populate the price field. diff --git a/app/controllers/spree/checkout_controller.rb b/app/controllers/spree/checkout_controller.rb deleted file mode 100644 index e639505e29..0000000000 --- a/app/controllers/spree/checkout_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# This controller (and respective route in the Spree engine) -# is only needed for the spree_paypal_express gem that redirects here explicitly. -# -# According to the rails docs it would be possible to redirect -# to CheckoutController directly in the routes -# with a slash like "to: '/checkout#edit'", but it does not work in this case. -module Spree - class CheckoutController < ::BaseController - def edit - flash.keep - redirect_to main_app.checkout_path - end - end -end diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb index 7eb12a39c5..caf38e8a77 100644 --- a/app/controllers/spree/orders_controller.rb +++ b/app/controllers/spree/orders_controller.rb @@ -86,13 +86,14 @@ module Spree if @order.complete? @order.update_shipping_fees! @order.update_payment_fees! + @order.create_tax_charge! end respond_with(@order) do |format| format.html do if params.key?(:checkout) @order.next_transition.run_callbacks if @order.cart? - redirect_to checkout_state_path(@order.checkout_steps.first) + redirect_to main_app.checkout_state_path(@order.checkout_steps.first) elsif @order.complete? redirect_to order_path(@order) else @@ -103,7 +104,7 @@ module Spree else # Show order with original values, not newly entered ones @insufficient_stock_lines = @order.insufficient_stock_lines - @order.line_items(true) + @order.line_items.reload respond_with(@order) end end diff --git a/app/controllers/spree/paypal_controller.rb b/app/controllers/spree/paypal_controller.rb index e139d53908..cae37e716b 100644 --- a/app/controllers/spree/paypal_controller.rb +++ b/app/controllers/spree/paypal_controller.rb @@ -27,11 +27,11 @@ module Spree redirect_to provider.express_checkout_url(pp_response, useraction: 'commit') else flash[:error] = Spree.t('flash.generic_error', scope: 'paypal', reasons: pp_response.errors.map(&:long_message).join(" ")) - redirect_to spree.checkout_state_path(:payment) + redirect_to main_app.checkout_state_path(:payment) end rescue SocketError flash[:error] = Spree.t('flash.connection_failed', scope: 'paypal') - redirect_to spree.checkout_state_path(:payment) + redirect_to main_app.checkout_state_path(:payment) end end @@ -57,7 +57,7 @@ module Spree session[:order_id] = nil redirect_to completion_route(@order) else - redirect_to checkout_state_path(@order.state) + redirect_to main_app.checkout_state_path(@order.state) end end diff --git a/app/controllers/spree/users_controller.rb b/app/controllers/spree/users_controller.rb index 93350cd187..a591e20064 100644 --- a/app/controllers/spree/users_controller.rb +++ b/app/controllers/spree/users_controller.rb @@ -60,11 +60,7 @@ module Spree private def orders_collection - if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, spree_current_user) - CompleteOrdersWithBalance.new(@user).query - else - @user.orders.where(state: 'complete').order('completed_at desc') - end + CompleteOrdersWithBalance.new(@user).query end def load_object diff --git a/app/helpers/admin/orders_helper.rb b/app/helpers/admin/orders_helper.rb index 9e16d27ed5..4be258821a 100644 --- a/app/helpers/admin/orders_helper.rb +++ b/app/helpers/admin/orders_helper.rb @@ -5,9 +5,7 @@ module Admin # We exclude shipping method adjustments because they are displayed in a # separate table together with the order line items. def order_adjustments_for_display(order) - order.adjustments.eligible.reject do |adjustment| - adjustment.originator_type == "Spree::ShippingMethod" - end + order.adjustments + order.all_adjustments.payment_fee.eligible end end end diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index 47d2522afe..5d764e15c4 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -4,19 +4,18 @@ module CheckoutHelper end def checkout_adjustments_for(order, opts = {}) - adjustments = order.adjustments.eligible exclude = opts[:exclude] || {} - adjustments = adjustments.to_a + order.shipment_adjustments.to_a + adjustments = order.all_adjustments.eligible.to_a # Remove empty tax adjustments and (optionally) shipping fees adjustments.reject! { |a| a.originator_type == 'Spree::TaxRate' && a.amount == 0 } adjustments.reject! { |a| a.originator_type == 'Spree::ShippingMethod' } if exclude.include? :shipping adjustments.reject! { |a| a.originator_type == 'Spree::PaymentMethod' } if exclude.include? :payment - adjustments.reject! { |a| a.source_type == 'Spree::LineItem' } if exclude.include? :line_item + adjustments.reject! { |a| a.adjustable_type == 'Spree::LineItem' } if exclude.include? :line_item - enterprise_fee_adjustments = adjustments.select { |a| a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem' } - adjustments.reject! { |a| a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem' } + enterprise_fee_adjustments = adjustments.select { |a| a.originator_type == 'EnterpriseFee' && a.adjustable_type != 'Spree::LineItem' } + adjustments.reject! { |a| a.originator_type == 'EnterpriseFee' && a.adjustable_type != 'Spree::LineItem' } unless exclude.include? :admin_and_handling adjustments << Spree::Adjustment.new( label: I18n.t(:orders_form_admin), amount: enterprise_fee_adjustments.sum(&:amount) @@ -26,17 +25,16 @@ module CheckoutHelper adjustments end - def display_checkout_admin_and_handling_adjustments_total_for(order) - adjustments = order.adjustments.eligible.where('originator_type = ? AND source_type != ? ', 'EnterpriseFee', 'Spree::LineItem') - Spree::Money.new adjustments.sum(:amount), currency: order.currency + def display_line_item_fees_total_for(order) + Spree::Money.new order.adjustments.enterprise_fee.sum(:amount), currency: order.currency end - def checkout_line_item_adjustments(order) - order.adjustments.eligible.where(source_type: "Spree::LineItem") + def checkout_line_item_fees(order) + order.line_item_adjustments.enterprise_fee end def checkout_subtotal(order) - order.item_total + checkout_line_item_adjustments(order).sum(:amount) + order.item_total + checkout_line_item_fees(order).sum(:amount) end def display_checkout_subtotal(order) diff --git a/app/helpers/order_helper.rb b/app/helpers/order_helper.rb index c6ab5807bb..e15b8acdbb 100644 --- a/app/helpers/order_helper.rb +++ b/app/helpers/order_helper.rb @@ -6,6 +6,6 @@ module OrderHelper end def outstanding_balance_label(order) - order.outstanding_balance.negative? ? t(:credit_owed) : t(:balance_due) + order.outstanding_balance.label end end diff --git a/app/helpers/shop_helper.rb b/app/helpers/shop_helper.rb index 8da650c4ef..fbd48f719f 100644 --- a/app/helpers/shop_helper.rb +++ b/app/helpers/shop_helper.rb @@ -1,13 +1,4 @@ module ShopHelper - def order_cycles_name_and_pickup_times(order_cycles) - order_cycles.map do |oc| - [ - pickup_time(oc), - oc.id - ] - end - end - def oc_select_options @order_cycles.map { |oc| { time: pickup_time(oc), id: oc.id } } end @@ -29,9 +20,9 @@ module ShopHelper { name: 'home', title: t(:shopping_tabs_home), show: show_home_tab? }, { name: 'shop', title: t(:shopping_tabs_shop), show: !require_customer? }, { name: 'about', title: t(:shopping_tabs_about), show: true }, - { name: 'producers', title: t(:label_producers), show: true }, + { name: 'producers', title: t(:shopping_tabs_producers), show: true }, { name: 'contact', title: t(:shopping_tabs_contact), show: true }, - { name: 'groups', title: t(:label_groups), show: current_distributor.groups.any? }, + { name: 'groups', title: t(:shopping_tabs_groups), show: current_distributor.groups.any? }, ].select{ |tab| tab[:show] } end diff --git a/app/helpers/spree/admin/orders_helper.rb b/app/helpers/spree/admin/orders_helper.rb index 8a93ff2f54..112b264d7f 100644 --- a/app/helpers/spree/admin/orders_helper.rb +++ b/app/helpers/spree/admin/orders_helper.rb @@ -50,13 +50,13 @@ module Spree def edit_order_link { name: t(:edit_order), - url: edit_admin_order_path(@order), + url: spree.edit_admin_order_path(@order), icon: 'icon-edit' } end def resend_confirmation_link { name: t(:resend_confirmation), - url: resend_admin_order_path(@order), + url: spree.resend_admin_order_path(@order), icon: 'icon-email', method: 'post', confirm: t(:confirm_resend_order_confirmation) } @@ -78,7 +78,7 @@ module Spree def print_invoice_link { name: t(:print_invoice), - url: print_admin_order_path(@order), + url: spree.print_admin_order_path(@order), icon: 'icon-print', target: "_blank" } end @@ -99,7 +99,7 @@ module Spree def ship_order_link { name: t(:ship_order), - url: fire_admin_order_path(@order, e: 'ship'), + url: spree.fire_admin_order_path(@order, e: 'ship'), method: 'put', icon: 'icon-truck', confirm: t(:are_you_sure) } @@ -107,7 +107,7 @@ module Spree def cancel_order_link { name: t(:cancel_order), - url: fire_admin_order_path(@order.number, e: 'cancel'), + url: spree.fire_admin_order_path(@order.number, e: 'cancel'), icon: 'icon-trash', confirm: t(:are_you_sure) } end @@ -120,6 +120,14 @@ module Spree method: :put, icon: "icon-#{event}", data: { confirm: confirm_message }) end + + def quantity_field_tag(manifest_item) + html_options = { min: 0, class: "line_item_quantity", size: 5 } + unless manifest_item.variant.on_demand + html_options.merge!(max: manifest_item.variant.on_hand + manifest_item.quantity) + end + number_field_tag :quantity, manifest_item.quantity, html_options + end end end end diff --git a/app/helpers/spree/api/api_helpers.rb b/app/helpers/spree/api/api_helpers.rb deleted file mode 100644 index c0fcc20b40..0000000000 --- a/app/helpers/spree/api/api_helpers.rb +++ /dev/null @@ -1,120 +0,0 @@ -module Spree - module Api - module ApiHelpers - def required_fields_for(model) - required_fields = model._validators.select do |_field, validations| - validations.any? { |v| v.is_a?(ActiveModel::Validations::PresenceValidator) } - end.map(&:first) # get fields that are invalid - # Permalinks presence is validated, but are really automatically generated - # Therefore we shouldn't tell API clients that they MUST send one through - required_fields.map!(&:to_s).delete("permalink") - required_fields - end - - def product_attributes - [:id, :name, :description, :price, :available_on, :permalink, :meta_description, - :meta_keywords, :shipping_category_id, :taxon_ids] - end - - def product_property_attributes - [:id, :product_id, :property_id, :value, :property_name] - end - - def variant_attributes - [:id, :name, :sku, :price, :weight, :height, :width, :depth, - :is_master, :permalink] - end - - def image_attributes - [:id, :position, :attachment_content_type, :attachment_file_name, - :type, :attachment_updated_at, :attachment_width, :attachment_height, :alt] - end - - def option_value_attributes - [:id, :name, :presentation, :option_type_name, :option_type_id] - end - - def order_attributes - [:id, :number, :item_total, :total, :state, :adjustment_total, :user_id, - :created_at, :updated_at, :completed_at, :payment_total, - :shipment_state, :payment_state, :email, :special_instructions, :token] - end - - def line_item_attributes - [:id, :quantity, :price, :variant_id] - end - - def option_type_attributes - [:id, :name, :presentation, :position] - end - - def payment_attributes - [:id, :source_type, :source_id, :amount, :payment_method_id, - :response_code, :state, :avs_response, :created_at, :updated_at] - end - - def payment_method_attributes - [:id, :name, :description] - end - - def shipment_attributes - [:id, :tracking, :number, :cost, :shipped_at, :state] - end - - def taxonomy_attributes - [:id, :name] - end - - def taxon_attributes - [:id, :name, :pretty_name, :permalink, :position, :parent_id, :taxonomy_id] - end - - def inventory_unit_attributes - [:id, :lock_version, :state, :variant_id, :shipment_id, :return_authorization_id] - end - - def return_authorization_attributes - [:id, :number, :state, :amount, :order_id, :reason, :created_at, :updated_at] - end - - def country_attributes - [:id, :iso_name, :iso, :iso3, :name, :numcode] - end - - def state_attributes - [:id, :name, :abbr, :country_id] - end - - def adjustment_attributes - [:id, :source_type, :source_id, :adjustable_type, :adjustable_id, :originator_type, - :originator_id, :amount, :label, :mandatory, :locked, :eligible, :created_at, :updated_at] - end - - def creditcard_attributes - [:id, :month, :year, :cc_type, :last_digits, :first_name, :last_name, - :gateway_customer_profile_id, :gateway_payment_profile_id] - end - - def user_attributes - [:id, :email, :created_at, :updated_at] - end - - def property_attributes - [:id, :name, :presentation] - end - - def stock_location_attributes - [:id, :name, :address1, :address2, :city, - :state_id, :state_name, :country_id, :zipcode, :phone, :active] - end - - def stock_movement_attributes - [:id, :quantity, :stock_item_id] - end - - def stock_item_attributes - [:id, :count_on_hand, :backorderable, :lock_version, :stock_location_id, :variant_id] - end - end - end -end diff --git a/app/jobs/subscription_placement_job.rb b/app/jobs/subscription_placement_job.rb index ee4369c1d9..69bcaea69e 100644 --- a/app/jobs/subscription_placement_job.rb +++ b/app/jobs/subscription_placement_job.rb @@ -3,7 +3,6 @@ require 'order_management/subscriptions/summarizer' class SubscriptionPlacementJob < ActiveJob::Base def perform ids = proxy_orders.pluck(:id) - proxy_orders.update_all(placed_at: Time.zone.now) ProxyOrder.where(id: ids).each do |proxy_order| place_order_for(proxy_order) end @@ -13,8 +12,8 @@ class SubscriptionPlacementJob < ActiveJob::Base private - delegate :record_order, :record_success, :record_issue, to: :summarizer - delegate :record_and_log_error, :send_placement_summary_emails, to: :summarizer + delegate :record_success, :record_issue, :record_subscription_issue, to: :summarizer + delegate :record_order, :record_and_log_error, :send_placement_summary_emails, to: :summarizer def summarizer @summarizer ||= OrderManagement::Subscriptions::Summarizer.new @@ -30,11 +29,15 @@ class SubscriptionPlacementJob < ActiveJob::Base def place_order_for(proxy_order) JobLogger.logger.info("Placing Order for Proxy Order #{proxy_order.id}") initialise_order(proxy_order) + return unless proxy_order.order.present? + + proxy_order.update_column(:placed_at, Time.zone.now) place_order(proxy_order.order) end def initialise_order(proxy_order) proxy_order.initialise_order! + record_subscription_issue(proxy_order.subscription) if proxy_order.order.nil? rescue StandardError => e Bugsnag.notify(e, subscription: proxy_order.subscription, proxy_order: proxy_order) end @@ -62,12 +65,18 @@ class SubscriptionPlacementJob < ActiveJob::Base unavailable_stock_lines_for(order).each do |line_item| changes[line_item.id] = changes[line_item.id] || line_item.quantity line_item.update(quantity: 0) + + Spree::OrderInventory.new(order).verify(line_item, order.shipment) + end + if changes.present? + order.line_items.reload + order.update_order_fees! end changes end def handle_empty_order(order, changes) - order.reload.adjustments.destroy_all + order.reload.all_adjustments.destroy_all order.update! send_empty_email(order, changes) end diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index 9f46b26a85..f135e16dfd 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -7,20 +7,18 @@ class ProducerMailer < Spree::BaseMailer @producer = producer @order_cycle = order_cycle - with_unscoped_products_and_variants do - load_data + load_data - I18n.with_locale(owner_locale) do - return unless orders?(order_cycle, producer) + I18n.with_locale(owner_locale) do + return unless orders?(order_cycle, producer) - mail( - to: @producer.contact.email, - from: from_address, - subject: subject, - reply_to: @coordinator.contact.email, - cc: @coordinator.contact.email - ) - end + mail( + to: @producer.contact.email, + from: from_address, + subject: subject, + reply_to: @coordinator.contact.email, + cc: @coordinator.contact.email + ) end end @@ -65,7 +63,7 @@ class ProducerMailer < Spree::BaseMailer includes(:option_values, variant: [:product, { option_values: :option_type }]). from_order_cycle(order_cycle). sorted_by_name_and_unit_value. - merge(Spree::Product.in_supplier(producer)). + merge(Spree::Product.with_deleted.in_supplier(producer)). merge(Spree::Order.by_state('complete')) end @@ -76,22 +74,4 @@ class ProducerMailer < Spree::BaseMailer def tax_total_from_line_items(line_items) Spree::Money.new line_items.to_a.sum(&:included_tax) end - - # This hack makes ActiveRecord skip the default_scope (deleted_at IS NULL) - # when eager loading associations. Further details: - # https://github.com/rails/rails/issues/11036 - def with_unscoped_products_and_variants - variant_default_scopes = Spree::Variant.default_scopes - product_default_scopes = Spree::Product.default_scopes - - Spree::Variant.default_scopes = [] - Spree::Product.default_scopes = [] - - return_value = yield - - Spree::Variant.default_scopes = variant_default_scopes - Spree::Product.default_scopes = product_default_scopes - - return_value - end end diff --git a/app/models/adjustment_metadata.rb b/app/models/adjustment_metadata.rb index d8315a3c71..c282368aca 100644 --- a/app/models/adjustment_metadata.rb +++ b/app/models/adjustment_metadata.rb @@ -1,4 +1,4 @@ -class AdjustmentMetadata < ActiveRecord::Base +class AdjustmentMetadata < ApplicationRecord belongs_to :adjustment, class_name: 'Spree::Adjustment' belongs_to :enterprise end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000000..e4478b1559 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class ApplicationRecord < ActiveRecord::Base + include DelegateBelongsTo + include Spree::Core::Permalinks + include Spree::Preferences::Preferable + + self.abstract_class = true +end diff --git a/app/models/calculator/default_tax.rb b/app/models/calculator/default_tax.rb index 5293dfd1cb..3ab75caac3 100644 --- a/app/models/calculator/default_tax.rb +++ b/app/models/calculator/default_tax.rb @@ -13,6 +13,8 @@ module Calculator case computable when Spree::Order compute_order(computable) + when Spree::Shipment + compute_shipment(computable) when Spree::LineItem compute_line_item(computable) end @@ -31,6 +33,7 @@ module Calculator [ line_items_total(order), + shipments_total(order), per_item_fees_total(order, calculator), per_order_fees_total(order, calculator) ].sum do |total| @@ -46,6 +49,12 @@ module Calculator matched_line_items.sum(&:total) end + def shipments_total(order) + order.shipments.select do |shipment| + shipment.tax_category == rate.tax_category + end.sum(&:cost) + end + # Finds relevant fees for each line_item, # calculates the tax on them, and returns the total tax def per_item_fees_total(order, calculator) @@ -70,17 +79,19 @@ module Calculator .sum { |applicator| applicator.enterprise_fee.compute_amount(order) } end - def compute_line_item(line_item) - if line_item.tax_category == rate.tax_category + def compute_shipment_or_line_item(item) + if item.tax_category == rate.tax_category if rate.included_in_price - deduced_total_by_rate(line_item.total, rate) + deduced_total_by_rate(item.amount, rate) else - round_to_two_places(line_item.total * rate.amount) + round_to_two_places(item.amount * rate.amount) end else 0 end end + alias_method :compute_shipment, :compute_shipment_or_line_item + alias_method :compute_line_item, :compute_shipment_or_line_item def round_to_two_places(amount) BigDecimal(amount.to_s).round(2, BigDecimal::ROUND_HALF_UP) diff --git a/app/models/column_preference.rb b/app/models/column_preference.rb index ae5cdd9127..0b60831541 100644 --- a/app/models/column_preference.rb +++ b/app/models/column_preference.rb @@ -1,6 +1,6 @@ require 'open_food_network/column_preference_defaults' -class ColumnPreference < ActiveRecord::Base +class ColumnPreference < ApplicationRecord extend OpenFoodNetwork::ColumnPreferenceDefaults # Non-persisted attributes that only have one diff --git a/app/models/concerns/balance.rb b/app/models/concerns/balance.rb index 91019d401c..af70eacce5 100644 --- a/app/models/concerns/balance.rb +++ b/app/models/concerns/balance.rb @@ -7,13 +7,18 @@ require 'active_support/concern' module Balance FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze + # Branches by the OrderBalance abstraction + def outstanding_balance + @order_balance ||= OrderBalance.new(self) + end + # Returns the order balance by considering the total as money owed to the order distributor aka. - # the shop, and as a positive balance of said enterprise. If the customer pays it all, they + # the shop, and as a positive balance of said enterprise. If the customer pays it all, the # distributor and customer are even. # # Note however, this is meant to be used only in the context of a single order object. When - # working with a collection of orders, such an index controller action, please consider using - # `app/queries/oustanding_balance.rb` instead so we avoid potential N+1s. + # working with a collection of orders, such as an index controller action, please consider using + # `app/queries/outstanding_balance.rb` instead so we avoid potential N+1s. def new_outstanding_balance if state.in?(FINALIZED_NON_SUCCESSFUL_STATES) -payment_total @@ -22,22 +27,11 @@ module Balance end end - # This method is the one we're gradually replacing with `#new_outstanding_balance`. Having them - # separate enables us to choose which implementation we want depending on the context using - # a feature toggle. This avoids incosistent behavior across the app during that incremental - # refactoring. - # - # It is meant to be removed as soon as we get product approval that the new implementation has - # been working correctly in production. - def outstanding_balance - total - payment_total - end - def outstanding_balance? !outstanding_balance.zero? end def display_outstanding_balance - Spree::Money.new(outstanding_balance, currency: currency) + outstanding_balance.display_amount end end diff --git a/app/models/concerns/line_item_based_adjustment_handling.rb b/app/models/concerns/line_item_based_adjustment_handling.rb deleted file mode 100644 index 70aa9549c7..0000000000 --- a/app/models/concerns/line_item_based_adjustment_handling.rb +++ /dev/null @@ -1,8 +0,0 @@ -module LineItemBasedAdjustmentHandling - extend ActiveSupport::Concern - - included do - has_many :adjustments_for_which_source, class_name: "Spree::Adjustment", as: :source, - dependent: :destroy - end -end diff --git a/app/models/coordinator_fee.rb b/app/models/coordinator_fee.rb index f15a194158..92238cbebe 100644 --- a/app/models/coordinator_fee.rb +++ b/app/models/coordinator_fee.rb @@ -1,4 +1,4 @@ -class CoordinatorFee < ActiveRecord::Base +class CoordinatorFee < ApplicationRecord belongs_to :order_cycle belongs_to :enterprise_fee end diff --git a/app/models/customer.rb b/app/models/customer.rb index b1ba0f2651..e128bde491 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,4 +1,4 @@ -class Customer < ActiveRecord::Base +class Customer < ApplicationRecord acts_as_taggable belongs_to :enterprise @@ -19,7 +19,7 @@ class Customer < ActiveRecord::Base validates :code, uniqueness: { scope: :enterprise_id, allow_nil: true } validates :email, presence: true, uniqueness: { scope: :enterprise_id, message: I18n.t('validation_msg_is_associated_with_an_exising_customer') } - validates :enterprise_id, presence: true + validates :enterprise, presence: true scope :of, ->(enterprise) { where(enterprise_id: enterprise) } @@ -46,6 +46,6 @@ class Customer < ActiveRecord::Base return true unless orders.any? errors[:base] << I18n.t('admin.customers.destroy.has_associated_orders') - false + throw :abort end end diff --git a/app/models/distributor_shipping_method.rb b/app/models/distributor_shipping_method.rb index 5c69cefbc0..87aba1b139 100644 --- a/app/models/distributor_shipping_method.rb +++ b/app/models/distributor_shipping_method.rb @@ -1,4 +1,4 @@ -class DistributorShippingMethod < ActiveRecord::Base +class DistributorShippingMethod < ApplicationRecord self.table_name = "distributors_shipping_methods" belongs_to :shipping_method, class_name: "Spree::ShippingMethod", touch: true belongs_to :distributor, class_name: "Enterprise", touch: true diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index e73f715598..f77e634e96 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -2,7 +2,7 @@ require 'spree/core/s3_support' -class Enterprise < ActiveRecord::Base +class Enterprise < ApplicationRecord SELLS = %w(unspecified none own any).freeze ENTERPRISE_SEARCH_RADIUS = 100 diff --git a/app/models/enterprise_fee.rb b/app/models/enterprise_fee.rb index b7a3eeb6e2..ff17383598 100644 --- a/app/models/enterprise_fee.rb +++ b/app/models/enterprise_fee.rb @@ -1,4 +1,4 @@ -class EnterpriseFee < ActiveRecord::Base +class EnterpriseFee < ApplicationRecord include Spree::Core::CalculatedAdjustments acts_as_paranoid @@ -41,7 +41,7 @@ class EnterpriseFee < ActiveRecord::Base } def self.clear_all_adjustments(order) - order.adjustments.enterprise_fee.destroy_all + order.all_adjustments.enterprise_fee.destroy_all end private diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index b2bbfba198..cde5d60e7c 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -4,7 +4,7 @@ require 'open_food_network/locking' require 'open_food_network/permalink_generator' require 'spree/core/s3_support' -class EnterpriseGroup < ActiveRecord::Base +class EnterpriseGroup < ApplicationRecord include PermalinkGenerator acts_as_list diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index 0eb4ac3d69..87e745f3c4 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -class EnterpriseRelationship < ActiveRecord::Base +class EnterpriseRelationship < ApplicationRecord belongs_to :parent, class_name: 'Enterprise', touch: true belongs_to :child, class_name: 'Enterprise', touch: true has_many :permissions, class_name: 'EnterpriseRelationshipPermission', dependent: :destroy - validates :parent_id, :child_id, presence: true + validates :parent, :child, presence: true validates :child_id, uniqueness: { scope: :parent_id, message: I18n.t('validation_msg_relationship_already_established') diff --git a/app/models/enterprise_relationship_permission.rb b/app/models/enterprise_relationship_permission.rb index 5bd40bf70c..55d70d57a8 100644 --- a/app/models/enterprise_relationship_permission.rb +++ b/app/models/enterprise_relationship_permission.rb @@ -1,3 +1,3 @@ -class EnterpriseRelationshipPermission < ActiveRecord::Base +class EnterpriseRelationshipPermission < ApplicationRecord default_scope { order('name') } end diff --git a/app/models/enterprise_role.rb b/app/models/enterprise_role.rb index 0b686e2e6e..72071eb69e 100644 --- a/app/models/enterprise_role.rb +++ b/app/models/enterprise_role.rb @@ -1,8 +1,8 @@ -class EnterpriseRole < ActiveRecord::Base +class EnterpriseRole < ApplicationRecord belongs_to :user, class_name: Spree.user_class.to_s belongs_to :enterprise - validates :user_id, :enterprise_id, presence: true + validates :user, :enterprise, presence: true validates :enterprise_id, uniqueness: { scope: :user_id, message: I18n.t(:enterprise_role_uniqueness_error) } scope :by_user_email, -> { joins(:user).order('spree_users.email ASC') } diff --git a/app/models/exchange.rb b/app/models/exchange.rb index 01e23405a5..a05e7cb201 100644 --- a/app/models/exchange.rb +++ b/app/models/exchange.rb @@ -7,12 +7,12 @@ # in its shopfront. Any incoming product can be selected to be shown in the # shopfront (outgoing products). But the set of shown products can be smaller # than all incoming products. -class Exchange < ActiveRecord::Base +class Exchange < ApplicationRecord acts_as_taggable belongs_to :order_cycle belongs_to :sender, class_name: 'Enterprise' - belongs_to :receiver, class_name: 'Enterprise', touch: true + belongs_to :receiver, class_name: 'Enterprise' has_many :exchange_variants, dependent: :destroy has_many :variants, through: :exchange_variants @@ -23,6 +23,8 @@ class Exchange < ActiveRecord::Base validates :order_cycle, :sender, :receiver, presence: true validates :sender_id, uniqueness: { scope: [:order_cycle_id, :receiver_id, :incoming] } + after_save :touch_receiver + accepts_nested_attributes_for :variants scope :in_order_cycle, lambda { |order_cycle| where(order_cycle_id: order_cycle) } @@ -95,4 +97,10 @@ class Exchange < ActiveRecord::Base def participant incoming? ? sender : receiver end + + def touch_receiver + return unless receiver&.persisted? + + receiver.touch_later + end end diff --git a/app/models/exchange_fee.rb b/app/models/exchange_fee.rb index ff9f12e8dd..7d9fa49269 100644 --- a/app/models/exchange_fee.rb +++ b/app/models/exchange_fee.rb @@ -1,4 +1,4 @@ -class ExchangeFee < ActiveRecord::Base +class ExchangeFee < ApplicationRecord belongs_to :exchange belongs_to :enterprise_fee end diff --git a/app/models/exchange_variant.rb b/app/models/exchange_variant.rb index 69e7bec7ba..01b792734e 100644 --- a/app/models/exchange_variant.rb +++ b/app/models/exchange_variant.rb @@ -1,4 +1,4 @@ -class ExchangeVariant < ActiveRecord::Base +class ExchangeVariant < ApplicationRecord belongs_to :exchange belongs_to :variant, class_name: 'Spree::Variant' end diff --git a/app/models/inventory_item.rb b/app/models/inventory_item.rb index 68f491ff6d..91ba0f6d10 100644 --- a/app/models/inventory_item.rb +++ b/app/models/inventory_item.rb @@ -1,10 +1,10 @@ -class InventoryItem < ActiveRecord::Base +class InventoryItem < ApplicationRecord belongs_to :enterprise belongs_to :variant, class_name: "Spree::Variant" validates :variant_id, uniqueness: { scope: :enterprise_id } - validates :enterprise_id, presence: true - validates :variant_id, presence: true + validates :enterprise, presence: true + validates :variant, presence: true validates :visible, inclusion: { in: [true, false], message: I18n.t(:inventory_item_visibility_error) } scope :visible, -> { where(visible: true) } diff --git a/app/models/order_balance.rb b/app/models/order_balance.rb index 58fb03a353..1e09940808 100644 --- a/app/models/order_balance.rb +++ b/app/models/order_balance.rb @@ -1,33 +1,29 @@ # frozen_string_literal: true class OrderBalance + delegate :zero?, :abs, :to_s, :to_f, :to_d, :<, :>, to: :amount + def initialize(order) @order = order end def label - to_f.negative? ? I18n.t(:credit_owed) : I18n.t(:balance_due) + amount.negative? ? I18n.t(:credit_owed) : I18n.t(:balance_due) + end + + def display_amount + Spree::Money.new(amount, currency: order.currency) end def amount - Spree::Money.new(to_f, currency: order.currency) + order.new_outstanding_balance end - def to_f - if customer_balance_enabled? - order.new_outstanding_balance - else - order.outstanding_balance - end + def +(other) + amount + other.to_f end - delegate :zero?, to: :to_f - private attr_reader :order - - def customer_balance_enabled? - OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, order.user) - end end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 93451f081c..37073c3628 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -1,6 +1,6 @@ require 'open_food_network/scope_variant_to_hub' -class OrderCycle < ActiveRecord::Base +class OrderCycle < ApplicationRecord belongs_to :coordinator, class_name: 'Enterprise' has_many :coordinator_fee_refs, class_name: 'CoordinatorFee' @@ -16,8 +16,8 @@ class OrderCycle < ActiveRecord::Base has_many :suppliers, -> { distinct }, source: :sender, through: :cached_incoming_exchanges has_many :distributors, -> { distinct }, source: :receiver, through: :cached_outgoing_exchanges - has_many :schedules, through: :order_cycle_schedules has_many :order_cycle_schedules + has_many :schedules, through: :order_cycle_schedules has_paper_trail meta: { custom_data: proc { |order_cycle| order_cycle.schedule_ids.to_s } } attr_accessor :incoming_exchanges, :outgoing_exchanges diff --git a/app/models/order_cycle_schedule.rb b/app/models/order_cycle_schedule.rb index bff4da5fc3..b3087cf11b 100644 --- a/app/models/order_cycle_schedule.rb +++ b/app/models/order_cycle_schedule.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class OrderCycleSchedule < ActiveRecord::Base +class OrderCycleSchedule < ApplicationRecord belongs_to :schedule belongs_to :order_cycle end diff --git a/app/models/producer_property.rb b/app/models/producer_property.rb index 278118871d..1d3ba6eb0e 100644 --- a/app/models/producer_property.rb +++ b/app/models/producer_property.rb @@ -1,4 +1,4 @@ -class ProducerProperty < ActiveRecord::Base +class ProducerProperty < ApplicationRecord belongs_to :producer, class_name: 'Enterprise', touch: true belongs_to :property, class_name: 'Spree::Property' diff --git a/app/models/proxy_order.rb b/app/models/proxy_order.rb index bece28a65d..c58d58528f 100644 --- a/app/models/proxy_order.rb +++ b/app/models/proxy_order.rb @@ -2,7 +2,7 @@ # Proxy pattern allows for deferral of initialization until absolutely required # This reduces the need to keep Orders in sync with their parent Subscriptions -class ProxyOrder < ActiveRecord::Base +class ProxyOrder < ApplicationRecord belongs_to :order, class_name: 'Spree::Order', dependent: :destroy belongs_to :subscription belongs_to :order_cycle diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 5fe5da3205..1a11305ede 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,10 +1,9 @@ -class Schedule < ActiveRecord::Base +class Schedule < ApplicationRecord has_paper_trail meta: { custom_data: proc { |schedule| schedule.order_cycle_ids.to_s } } - has_many :order_cycles, through: :order_cycle_schedules has_many :order_cycle_schedules, dependent: :destroy - - has_many :coordinators, -> { uniq }, through: :order_cycles + has_many :order_cycles, through: :order_cycle_schedules + has_many :coordinators, -> { distinct }, through: :order_cycles scope :with_coordinator, lambda { |enterprise| joins(:order_cycles).where('coordinator_id = ?', enterprise.id).select('DISTINCT schedules.*') } diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb index d3ed85c507..94fa8ebc2f 100644 --- a/app/models/spree/ability.rb +++ b/app/models/spree/ability.rb @@ -290,12 +290,8 @@ module Spree can [:destroy], Spree::Adjustment do |adjustment| if user.admin? true - elsif adjustment.adjustable.instance_of? Spree::Order - order = adjustment.adjustable - user.enterprises.include?(order.distributor) || - order.order_cycle.andand.coordinated_by?(user) - elsif adjustment.adjustable.instance_of? Spree::LineItem - order = adjustment.adjustable.order + else + order = adjustment.order user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user) end diff --git a/app/models/spree/address.rb b/app/models/spree/address.rb index 28bc7511d7..7a4307f2a1 100644 --- a/app/models/spree/address.rb +++ b/app/models/spree/address.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Address < ActiveRecord::Base + class Address < ApplicationRecord include AddressDisplay belongs_to :country, class_name: "Spree::Country" @@ -146,7 +146,9 @@ module Spree end def touch_enterprise - enterprise.andand.touch + return unless enterprise&.persisted? + + enterprise.touch end def render_address(parts) diff --git a/app/models/spree/adjustment.rb b/app/models/spree/adjustment.rb index ef34d0eb9f..c3efde7ab5 100644 --- a/app/models/spree/adjustment.rb +++ b/app/models/spree/adjustment.rb @@ -28,7 +28,7 @@ require 'concerns/adjustment_scopes' # total. This allows an adjustment to be preserved if it becomes ineligible so # it might be reinstated. module Spree - class Adjustment < ActiveRecord::Base + class Adjustment < ApplicationRecord extend Spree::LocalizedNumber # Deletion of metadata is handled in the database. @@ -37,8 +37,7 @@ module Spree has_one :metadata, class_name: 'AdjustmentMetadata' belongs_to :adjustable, polymorphic: true - belongs_to :source, polymorphic: true - belongs_to :originator, polymorphic: true + belongs_to :originator, -> { with_deleted }, polymorphic: true belongs_to :order, class_name: "Spree::Order" belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } }, @@ -47,6 +46,8 @@ module Spree validates :label, presence: true validates :amount, numericality: true + after_create :update_adjustable_adjustment_total + state_machine :state, initial: :open do event :close do transition from: :open, to: :closed @@ -66,15 +67,12 @@ module Spree scope :optional, -> { where(mandatory: false) } scope :charge, -> { where('amount >= 0') } scope :credit, -> { where('amount < 0') } - scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") } + scope :return_authorization, -> { where(originator_type: "Spree::ReturnAuthorization") } scope :inclusive, -> { where(included: true) } scope :additional, -> { where(included: false) } scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') } - scope :admin, -> { where(source_type: nil, originator_type: nil) } - scope :included_tax, -> { - where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem') - } + scope :admin, -> { where(originator_type: nil) } scope :with_tax, -> { where('spree_adjustments.included_tax <> 0') } scope :without_tax, -> { where('spree_adjustments.included_tax = 0') } @@ -99,13 +97,17 @@ module Spree # object on the association would be in a old state and therefore the # adjustment calculations would not performed on proper values def update!(calculable = nil, force: false) - return if immutable? && !force + return amount if immutable? && !force - # Fix for Spree issue #3381 - # If we attempt to call 'source' before the reload, then source is currently - # the order object. After calling a reload, the source is the Shipment. - reload - originator.update_adjustment(self, calculable || source) if originator.present? + if originator.present? + amount = originator.compute_amount(calculable || adjustable) + update_columns( + amount: amount, + updated_at: Time.zone.now, + ) + end + + amount end def currency @@ -116,13 +118,12 @@ module Spree Spree::Money.new(amount, currency: currency) end - def immutable? - state != "open" + def admin? + originator_type.nil? end - def set_included_tax!(rate) - tax = amount - (amount / (1 + rate)) - set_absolute_included_tax! tax + def immutable? + state != "open" end def set_absolute_included_tax!(tax) @@ -141,11 +142,10 @@ module Spree included_tax.positive? end - # Allow accessing soft-deleted originator objects - def originator - return if originator_type.blank? + private - originator_type.constantize.unscoped { super } + def update_adjustable_adjustment_total + Spree::ItemAdjustments.new(adjustable).update if adjustable end end end diff --git a/app/models/spree/app_configuration.rb b/app/models/spree/app_configuration.rb index d30f0e6215..5190b92547 100644 --- a/app/models/spree/app_configuration.rb +++ b/app/models/spree/app_configuration.rb @@ -58,7 +58,6 @@ module Spree preference :products_per_page, :integer, default: 12 preference :redirect_https_to_http, :boolean, default: false preference :require_master_price, :boolean, default: true - preference :shipment_inc_vat, :boolean, default: false # Request instructions/info for shipping preference :shipping_instructions, :boolean, default: false # Displays variant full price or difference with product price. @@ -118,13 +117,11 @@ module Spree # Tax Preferences preference :products_require_tax_category, :boolean, default: false - preference :shipping_tax_rate, :decimal, default: 0 # Monitoring preference :last_job_queue_heartbeat_at, :string, default: nil # External services - preference :bugherd_api_key, :string, default: nil preference :matomo_url, :string, default: nil preference :matomo_site_id, :string, default: nil preference :matomo_tag_manager_url, :string, default: nil diff --git a/app/models/spree/asset.rb b/app/models/spree/asset.rb index d5eb00d506..168435c12f 100644 --- a/app/models/spree/asset.rb +++ b/app/models/spree/asset.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Asset < ActiveRecord::Base + class Asset < ApplicationRecord belongs_to :viewable, polymorphic: true, touch: true acts_as_list scope: :viewable end diff --git a/app/models/spree/calculator.rb b/app/models/spree/calculator.rb index 40bea838f5..fa7880f3ec 100644 --- a/app/models/spree/calculator.rb +++ b/app/models/spree/calculator.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Calculator < ActiveRecord::Base + class Calculator < ApplicationRecord belongs_to :calculable, polymorphic: true # This method must be overriden in concrete calculator. diff --git a/app/models/spree/classification.rb b/app/models/spree/classification.rb index 0b668a068b..696595a033 100644 --- a/app/models/spree/classification.rb +++ b/app/models/spree/classification.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Classification < ActiveRecord::Base + class Classification < ApplicationRecord self.table_name = 'spree_products_taxons' belongs_to :product, class_name: "Spree::Product", touch: true belongs_to :taxon, class_name: "Spree::Taxon", touch: true @@ -15,7 +15,7 @@ module Spree errors.add :base, I18n.t(:spree_classification_primary_taxon_error, taxon: taxon.name, product: product.name) - false + throw :abort end end end diff --git a/app/models/spree/country.rb b/app/models/spree/country.rb index e0a69f3ae6..ee94968556 100644 --- a/app/models/spree/country.rb +++ b/app/models/spree/country.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Country < ActiveRecord::Base + class Country < ApplicationRecord has_many :states, -> { order('name ASC') } validates :name, :iso_name, presence: true diff --git a/app/models/spree/credit_card.rb b/app/models/spree/credit_card.rb index 5a4efea485..ef51c4898b 100644 --- a/app/models/spree/credit_card.rb +++ b/app/models/spree/credit_card.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class CreditCard < ActiveRecord::Base + class CreditCard < ApplicationRecord belongs_to :payment_method belongs_to :user diff --git a/app/models/spree/gateway.rb b/app/models/spree/gateway.rb index 4b7533c2d8..6a0320835b 100644 --- a/app/models/spree/gateway.rb +++ b/app/models/spree/gateway.rb @@ -28,7 +28,7 @@ module Spree gateway_options = options gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil? if gateway_options[:server] - ActiveMerchant::Billing::Base.gateway_mode = gateway_options[:server].to_sym + ActiveMerchant::Billing::Base.mode = gateway_options[:server].to_sym end @provider ||= provider_class.new(gateway_options) end diff --git a/app/models/spree/inventory_unit.rb b/app/models/spree/inventory_unit.rb index 79c834d490..7bad1f998c 100644 --- a/app/models/spree/inventory_unit.rb +++ b/app/models/spree/inventory_unit.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module Spree - class InventoryUnit < ActiveRecord::Base - belongs_to :variant, class_name: "Spree::Variant" + class InventoryUnit < ApplicationRecord + belongs_to :variant, -> { with_deleted }, class_name: "Spree::Variant" belongs_to :order, class_name: "Spree::Order" belongs_to :shipment, class_name: "Spree::Shipment" belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization", @@ -59,11 +59,6 @@ module Spree variant_id: variant_id) end - # Remove variant default_scope `deleted_at: nil` - def variant - Spree::Variant.unscoped { super } - end - private def allow_ship? diff --git a/app/models/spree/item_adjustments.rb b/app/models/spree/item_adjustments.rb new file mode 100644 index 0000000000..aedd8f0fbf --- /dev/null +++ b/app/models/spree/item_adjustments.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Spree + # Manage (recalculate) item (LineItem or Shipment) adjustments + class ItemAdjustments + attr_reader :item + + delegate :adjustments, :order, to: :item + + def initialize(item) + @item = item + end + + def update + update_adjustments if updatable_totals? + item + end + + def update_adjustments + adjustment_total = adjustments.additional.map(&:update!).compact.sum + included_tax_total = tax_adjustments.inclusive.reload.map(&:update!).compact.sum + additional_tax_total = tax_adjustments.additional.reload.map(&:update!).compact.sum + + item.update_columns( + included_tax_total: included_tax_total, + additional_tax_total: additional_tax_total, + adjustment_total: adjustment_total, + updated_at: Time.zone.now + ) + end + + private + + def updatable_totals? + item.persisted? && item.is_a?(Spree::Shipment) + end + + def tax_adjustments + (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax + end + end +end diff --git a/app/models/spree/line_item.rb b/app/models/spree/line_item.rb index d224b154a8..97cd7dd888 100644 --- a/app/models/spree/line_item.rb +++ b/app/models/spree/line_item.rb @@ -4,13 +4,12 @@ require 'open_food_network/scope_variant_to_hub' require 'variant_units/variant_and_line_item_naming' module Spree - class LineItem < ActiveRecord::Base + class LineItem < ApplicationRecord include VariantUnits::VariantAndLineItemNaming include LineItemStockChanges - include LineItemBasedAdjustmentHandling belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items - belongs_to :variant, class_name: "Spree::Variant" + belongs_to :variant, -> { with_deleted }, class_name: "Spree::Variant" belongs_to :tax_category, class_name: "Spree::TaxCategory" has_one :product, through: :variant @@ -154,18 +153,6 @@ module Spree @preferred_shipment = shipment end - # Remove product default_scope `deleted_at: nil` - def product - variant.product - end - - # This ensures that LineItems always have access to soft-deleted variants. - # In some situations, unscoped super will be nil. In these cases, - # we fetch the variant using variant_id. See issue #4946 for more details. - def variant - Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(variant_id) - end - def cap_quantity_at_stock! scoper.scope(variant) return if variant.on_demand @@ -190,9 +177,9 @@ module Spree # so line_item.adjustments returns an empty array return 0 if quantity.zero? - line_item_adjustments = OrderAdjustmentsFetcher.new(order).line_item_adjustments(self) + fees = adjustments.enterprise_fee.sum(:amount) - (price + line_item_adjustments.to_a.sum(&:amount) / quantity).round(2) + (price + fees / quantity).round(2) end def single_display_amount_with_adjustments @@ -220,9 +207,9 @@ module Spree end def unit_price_price_and_unit - price = Spree::Money.new((rand * 10).round(2), currency: currency) - unit = ["item", "kg"].sample - price.to_html + " / " + unit + unit_price = UnitPrice.new(variant) + Spree::Money.new(price_with_adjustments / unit_price.denominator).to_html + + " / ".html_safe + unit_price.unit end def scoper diff --git a/app/models/spree/log_entry.rb b/app/models/spree/log_entry.rb index 85b65fe8e7..449df8c4ec 100644 --- a/app/models/spree/log_entry.rb +++ b/app/models/spree/log_entry.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class LogEntry < ActiveRecord::Base + class LogEntry < ApplicationRecord belongs_to :source, polymorphic: true # Fix for Spree #1767 diff --git a/app/models/spree/option_type.rb b/app/models/spree/option_type.rb index 91b65c97bb..3c03976ec3 100644 --- a/app/models/spree/option_type.rb +++ b/app/models/spree/option_type.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class OptionType < ActiveRecord::Base + class OptionType < ApplicationRecord has_many :products, through: :product_option_types has_many :option_values, -> { order(:position) }, dependent: :destroy has_many :product_option_types, dependent: :destroy diff --git a/app/models/spree/option_value.rb b/app/models/spree/option_value.rb index b21eed19ba..f03301a5e5 100644 --- a/app/models/spree/option_value.rb +++ b/app/models/spree/option_value.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class OptionValue < ActiveRecord::Base + class OptionValue < ApplicationRecord belongs_to :option_type acts_as_list scope: :option_type has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants', diff --git a/app/models/spree/option_values_line_item.rb b/app/models/spree/option_values_line_item.rb index 4f1ab992a8..0b6632e7e3 100644 --- a/app/models/spree/option_values_line_item.rb +++ b/app/models/spree/option_values_line_item.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class OptionValuesLineItem < ActiveRecord::Base + class OptionValuesLineItem < ApplicationRecord belongs_to :line_item, class_name: 'Spree::LineItem' belongs_to :option_value, class_name: 'Spree::OptionValue' end diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index 6ed2f5fcc2..2a919c5463 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -7,7 +7,7 @@ require 'open_food_network/tag_rule_applicator' require 'concerns/order_shipment' module Spree - class Order < ActiveRecord::Base + class Order < ApplicationRecord prepend OrderShipment include Checkout @@ -42,16 +42,16 @@ module Spree as: :adjustable, dependent: :destroy - has_many :line_item_adjustments, through: :line_items, source: :adjustments - has_many :shipment_adjustments, through: :shipments, source: :adjustments - has_many :all_adjustments, class_name: 'Spree::Adjustment', dependent: :destroy - has_many :shipments, dependent: :destroy do def states pluck(:state).uniq end end + has_many :line_item_adjustments, through: :line_items, source: :adjustments + has_many :shipment_adjustments, through: :shipments, source: :adjustments + has_many :all_adjustments, class_name: 'Spree::Adjustment', dependent: :destroy + belongs_to :order_cycle belongs_to :distributor, class_name: 'Enterprise' belongs_to :customer @@ -541,21 +541,6 @@ module Spree shipments end - # Clean shipments and make order back to address state - # - # At some point the might need to force the order to transition from address - # to delivery again so that proper updated shipments are created. - # e.g. customer goes back from payment step and changes order items - def ensure_updated_shipments - return unless shipments.any? - - shipments.destroy_all - update_columns( - state: "address", - updated_at: Time.zone.now - ) - end - def refresh_shipment_rates shipments.map(&:refresh_rates) end @@ -646,17 +631,15 @@ module Spree end def shipping_tax - shipment_adjustments.reload.shipping.sum(:included_tax) + shipment_adjustments.reload.tax.sum(:amount) end def enterprise_fee_tax - adjustments.reload.enterprise_fee.sum(:included_tax) + all_adjustments.reload.enterprise_fee.sum(:included_tax) end def total_tax - adjustments.sum(:included_tax) + - shipment_adjustments.sum(:included_tax) + - line_item_adjustments.tax.sum(:amount) + additional_tax_total + included_tax_total end def has_taxes_included @@ -750,7 +733,8 @@ module Spree end def require_customer? - return true unless new_record? || state == 'cart' + return false if new_record? || state == 'cart' + true end def customer_is_valid? @@ -790,7 +774,7 @@ module Spree # before the shipping method is set. This results in the customer not being # charged for their order's shipping. To fix this, we refresh the payment # amount here. - def charge_shipping_and_payment_fees! + def set_payment_amount! update_totals return unless pending_payments.any? diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb index 6f746d33e7..4d34f091ca 100644 --- a/app/models/spree/order/checkout.rb +++ b/app/models/spree/order/checkout.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Order < ActiveRecord::Base + class Order < ApplicationRecord module Checkout def self.included(klass) klass.class_eval do @@ -77,12 +77,12 @@ module Spree before_transition to: :delivery, do: :create_proposed_shipments before_transition to: :delivery, do: :ensure_available_shipping_rates + before_transition to: :payment, do: :create_tax_charge! after_transition to: :complete, do: :finalize! - after_transition to: :delivery, do: :create_tax_charge! after_transition to: :resumed, do: :after_resume after_transition to: :canceled, do: :after_cancel - after_transition to: :payment, do: :charge_shipping_and_payment_fees! + after_transition to: :payment, do: :set_payment_amount! end end @@ -130,22 +130,6 @@ module Spree steps << "complete" unless steps.include?("complete") steps end - - def checkout_step?(step) - step.present? ? checkout_steps.include?(step) : false - end - - def checkout_step_index(step) - checkout_steps.index(step) - end - - def can_go_to_state?(state) - return false unless self.state.present? && - checkout_step?(state) && - checkout_step?(self.state) - - checkout_step_index(state) > checkout_step_index(self.state) - end end end end diff --git a/app/models/spree/order_inventory.rb b/app/models/spree/order_inventory.rb index 8416bb4755..44ff226609 100644 --- a/app/models/spree/order_inventory.rb +++ b/app/models/spree/order_inventory.rb @@ -98,8 +98,7 @@ module Spree inventory_unit.destroy removed_quantity += 1 end - - shipment.destroy if shipment.inventory_units.count == 0 + shipment.destroy if shipment.inventory_units.reload.count == 0 # removing this from shipment, and adding to stock_location if order.completed? diff --git a/app/models/spree/payment.rb b/app/models/spree/payment.rb index e3a9aab7bb..d16e428922 100644 --- a/app/models/spree/payment.rb +++ b/app/models/spree/payment.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Payment < ActiveRecord::Base + class Payment < ApplicationRecord include Spree::Payment::Processing extend Spree::LocalizedNumber @@ -20,7 +20,7 @@ module Spree class_name: "Spree::Payment", foreign_key: :source_id has_many :log_entries, as: :source, dependent: :destroy - has_one :adjustment, as: :source, dependent: :destroy + has_one :adjustment, as: :adjustable, dependent: :destroy validate :validate_source before_create :set_unique_identifier @@ -135,8 +135,8 @@ module Spree adjustment.label = adjustment_label adjustment.save else - payment_method.create_adjustment(adjustment_label, order, self, true) - association(:adjustment).reload + payment_method.create_adjustment(adjustment_label, self, true) + adjustment.reload end end @@ -201,7 +201,7 @@ module Spree end def update_order - order.reload.update! + order.update! end # Necessary because some payment gateways will refuse payments with diff --git a/app/models/spree/payment/processing.rb b/app/models/spree/payment/processing.rb index 9e9c0d959f..a40a0798da 100644 --- a/app/models/spree/payment/processing.rb +++ b/app/models/spree/payment/processing.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Payment < ActiveRecord::Base + class Payment < ApplicationRecord module Processing def process! return unless validate! diff --git a/app/models/spree/payment_method.rb b/app/models/spree/payment_method.rb index 4204632b91..c055842951 100644 --- a/app/models/spree/payment_method.rb +++ b/app/models/spree/payment_method.rb @@ -4,7 +4,7 @@ require 'concerns/payment_method_distributors' require 'spree/core/calculated_adjustments' module Spree - class PaymentMethod < ActiveRecord::Base + class PaymentMethod < ApplicationRecord include Spree::Core::CalculatedAdjustments include PaymentMethodDistributors diff --git a/app/models/spree/paypal_express_checkout.rb b/app/models/spree/paypal_express_checkout.rb index 93e0b0e6d0..d796558959 100644 --- a/app/models/spree/paypal_express_checkout.rb +++ b/app/models/spree/paypal_express_checkout.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true module Spree - class PaypalExpressCheckout < ActiveRecord::Base + class PaypalExpressCheckout < ApplicationRecord end end diff --git a/app/models/spree/preference.rb b/app/models/spree/preference.rb index b877f460ce..dfef2a146d 100644 --- a/app/models/spree/preference.rb +++ b/app/models/spree/preference.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Preference < ActiveRecord::Base + class Preference < ApplicationRecord serialize :value validates :key, presence: true diff --git a/app/models/spree/price.rb b/app/models/spree/price.rb index 54d4c39788..871b7886e3 100644 --- a/app/models/spree/price.rb +++ b/app/models/spree/price.rb @@ -1,10 +1,10 @@ # frozen_string_literal: false module Spree - class Price < ActiveRecord::Base + class Price < ApplicationRecord acts_as_paranoid without_default_scope: true - belongs_to :variant, class_name: 'Spree::Variant' + belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant' validate :check_price validates :amount, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true @@ -26,11 +26,6 @@ module Spree self[:amount] = parse_price(price) end - # Allow prices to access associated soft-deleted variants. - def variant - Spree::Variant.unscoped { super } - end - private def check_price diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb index 09b239855b..6bd6cbc3dd 100755 --- a/app/models/spree/product.rb +++ b/app/models/spree/product.rb @@ -24,7 +24,7 @@ require 'concerns/product_stock' # Sum of on_hand each variant's inventory level determine "on_hand" level for the product. # module Spree - class Product < ActiveRecord::Base + class Product < ApplicationRecord include PermalinkGenerator include ProductStock @@ -52,11 +52,11 @@ module Spree dependent: :destroy has_many :variants, -> { - where(is_master: false).order("#{::Spree::Variant.quoted_table_name}.position ASC") + where(is_master: false).order("spree_variants.position ASC") }, class_name: 'Spree::Variant' has_many :variants_including_master, - -> { order("#{::Spree::Variant.quoted_table_name}.position ASC") }, + -> { order("spree_variants.position ASC") }, class_name: 'Spree::Variant', dependent: :destroy @@ -86,11 +86,12 @@ module Spree validates :name, presence: true validates :permalink, presence: true validates :price, presence: true, if: proc { Spree::Config[:require_master_price] } - validates :shipping_category_id, presence: true + validates :shipping_category, presence: true validates :supplier, presence: true validates :primary_taxon, presence: true - validates :tax_category_id, presence: true, if: "Spree::Config.products_require_tax_category" + validates :tax_category, presence: true, + if: proc { Spree::Config[:products_require_tax_category] } validates :variant_unit, presence: true validates :unit_value, presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } } @@ -172,7 +173,7 @@ module Spree scope :in_distributors, lambda { |distributors| with_order_cycles_outer. where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors). - uniq + distinct } # Products supplied by a given enterprise or distributed via that enterprise through an OC @@ -288,12 +289,6 @@ module Spree }.inject(:or) end - def empty_option_values? - options.empty? || options.any? do |opt| - opt.option_type.option_values.empty? - end - end - def property(property_name) return nil unless prop = properties.find_by(name: property_name) @@ -366,7 +361,7 @@ module Spree Spree::OptionType.where('name LIKE ?', 'unit_%%') end - def destroy_with_delete_from_order_cycles + def destroy transaction do touch_distributors @@ -374,10 +369,9 @@ module Spree where('exchange_variants.variant_id IN (?)', variants_including_master.with_deleted. select(:id)).destroy_all - destroy_without_delete_from_order_cycles + super end end - alias_method_chain :destroy, :delete_from_order_cycles private diff --git a/app/models/spree/product_option_type.rb b/app/models/spree/product_option_type.rb index b02db6a440..9ef5496480 100644 --- a/app/models/spree/product_option_type.rb +++ b/app/models/spree/product_option_type.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ProductOptionType < ActiveRecord::Base + class ProductOptionType < ApplicationRecord after_destroy :remove_option_values belongs_to :product, class_name: 'Spree::Product' diff --git a/app/models/spree/product_property.rb b/app/models/spree/product_property.rb index a86a12f1a9..2f67dbcd9b 100644 --- a/app/models/spree/product_property.rb +++ b/app/models/spree/product_property.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ProductProperty < ActiveRecord::Base + class ProductProperty < ApplicationRecord belongs_to :product, class_name: "Spree::Product", touch: true belongs_to :property, class_name: 'Spree::Property' diff --git a/app/models/spree/property.rb b/app/models/spree/property.rb index 18f2497786..900519aa6c 100644 --- a/app/models/spree/property.rb +++ b/app/models/spree/property.rb @@ -1,5 +1,5 @@ module Spree - class Property < ActiveRecord::Base + class Property < ApplicationRecord has_many :product_properties, dependent: :destroy has_many :products, through: :product_properties has_many :producer_properties diff --git a/app/models/spree/return_authorization.rb b/app/models/spree/return_authorization.rb index fc5acb3f02..0361aaf081 100644 --- a/app/models/spree/return_authorization.rb +++ b/app/models/spree/return_authorization.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true module Spree - class ReturnAuthorization < ActiveRecord::Base + class ReturnAuthorization < ApplicationRecord + acts_as_paranoid + belongs_to :order, class_name: 'Spree::Order', inverse_of: :return_authorizations has_many :inventory_units, inverse_of: :return_authorization @@ -64,6 +66,11 @@ module Spree order.shipped_shipments.collect{ |s| s.inventory_units.to_a }.flatten end + # Used when Adjustment#update! wants to update the related adjustment + def compute_amount(*_args) + -amount.abs + end + private def must_have_shipped_units @@ -89,10 +96,13 @@ module Spree Spree::StockMovement.create!(stock_item_id: iu.find_stock_item.id, quantity: 1) end - credit = Adjustment.new(amount: amount.abs * -1, label: Spree.t(:rma_credit)) - credit.source = self - credit.adjustable = order - credit.save + Adjustment.create( + amount: -amount.abs, + label: I18n.t('spree.rma_credit'), + order: order, + adjustable: order, + originator: self + ) order.return if inventory_units.all?(&:returned?) order.update! diff --git a/app/models/spree/role.rb b/app/models/spree/role.rb index 1c8f575835..01b6704432 100644 --- a/app/models/spree/role.rb +++ b/app/models/spree/role.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Role < ActiveRecord::Base + class Role < ApplicationRecord has_and_belongs_to_many :users, join_table: 'spree_roles_users', class_name: Spree.user_class.to_s end diff --git a/app/models/spree/shipment.rb b/app/models/spree/shipment.rb index 173c3bebe8..b5f7516f06 100644 --- a/app/models/spree/shipment.rb +++ b/app/models/spree/shipment.rb @@ -3,7 +3,7 @@ require 'ostruct' module Spree - class Shipment < ActiveRecord::Base + class Shipment < ApplicationRecord belongs_to :order, class_name: 'Spree::Order' belongs_to :address, class_name: 'Spree::Address' belongs_to :stock_location, class_name: 'Spree::StockLocation' @@ -15,7 +15,7 @@ module Spree has_many :adjustments, as: :adjustable, dependent: :destroy before_create :generate_shipment_number - after_save :ensure_correct_adjustment, :update_order + after_save :ensure_correct_adjustment, :update_adjustments attr_accessor :special_instructions alias_attribute :amount, :cost @@ -104,6 +104,10 @@ module Spree save! end + def tax_category + selected_shipping_rate.try(:shipping_method).try(:tax_category) + end + def refresh_rates return shipping_rates if shipped? @@ -161,10 +165,13 @@ module Spree end def update_amounts + return unless fee_adjustment&.amount != cost + update_columns( cost: fee_adjustment&.amount || 0.0, updated_at: Time.zone.now ) + recalculate_adjustments end def manifest @@ -269,21 +276,23 @@ module Spree fee_adjustment.reload elsif selected_shipping_rate_id shipping_method.create_adjustment(adjustment_label, - self, self, true, "open") reload # ensure adjustment is present on later saves end - update_amounts if fee_adjustment&.amount != cost - update_adjustment_included_tax if fee_adjustment + update_amounts end def adjustment_label I18n.t('shipping') end + def can_modify? + !shipped? && !order.canceled? + end + private def manifest_unstock(item) @@ -328,16 +337,14 @@ module Spree ShipmentMailer.shipped_email(id).deliver_later end - def update_adjustment_included_tax - if Config.shipment_inc_vat && (order.distributor.nil? || order.distributor.charges_sales_tax) - fee_adjustment.set_included_tax! Config.shipping_tax_rate - else - fee_adjustment.set_included_tax! 0 - end + def update_adjustments + return unless cost_changed? && state != 'shipped' + + recalculate_adjustments end - def update_order - order.reload.update! + def recalculate_adjustments + Spree::ItemAdjustments.new(self).update end end end diff --git a/app/models/spree/shipping_category.rb b/app/models/spree/shipping_category.rb index b28031d026..6bbfb7f603 100644 --- a/app/models/spree/shipping_category.rb +++ b/app/models/spree/shipping_category.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ShippingCategory < ActiveRecord::Base + class ShippingCategory < ApplicationRecord validates :name, presence: true has_many :products has_many :shipping_method_categories, inverse_of: :shipping_method diff --git a/app/models/spree/shipping_method.rb b/app/models/spree/shipping_method.rb index 909ed9c99f..efff8c56bc 100644 --- a/app/models/spree/shipping_method.rb +++ b/app/models/spree/shipping_method.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ShippingMethod < ActiveRecord::Base + class ShippingMethod < ApplicationRecord include Spree::Core::CalculatedAdjustments DISPLAY = [:both, :front_end, :back_end].freeze @@ -10,10 +10,10 @@ module Spree default_scope -> { where(deleted_at: nil) } + has_many :shipping_rates, inverse_of: :shipping_method has_many :shipments, through: :shipping_rates has_many :shipping_method_categories has_many :shipping_categories, through: :shipping_method_categories - has_many :shipping_rates, inverse_of: :shipping_method has_many :distributor_shipping_methods has_many :distributors, through: :distributor_shipping_methods, class_name: 'Enterprise', @@ -23,6 +23,8 @@ module Spree class_name: 'Spree::Zone', foreign_key: 'shipping_method_id' + belongs_to :tax_category, class_name: 'Spree::TaxCategory' + validates :name, presence: true validate :distributor_validation validate :at_least_one_shipping_category diff --git a/app/models/spree/shipping_method_category.rb b/app/models/spree/shipping_method_category.rb index e8fa1498ff..0a32c66125 100644 --- a/app/models/spree/shipping_method_category.rb +++ b/app/models/spree/shipping_method_category.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ShippingMethodCategory < ActiveRecord::Base + class ShippingMethodCategory < ApplicationRecord belongs_to :shipping_method, class_name: 'Spree::ShippingMethod' belongs_to :shipping_category, class_name: 'Spree::ShippingCategory', inverse_of: :shipping_method_categories diff --git a/app/models/spree/shipping_rate.rb b/app/models/spree/shipping_rate.rb index 857847b398..710a8a25b4 100644 --- a/app/models/spree/shipping_rate.rb +++ b/app/models/spree/shipping_rate.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ShippingRate < ActiveRecord::Base + class ShippingRate < ApplicationRecord belongs_to :shipment, class_name: 'Spree::Shipment' belongs_to :shipping_method, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates @@ -24,13 +24,7 @@ module Spree delegate :name, to: :shipping_method def display_price - price = if Spree::Config[:shipment_inc_vat] - (1 + Spree::TaxRate.default) * cost - else - cost - end - - Spree::Money.new(price, { currency: currency }) + Spree::Money.new(cost, { currency: currency }) end alias_method :display_cost, :display_price diff --git a/app/models/spree/state.rb b/app/models/spree/state.rb index 7b3c5ff057..55bd4b5ae6 100644 --- a/app/models/spree/state.rb +++ b/app/models/spree/state.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class State < ActiveRecord::Base + class State < ApplicationRecord belongs_to :country, class_name: 'Spree::Country' validates :country, :name, presence: true diff --git a/app/models/spree/state_change.rb b/app/models/spree/state_change.rb index 9f52777095..0e770096b5 100644 --- a/app/models/spree/state_change.rb +++ b/app/models/spree/state_change.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class StateChange < ActiveRecord::Base + class StateChange < ApplicationRecord belongs_to :user belongs_to :stateful, polymorphic: true before_create :assign_user diff --git a/app/models/spree/stock_item.rb b/app/models/spree/stock_item.rb index 56325c3bb5..96950899b2 100644 --- a/app/models/spree/stock_item.rb +++ b/app/models/spree/stock_item.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true module Spree - class StockItem < ActiveRecord::Base + class StockItem < ApplicationRecord acts_as_paranoid belongs_to :stock_location, class_name: 'Spree::StockLocation', inverse_of: :stock_items - belongs_to :variant, class_name: 'Spree::Variant' + belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant' has_many :stock_movements validates :stock_location, :variant, presence: true @@ -37,10 +37,6 @@ module Spree in_stock? || backorderable? end - def variant - Spree::Variant.unscoped { super } - end - def count_on_hand=(value) self[:count_on_hand] = value end diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb index e0da35e685..7cf9e26d51 100644 --- a/app/models/spree/stock_location.rb +++ b/app/models/spree/stock_location.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class StockLocation < ActiveRecord::Base + class StockLocation < ApplicationRecord has_many :stock_items, dependent: :delete_all, inverse_of: :stock_location has_many :stock_movements, through: :stock_items diff --git a/app/models/spree/stock_movement.rb b/app/models/spree/stock_movement.rb index f435ed1f50..1409c8a606 100644 --- a/app/models/spree/stock_movement.rb +++ b/app/models/spree/stock_movement.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class StockMovement < ActiveRecord::Base + class StockMovement < ApplicationRecord belongs_to :stock_item, class_name: 'Spree::StockItem' belongs_to :originator, polymorphic: true diff --git a/app/models/spree/tax_category.rb b/app/models/spree/tax_category.rb index 864e97e53a..c69a744cee 100644 --- a/app/models/spree/tax_category.rb +++ b/app/models/spree/tax_category.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class TaxCategory < ActiveRecord::Base + class TaxCategory < ApplicationRecord acts_as_paranoid validates :name, presence: true, uniqueness: { scope: :deleted_at } diff --git a/app/models/spree/tax_rate.rb b/app/models/spree/tax_rate.rb index eb543306f7..cce477b29d 100644 --- a/app/models/spree/tax_rate.rb +++ b/app/models/spree/tax_rate.rb @@ -13,14 +13,14 @@ module Spree end module Spree - class TaxRate < ActiveRecord::Base + class TaxRate < ApplicationRecord acts_as_paranoid include Spree::Core::CalculatedAdjustments belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates validates :amount, presence: true, numericality: true - validates :tax_category_id, presence: true + validates :tax_category, presence: true validates_with DefaultTaxZoneValidator scope :by_zone, ->(zone) { where(zone_id: zone) } @@ -36,8 +36,7 @@ module Spree end def self.adjust(order) - order.adjustments.tax.destroy_all - order.line_item_adjustments.where(originator_type: 'Spree::TaxRate').destroy_all + order.all_adjustments.tax.destroy_all match(order).each do |rate| rate.adjust(order) @@ -62,14 +61,14 @@ module Spree label = create_label if included_in_price if default_zone_or_zone_match? order - order.line_items.each { |line_item| create_adjustment(label, line_item, line_item) } + order.line_items.each { |line_item| create_adjustment(label, line_item, false, "open") } + order.shipments.each { |shipment| create_adjustment(label, shipment, false, "open") } else amount = -1 * calculator.compute(order) label = Spree.t(:refund) + label order.adjustments.create( amount: amount, - source: order, originator: self, order: order, state: "closed", @@ -77,16 +76,11 @@ module Spree ) end else - create_adjustment(label, order, order) + create_adjustment(label, order, false, "open") end order.adjustments.reload order.line_items.reload - # TaxRate adjustments (order.adjustments.tax) - # and line item adjustments (tax included on line items) consist of 100% tax - order.adjustments.tax.additional.each do |adjustment| - adjustment.set_absolute_included_tax! adjustment.amount - end end def default_zone_or_zone_match?(order) diff --git a/app/models/spree/taxon.rb b/app/models/spree/taxon.rb index 4e29c068ce..2c9b3177da 100644 --- a/app/models/spree/taxon.rb +++ b/app/models/spree/taxon.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Taxon < ActiveRecord::Base + class Taxon < ApplicationRecord acts_as_nested_set dependent: :destroy belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true diff --git a/app/models/spree/taxonomy.rb b/app/models/spree/taxonomy.rb index f4e4576505..11364fda0c 100644 --- a/app/models/spree/taxonomy.rb +++ b/app/models/spree/taxonomy.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Taxonomy < ActiveRecord::Base + class Taxonomy < ApplicationRecord validates :name, presence: true has_many :taxons diff --git a/app/models/spree/tokenized_permission.rb b/app/models/spree/tokenized_permission.rb index 58c5882c3a..e2d5329dec 100644 --- a/app/models/spree/tokenized_permission.rb +++ b/app/models/spree/tokenized_permission.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class TokenizedPermission < ActiveRecord::Base + class TokenizedPermission < ApplicationRecord belongs_to :permissable, polymorphic: true end end diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index ab1ef6ddfc..372a29bf29 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -1,5 +1,5 @@ module Spree - class User < ActiveRecord::Base + class User < ApplicationRecord devise :database_authenticatable, :token_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :encryptable, :confirmable, encryptor: 'authlogic_sha512', reconfirmable: true @@ -135,6 +135,10 @@ module Spree spree_orders.incomplete.where(created_by_id: id).order('created_at DESC').first end + def flipper_id + "#{self.class.name};#{id}" + end + protected def password_required? diff --git a/app/models/spree/variant.rb b/app/models/spree/variant.rb index 93430b3b2b..8268d78336 100644 --- a/app/models/spree/variant.rb +++ b/app/models/spree/variant.rb @@ -6,14 +6,15 @@ require 'concerns/variant_stock' require 'spree/localized_number' module Spree - class Variant < ActiveRecord::Base + class Variant < ApplicationRecord extend Spree::LocalizedNumber include VariantUnits::VariantAndLineItemNaming include VariantStock acts_as_paranoid - belongs_to :product, touch: true, class_name: 'Spree::Product' + belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product' + delegate_belongs_to :product, :name, :description, :permalink, :available_on, :tax_category_id, :shipping_category_id, :meta_description, :meta_keywords, :tax_category, :shipping_category @@ -33,7 +34,7 @@ module Spree accepts_nested_attributes_for :images has_one :default_price, - -> { where currency: Spree::Config[:currency] }, + -> { with_deleted.where(currency: Spree::Config[:currency]) }, class_name: 'Spree::Price', dependent: :destroy has_many :prices, @@ -58,6 +59,8 @@ module Spree %w(weight volume).include?(variant.product.andand.variant_unit) } + validates :unit_value, numericality: { greater_than: 0 } + validates :unit_description, presence: true, if: ->(variant) { variant.product.andand.variant_unit.present? && variant.unit_value.nil? } @@ -109,12 +112,13 @@ module Spree } scope :not_hidden_for, lambda { |enterprise| - return where("1=0") if enterprise.blank? + enterprise_id = enterprise&.id.to_i + return none if enterprise_id < 1 joins(" LEFT OUTER JOIN (SELECT * FROM inventory_items - WHERE enterprise_id = #{sanitize enterprise.andand.id}) + WHERE enterprise_id = #{enterprise_id}) AS o_inventory_items ON o_inventory_items.variant_id = spree_variants.id") .where("o_inventory_items.id IS NULL OR o_inventory_items.visible = (?)", true) @@ -150,11 +154,6 @@ module Spree select("spree_variants.id")) end - # Allow variant to access associated soft-deleted prices. - def default_price - Spree::Price.unscoped { super } - end - def price_with_fees(distributor, order_cycle) price + fees_for(distributor, order_cycle) end @@ -187,13 +186,6 @@ module Spree price_in(currency).try(:amount) end - # Product may be created with deleted_at already set, - # which would make AR's default finder return nil. - # This is a stopgap for that little problem. - def product - Spree::Product.unscoped { super } - end - # can_supply? is implemented in VariantStock def in_stock?(quantity = 1) can_supply?(quantity) diff --git a/app/models/spree/zone.rb b/app/models/spree/zone.rb index b2dd4bf69a..db5286c9bd 100644 --- a/app/models/spree/zone.rb +++ b/app/models/spree/zone.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class Zone < ActiveRecord::Base + class Zone < ApplicationRecord has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember", inverse_of: :zone has_many :tax_rates, dependent: :destroy, inverse_of: :zone has_and_belongs_to_many :shipping_methods, join_table: 'spree_shipping_methods_zones' diff --git a/app/models/spree/zone_member.rb b/app/models/spree/zone_member.rb index 46c6c4c43b..45a28efebd 100644 --- a/app/models/spree/zone_member.rb +++ b/app/models/spree/zone_member.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class ZoneMember < ActiveRecord::Base + class ZoneMember < ApplicationRecord belongs_to :zone, class_name: 'Spree::Zone', counter_cache: true, inverse_of: :zone_members belongs_to :zoneable, polymorphic: true diff --git a/app/models/stripe_account.rb b/app/models/stripe_account.rb index 1b2840ffe6..2065bc14ec 100644 --- a/app/models/stripe_account.rb +++ b/app/models/stripe_account.rb @@ -1,4 +1,4 @@ -class StripeAccount < ActiveRecord::Base +class StripeAccount < ApplicationRecord belongs_to :enterprise validates :stripe_user_id, :stripe_publishable_key, presence: true validates :enterprise_id, uniqueness: true diff --git a/app/models/subscription.rb b/app/models/subscription.rb index dbb5a8bf23..c8f6901816 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -1,4 +1,4 @@ -class Subscription < ActiveRecord::Base +class Subscription < ApplicationRecord ALLOWED_PAYMENT_METHOD_TYPES = ["Spree::PaymentMethod::Check", "Spree::Gateway::StripeConnect", "Spree::Gateway::StripeSCA"].freeze diff --git a/app/models/subscription_line_item.rb b/app/models/subscription_line_item.rb index 86f3a00577..795d5996ce 100644 --- a/app/models/subscription_line_item.rb +++ b/app/models/subscription_line_item.rb @@ -1,6 +1,6 @@ -class SubscriptionLineItem < ActiveRecord::Base +class SubscriptionLineItem < ApplicationRecord belongs_to :subscription, inverse_of: :subscription_line_items - belongs_to :variant, class_name: 'Spree::Variant' + belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant' validates :subscription, presence: true validates :variant, presence: true @@ -12,11 +12,6 @@ class SubscriptionLineItem < ActiveRecord::Base (price_estimate || 0) * (quantity || 0) end - # Ensure SubscriptionLineItem always has access to soft-deleted Variant attribute - def variant - Spree::Variant.unscoped { super } - end - # Used to calculators to estimate fees alias_method :amount, :total_estimate diff --git a/app/models/tag_rule.rb b/app/models/tag_rule.rb index 404c449e50..6f61d4a31a 100644 --- a/app/models/tag_rule.rb +++ b/app/models/tag_rule.rb @@ -1,4 +1,4 @@ -class TagRule < ActiveRecord::Base +class TagRule < ApplicationRecord belongs_to :enterprise preference :customer_tags, :string, default: "" diff --git a/app/models/tag_rule/discount_order.rb b/app/models/tag_rule/discount_order.rb deleted file mode 100644 index 5f9ca44b2f..0000000000 --- a/app/models/tag_rule/discount_order.rb +++ /dev/null @@ -1,24 +0,0 @@ -class TagRule::DiscountOrder < TagRule - include Spree::Core::CalculatedAdjustments - - private - - # Warning: this should only EVER be called via TagRule#apply - def apply! - create_adjustment(I18n.t("discount"), subject, subject) - end - - def subject_class_matches? - subject.class == Spree::Order - end - - def additional_requirements_met? - return false if already_applied? - - true - end - - def already_applied? - subject.adjustments.where(originator_id: id, originator_type: "TagRule").any? - end -end diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index ad4369ea51..9fd26b1ed4 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -1,4 +1,8 @@ -class VariantOverride < ActiveRecord::Base +# frozen_string_literal: true + +require 'spree/localized_number' + +class VariantOverride < ApplicationRecord extend Spree::LocalizedNumber include StockSettingsOverrideValidation @@ -7,8 +11,8 @@ class VariantOverride < ActiveRecord::Base belongs_to :hub, class_name: 'Enterprise' belongs_to :variant, class_name: 'Spree::Variant' - validates :hub_id, presence: true - validates :variant_id, presence: true + validates :hub, presence: true + validates :variant, presence: true # Default stock can be nil, indicating stock should not be reset or zero, meaning reset to zero. Need to ensure this can be set by the user. validates :default_stock, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true diff --git a/app/queries/outstanding_balance.rb b/app/queries/outstanding_balance.rb index 48ee451009..5f4b5b921f 100644 --- a/app/queries/outstanding_balance.rb +++ b/app/queries/outstanding_balance.rb @@ -30,8 +30,8 @@ class OutstandingBalance # a little longer. See https://github.com/rails/arel/pull/400 for details. def statement <<-SQL.strip_heredoc - CASE WHEN state IN #{non_fulfilled_states_group.to_sql} THEN payment_total - WHEN state IS NOT NULL THEN payment_total - total + CASE WHEN "spree_orders"."state" IN #{non_fulfilled_states_group.to_sql} THEN "spree_orders"."payment_total" + WHEN "spree_orders"."state" IS NOT NULL THEN "spree_orders"."payment_total" - "spree_orders"."total" ELSE 0 END SQL end diff --git a/app/serializers/api/adjustment_serializer.rb b/app/serializers/api/adjustment_serializer.rb index 254b173777..44fa26f227 100644 --- a/app/serializers/api/adjustment_serializer.rb +++ b/app/serializers/api/adjustment_serializer.rb @@ -1,7 +1,6 @@ module Api class AdjustmentSerializer < ActiveModel::Serializer attributes :id, :amount, :label, :eligible, - :source_type, :source_id, :adjustable_type, :adjustable_id, :originator_type, :originator_id end diff --git a/app/serializers/api/admin/customer_with_calculated_balance_serializer.rb b/app/serializers/api/admin/customer_with_calculated_balance_serializer.rb deleted file mode 100644 index 6db568ed35..0000000000 --- a/app/serializers/api/admin/customer_with_calculated_balance_serializer.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Api - module Admin - class CustomerWithCalculatedBalanceSerializer < CustomerSerializer - attributes :balance, :balance_status - - def balance - Spree::Money.new(balance_value, currency: Spree::Config[:currency]).to_s - end - - def balance_status - if balance_value.positive? - "credit_owed" - elsif balance_value.negative? - "balance_due" - else - "" - end - end - - def balance_value - @balance_value ||= - OpenFoodNetwork::UserBalanceCalculator.new(object.email, object.enterprise).balance - end - end - end -end diff --git a/app/serializers/api/admin/subscription_serializer.rb b/app/serializers/api/admin/subscription_serializer.rb index 7088fd6908..4a2cb33db9 100644 --- a/app/serializers/api/admin/subscription_serializer.rb +++ b/app/serializers/api/admin/subscription_serializer.rb @@ -5,7 +5,7 @@ module Api class SubscriptionSerializer < ActiveModel::Serializer attributes :id, :shop_id, :customer_id, :schedule_id, :payment_method_id, :shipping_method_id, :begins_at, :ends_at, - :customer_email, :schedule_name, :edit_path, :canceled_at, :paused_at, :state, + :customer_email, :customer_name, :schedule_name, :edit_path, :canceled_at, :paused_at, :state, :shipping_fee_estimate, :payment_fee_estimate has_many :subscription_line_items, serializer: Api::Admin::SubscriptionLineItemSerializer @@ -34,6 +34,10 @@ module Api object.customer.andand.email end + def customer_name + object.customer.andand.name + end + def schedule_name object.schedule.andand.name end diff --git a/app/serializers/api/admin/tag_rule_serializer.rb b/app/serializers/api/admin/tag_rule_serializer.rb index 0f96f2a5ee..0a64f74c8b 100644 --- a/app/serializers/api/admin/tag_rule_serializer.rb +++ b/app/serializers/api/admin/tag_rule_serializer.rb @@ -19,10 +19,6 @@ module Api attributes :id, :enterprise_id, :type, :is_default, :preferred_customer_tags end - class DiscountOrderSerializer < BaseSerializer - has_one :calculator, serializer: Api::Admin::Calculator::FlatPercentItemTotalSerializer - end - class FilterShippingMethodsSerializer < BaseSerializer attributes :preferred_matched_shipping_methods_visibility, :preferred_shipping_method_tags, :shipping_method_tags diff --git a/app/serializers/api/order_detailed_serializer.rb b/app/serializers/api/order_detailed_serializer.rb index 5fa36dcddc..fd625b6936 100644 --- a/app/serializers/api/order_detailed_serializer.rb +++ b/app/serializers/api/order_detailed_serializer.rb @@ -12,7 +12,7 @@ module Api def adjustments adjustments = object.all_adjustments.where( - adjustable_type: ["Spree::Order", "Spree::Shipment"] + adjustable_type: ["Spree::Order", "Spree::Shipment", "Spree::Payment"] ).order(label: :desc) ActiveModel::ArraySerializer.new(adjustments, each_serializer: Api::AdjustmentSerializer) end diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index f5e9b001d8..f741675318 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -7,12 +7,10 @@ module Api has_many :payments, serializer: Api::PaymentSerializer + # This method relies on `balance_value` as a computed DB column. See `CompleteOrdersWithBalance` + # for reference. def outstanding_balance - if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, object.user) - -object.balance_value - else - object.outstanding_balance - end + -object.balance_value end def payments diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index 5c99fc1730..06d841c392 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -41,10 +41,16 @@ class Api::VariantSerializer < ActiveModel::Serializer end def unit_price_price - (rand * 10).round(2) + price_with_fees / (unit_price.denominator || 1) end def unit_price_unit - rand > 0.5 ? "item" : "kg" + unit_price.unit + end + + private + + def unit_price + @unit_price ||= UnitPrice.new(object) end end diff --git a/app/services/action_callbacks.rb b/app/services/action_callbacks.rb deleted file mode 100644 index 2cfecc961b..0000000000 --- a/app/services/action_callbacks.rb +++ /dev/null @@ -1,23 +0,0 @@ -class ActionCallbacks - attr_reader :before_methods - attr_reader :after_methods - attr_reader :fails_methods - - def initialize - @before_methods = [] - @after_methods = [] - @fails_methods = [] - end - - def before(method) - @before_methods << method - end - - def after(method) - @after_methods << method - end - - def fails(method) - @fails_methods << method - end -end diff --git a/app/services/cart_service.rb b/app/services/cart_service.rb index 35dcb720f0..c4f3b5a5c0 100644 --- a/app/services/cart_service.rb +++ b/app/services/cart_service.rb @@ -106,13 +106,15 @@ class CartService end def read_variants_hash(data) - (data[:variants] || []).map do |variant_id, quantity| - if quantity.is_a?(Hash) - { variant_id: variant_id, quantity: quantity[:quantity], max_quantity: quantity[:max_quantity] } + variants_array = [] + (data[:variants] || []).each do |variant_id, quantity| + if quantity.is_a?(ActionController::Parameters) + variants_array.push({ variant_id: variant_id, quantity: quantity[:quantity], max_quantity: quantity[:max_quantity] }) else - { variant_id: variant_id, quantity: quantity } + variants_array.push({ variant_id: variant_id, quantity: quantity }) end end + variants_array end def cart_remove(variant_id) diff --git a/app/services/invoice_renderer.rb b/app/services/invoice_renderer.rb index bbb1886a5b..956550d51b 100644 --- a/app/services/invoice_renderer.rb +++ b/app/services/invoice_renderer.rb @@ -5,7 +5,7 @@ class InvoiceRenderer def render_to_string(order) renderer.instance_variable_set(:@order, order) - renderer.render_to_string(args(order)) + renderer.render_to_string_with_wicked_pdf(args(order)) end def args(order) diff --git a/app/services/order_adjustments_fetcher.rb b/app/services/order_adjustments_fetcher.rb index 9292fe8e91..09618b60f4 100644 --- a/app/services/order_adjustments_fetcher.rb +++ b/app/services/order_adjustments_fetcher.rb @@ -29,20 +29,12 @@ class OrderAdjustmentsFetcher sum_adjustments "shipping" end - def line_item_adjustments(line_item) - if adjustments_eager_loaded? - adjustments.select{ |adjustment| adjustment.source_id == line_item.id } - else - adjustments.where(source_id: line_item.id) - end - end - private attr_reader :order def adjustments - order.adjustments + order.all_adjustments end def adjustments_eager_loaded? @@ -71,11 +63,11 @@ class OrderAdjustmentsFetcher adjustments.select do |adjustment| match_by_scope(adjustment, eligible_scope) && adjustment.originator_type == 'EnterpriseFee' && - adjustment.source_type != 'Spree::LineItem' + adjustment.adjustable_type != 'Spree::LineItem' end else adjustments.eligible. - where("originator_type = ? AND source_type != ?", 'EnterpriseFee', 'Spree::LineItem') + where("originator_type = ? AND adjustable_type != ?", 'EnterpriseFee', 'Spree::LineItem') end end diff --git a/app/services/order_checkout_restart.rb b/app/services/order_checkout_restart.rb index 5ca7d2bf78..58d7c29d76 100644 --- a/app/services/order_checkout_restart.rb +++ b/app/services/order_checkout_restart.rb @@ -13,7 +13,7 @@ class OrderCheckoutRestart clear_shipments clear_payments - order.reload + order.reload.update! end private diff --git a/app/services/order_fees_handler.rb b/app/services/order_fees_handler.rb index 55c2416136..76e3695c90 100644 --- a/app/services/order_fees_handler.rb +++ b/app/services/order_fees_handler.rb @@ -19,6 +19,9 @@ class OrderFeesHandler create_line_item_fees! create_order_fees! + + order.updater.update_totals + order.updater.persist_totals end order.update! @@ -45,7 +48,7 @@ class OrderFeesHandler end def update_order_fees! - order.adjustments.enterprise_fee.where(source_type: 'Spree::Order').each do |fee| + order.adjustments.enterprise_fee.where(adjustable_type: 'Spree::Order').each do |fee| fee.update!(order, force: true) end end diff --git a/app/services/order_tax_adjustments_fetcher.rb b/app/services/order_tax_adjustments_fetcher.rb index 686efff9a4..7c01a2b175 100644 --- a/app/services/order_tax_adjustments_fetcher.rb +++ b/app/services/order_tax_adjustments_fetcher.rb @@ -20,28 +20,11 @@ class OrderTaxAdjustmentsFetcher attr_reader :order def all - Spree::Adjustment - .where(order_adjustments.or(line_item_adjustments).or(shipment_adjustments)) - .order('created_at ASC') - end + tax_adjustments = order.all_adjustments.tax + enterprise_fees_with_tax = order.all_adjustments.enterprise_fee.with_tax + admin_adjustments_with_tax = order.all_adjustments.admin.with_tax - def order_adjustments - table[:adjustable_id].eq(order.id) - .and(table[:adjustable_type].eq('Spree::Order')) - end - - def line_item_adjustments - table[:adjustable_id].eq_any(order.line_item_ids) - .and(table[:adjustable_type].eq('Spree::LineItem')) - end - - def shipment_adjustments - table[:order_id].eq(order.id) - .and(table[:adjustable_type].eq('Spree::Shipment')) - end - - def table - @table ||= Spree::Adjustment.arel_table + tax_adjustments.or(enterprise_fees_with_tax).or(admin_adjustments_with_tax) end def tax_rates_hash(adjustment) @@ -66,10 +49,9 @@ class OrderTaxAdjustmentsFetcher end def no_tax_adjustments?(adjustment) - # Enterprise Fees, Admin Adjustments, and Shipping Fees currently do not have tax adjustments. + # Enterprise Fees and Admin Adjustments currently do not have tax adjustments. # The tax amount is stored in the included_tax attribute. adjustment.originator_type == "EnterpriseFee" || - adjustment.originator_type == "Spree::ShippingMethod" || - (adjustment.source_type.nil? && adjustment.originator_type.nil?) + adjustment.originator_type.nil? end end diff --git a/app/services/permitted_attributes/enterprise.rb b/app/services/permitted_attributes/enterprise.rb index 1f20a62b13..0989511d69 100644 --- a/app/services/permitted_attributes/enterprise.rb +++ b/app/services/permitted_attributes/enterprise.rb @@ -7,7 +7,7 @@ module PermittedAttributes end def call - return @params[:enterprise] if @params[:enterprise].blank? + return {} if @params[:enterprise].blank? @params.require(:enterprise).permit(self.class.attributes) end diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb index 046726a96f..f46a4c63d2 100644 --- a/app/services/permitted_attributes/order_cycle.rb +++ b/app/services/permitted_attributes/order_cycle.rb @@ -7,7 +7,7 @@ module PermittedAttributes end def call - return @params[:order_cycle] if @params[:order_cycle].blank? + return {} if @params[:order_cycle].blank? @params.require(:order_cycle).permit(attributes) end diff --git a/app/services/permitted_attributes/subscription.rb b/app/services/permitted_attributes/subscription.rb index 21e523e4fe..e80469767f 100644 --- a/app/services/permitted_attributes/subscription.rb +++ b/app/services/permitted_attributes/subscription.rb @@ -7,7 +7,7 @@ module PermittedAttributes end def call - return @params[:subscription] if @params[:subscription].blank? + return {} if @params[:subscription].blank? @params.require(:subscription).permit(basic_permitted_attributes + other_permitted_attributes) end diff --git a/app/services/tax_rate_finder.rb b/app/services/tax_rate_finder.rb index 01b955d3d0..1c979cf776 100644 --- a/app/services/tax_rate_finder.rb +++ b/app/services/tax_rate_finder.rb @@ -6,36 +6,36 @@ class TaxRateFinder def self.tax_rates_of(adjustment) new.tax_rates( adjustment.originator, - adjustment.source, + adjustment.adjustable, adjustment.amount, adjustment.included_tax ) end # @return [Array] - def tax_rates(originator, source, amount, included_tax) - find_associated_tax_rate(originator, source) || + def tax_rates(originator, adjustable, amount, included_tax) + find_associated_tax_rate(originator, adjustable) || find_closest_tax_rates_from_included_tax(amount, included_tax) end private - def find_associated_tax_rate(originator, source) + def find_associated_tax_rate(originator, adjustable) case originator when Spree::TaxRate [originator] when EnterpriseFee - enterprise_fee_tax_rates(originator, source) + enterprise_fee_tax_rates(originator, adjustable) end end - def enterprise_fee_tax_rates(enterprise_fee, source) - case source + def enterprise_fee_tax_rates(enterprise_fee, adjustable) + case adjustable when Spree::LineItem - tax_category = line_item_tax_category(enterprise_fee, source) - tax_category ? tax_category.tax_rates.match(source.order) : [] + tax_category = line_item_tax_category(enterprise_fee, adjustable) + tax_category ? tax_category.tax_rates.match(adjustable.order) : [] when Spree::Order - enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(source) : [] + enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(adjustable) : [] end end diff --git a/app/services/unit_price.rb b/app/services/unit_price.rb new file mode 100644 index 0000000000..0b28c973d5 --- /dev/null +++ b/app/services/unit_price.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class UnitPrice + def initialize(variant) + @variant = variant + @product = variant.product + end + + def denominator + # catches any case where unit is not kg, lb, or L. + return @variant.unit_value if @product&.variant_unit == "items" + + case unit + when "lb" + @variant.unit_value / 453.6 + when "kg" + @variant.unit_value / 1000 + else # Liters + @variant.unit_value + end + end + + def unit + return "lb" if WeightsAndMeasures.new(@variant).system == "imperial" + + case @product&.variant_unit + when "weight" + "kg" + when "volume" + "L" + else + @product.variant_unit_name.presence || I18n.t("item") + end + end +end diff --git a/app/services/variant_units/option_value_namer.rb b/app/services/variant_units/option_value_namer.rb index 7cb8fc8547..9d95f58f2e 100644 --- a/app/services/variant_units/option_value_namer.rb +++ b/app/services/variant_units/option_value_namer.rb @@ -62,40 +62,7 @@ module VariantUnits end def scale_for_unit_value - units = { - 'weight' => { - 1.0 => { 'name' => 'g', 'system' => 'metric' }, - 28.35 => { 'name' => 'oz', 'system' => 'imperial' }, - 453.6 => { 'name' => 'lb', 'system' => 'imperial' }, - 1000.0 => { 'name' => 'kg', 'system' => 'metric' }, - 1_000_000.0 => { 'name' => 'T', 'system' => 'metric' } - }, - 'volume' => { - 0.001 => { 'name' => 'mL', 'system' => 'metric' }, - 1.0 => { 'name' => 'L', 'system' => 'metric' }, - 1000.0 => { 'name' => 'kL', 'system' => 'metric' } - } - } - - scales = units[@variant.product.variant_unit] - product_scale = @variant.product.variant_unit_scale - product_scale_system = scales[product_scale.to_f]['system'] - - largest_unit = find_largest_unit(scales, product_scale_system) - [largest_unit[0], largest_unit[1]["name"]] - end - - # Find the largest available and compatible unit where unit_value comes - # to >= 1 when expressed in it. - # If there is none available where this is true, use the smallest available unit. - def find_largest_unit(scales, product_scale_system) - largest_unit = scales.select { |scale, unit_info| - unit_info['system'] == product_scale_system && - @variant.unit_value / scale >= 1 - }.max - return scales.first if largest_unit.nil? - - largest_unit + WeightsAndMeasures.new(@variant).scale_for_unit_value end def pluralize(unit_name, count) diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb new file mode 100644 index 0000000000..c2bc8c313c --- /dev/null +++ b/app/services/weights_and_measures.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +class WeightsAndMeasures + def initialize(variant) + @variant = variant + @units = UNITS + end + + def scale_for_unit_value + largest_unit = find_largest_unit(scales_for_variant_unit, system) + return [nil, nil] unless largest_unit + + [largest_unit[0], largest_unit[1]["name"]] + end + + def system + return "custom" unless scales = scales_for_variant_unit + return "custom" unless product_scale = @variant.product.variant_unit_scale + + scales[product_scale.to_f]['system'] + end + + private + + UNITS = { + 'weight' => { + 1.0 => { 'name' => 'g', 'system' => 'metric' }, + 28.35 => { 'name' => 'oz', 'system' => 'imperial' }, + 453.6 => { 'name' => 'lb', 'system' => 'imperial' }, + 1000.0 => { 'name' => 'kg', 'system' => 'metric' }, + 1_000_000.0 => { 'name' => 'T', 'system' => 'metric' } + }, + 'volume' => { + 0.001 => { 'name' => 'mL', 'system' => 'metric' }, + 1.0 => { 'name' => 'L', 'system' => 'metric' }, + 1000.0 => { 'name' => 'kL', 'system' => 'metric' } + } + }.freeze + + def scales_for_variant_unit + @units[@variant.product.variant_unit] + end + + # Find the largest available and compatible unit where unit_value comes + # to >= 1 when expressed in it. + # If there is none available where this is true, use the smallest available unit. + def find_largest_unit(scales, product_scale_system) + return nil unless scales + + largest_unit = scales.select { |scale, unit_info| + unit_info['system'] == product_scale_system && + @variant.unit_value / scale >= 1 + }.max + return scales.first if largest_unit.nil? + + largest_unit + end +end diff --git a/app/views/admin/subscriptions/_table.html.haml b/app/views/admin/subscriptions/_table.html.haml index 902515f385..c4eb12b891 100644 --- a/app/views/admin/subscriptions/_table.html.haml +++ b/app/views/admin/subscriptions/_table.html.haml @@ -38,7 +38,10 @@   %tbody.panel-ctrl{ object: 'subscription', ng: { repeat: "subscription in subscriptions | filter:query as filteredSubscriptions track by subscription.id" } } %tr.subscription{ :id => "so_{{subscription.id}}", ng: { class: { even: "'even'", odd: "'odd'" } } } - %td.customer.text-center{ ng: { show: 'columns.customer.visible', bind: '::subscription.customer_email' } } + %td.customer.text-center{ ng: { show: 'columns.customer.visible'}} + %span{ "ng-bind": '::subscription.customer_email' } + %br + %span{ "ng-bind": '::subscription.customer_name' } %td.schedule.text-center{ ng: { show: 'columns.schedule.visible', bind: '::subscription.schedule_name' } } %td.items.panel-toggle.text-center{ name: 'products', ng: { show: 'columns.items.visible' } } %h5{ ng: { bind: 'itemCount(subscription)' } } diff --git a/app/views/admin/variant_overrides/_hidden_products.html.haml b/app/views/admin/variant_overrides/_hidden_products.html.haml index b8cdc1af01..38f144b479 100644 --- a/app/views/admin/variant_overrides/_hidden_products.html.haml +++ b/app/views/admin/variant_overrides/_hidden_products.html.haml @@ -8,7 +8,7 @@ %tr %th.producer=t('admin.producer') %th.product=t('admin.product') - %th.variant=t('(admin.variant') + %th.variant=t('admin.variant') %th.add=t('admin.variant_overrides.index.add') %tbody{ ng: { repeat: 'product in filteredProducts | limitTo:productLimit' } } %tr{ id: "v_{{variant.id}}", ng: { repeat: 'variant in product.variants | inventoryVariants:hub_id:views' } } diff --git a/app/views/layouts/_bugherd_script.html.haml b/app/views/layouts/_bugherd_script.html.haml deleted file mode 100644 index 8a04160cfd..0000000000 --- a/app/views/layouts/_bugherd_script.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- if (Rails.env.staging? || Rails.env.production?) && Spree::Config.bugherd_api_key.present? - :javascript - (function (d, t) { - var bh = d.createElement(t), s = d.getElementsByTagName(t)[0]; - bh.type = 'text/javascript'; - bh.src = '//www.bugherd.com/sidebarv2.js?apikey=#{Spree::Config.bugherd_api_key}'; - s.parentNode.insertBefore(bh, s); - })(document, 'script'); diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index e1ae43cf7a..2ade6f4e86 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -61,5 +61,4 @@ = inject_currency_config = yield :injection_data - = render "layouts/bugherd_script" = render "layouts/matomo_tag" diff --git a/app/views/layouts/registration.html.haml b/app/views/layouts/registration.html.haml index 56900bbec2..815bff62c2 100644 --- a/app/views/layouts/registration.html.haml +++ b/app/views/layouts/registration.html.haml @@ -35,4 +35,3 @@ = yield :injection_data = render "layouts/i18n_script" - = render "layouts/bugherd_script" diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 6a6c085782..b95936d45b 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -30,9 +30,10 @@ "question-mark-with-tooltip-append-to-body" => "true", "question-mark-with-tooltip-placement" => "top", "question-mark-with-tooltip-animation" => true, + key: "'js.shopfront.unit_price_tooltip'", context: "'cart-sidebar'"} .options-text - {{ line_item.variant.unit_price_price | localizeCurrency }} / {{ line_item.variant.unit_price_unit }} + {{ line_item.variant.unit_price_price | localizeCurrency }} / {{ line_item.variant.unit_price_unit }} .cart-empty{"ng-show" => "Cart.line_items.length == 0"} %p diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index dcd261e0b2..3fbdb1c43f 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -14,7 +14,7 @@ = render "shop/products/summary" .shop-variants - if feature? :unit_price, spree_current_user - %shop-variant-with-unit-price{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} + %shop-variant-with-unit-price{showunitprice: 'true', variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} - else %shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} %product{"ng-show" => "Products.loading"} diff --git a/app/views/shopping_shared/_header.html.haml b/app/views/shopping_shared/_header.html.haml index e718e9247c..caf3ccc6ad 100644 --- a/app/views/shopping_shared/_header.html.haml +++ b/app/views/shopping_shared/_header.html.haml @@ -6,8 +6,7 @@ #distributor_title - if distributor.logo? %img.left{src: distributor.logo.url(:thumb)} - %h3 - = distributor.name + = render DistributorTitleComponent.new(name: distributor.name) %location= distributor.address.city = yield :ordercycle_sidebar diff --git a/app/views/spree/admin/adjustments/_adjustments_table.html.haml b/app/views/spree/admin/adjustments/_adjustments_table.html.haml index 7b916f5aee..cbc7df005b 100644 --- a/app/views/spree/admin/adjustments/_adjustments_table.html.haml +++ b/app/views/spree/admin/adjustments/_adjustments_table.html.haml @@ -17,6 +17,7 @@ %td.align-center.label= adjustment.label %td.align-center.amount= adjustment.display_amount.to_html %td.align-center.included-tax= adjustment.display_included_tax.to_html - %td.actions - = link_to_edit adjustment, no_text: true - = link_to_delete adjustment, no_text: true + - unless @order.canceled? + %td.actions + = link_to_edit adjustment, no_text: true + = link_to_delete adjustment, no_text: true diff --git a/app/views/spree/admin/adjustments/_edit_form.html.haml b/app/views/spree/admin/adjustments/_edit_form.html.haml index 918a9b5b6f..58d2db990d 100644 --- a/app/views/spree/admin/adjustments/_edit_form.html.haml +++ b/app/views/spree/admin/adjustments/_edit_form.html.haml @@ -5,18 +5,19 @@ = text_field :adjustment, :amount, :class => 'fullwidth' = f.error_message_on :amount - .four.columns - = f.field_container :included_tax do - = f.label :included_tax, t(:included_tax) - = f.text_field :included_tax, disabled: true, class: 'fullwidth', - value: number_with_precision(f.object.included_tax, precision: 2) - = f.error_message_on :included_tax + - if @adjustment.admin? + .four.columns + = f.field_container :included_tax do + = f.label :included_tax, t(:included_tax) + = f.text_field :included_tax, disabled: true, class: 'fullwidth', + value: number_with_precision(f.object.included_tax, precision: 2) + = f.error_message_on :included_tax - .omega.four.columns - = f.field_container :tax_rate_id do - = f.label :tax_rate_id, t(:tax_rate) - = select_tag :tax_rate_id, options_from_collection_for_select(Spree::TaxRate.all, :id, :name, @tax_rate_id), prompt: t(:remove_tax), class: 'select2 fullwidth' - = f.error_message_on :tax_rate_id + .omega.four.columns + = f.field_container :tax_rate_id do + = f.label :tax_rate_id, t(:tax_rate) + = select_tag :tax_rate_id, options_from_collection_for_select(Spree::TaxRate.all, :id, :name, @tax_rate_id), prompt: t(:remove_tax), class: 'select2 fullwidth' + = f.error_message_on :tax_rate_id .row .alpha.omega.twelve.columns diff --git a/app/views/spree/admin/adjustments/index.html.haml b/app/views/spree/admin/adjustments/index.html.haml index 4aa8de7967..31d0e9bff9 100644 --- a/app/views/spree/admin/adjustments/index.html.haml +++ b/app/views/spree/admin/adjustments/index.html.haml @@ -6,7 +6,8 @@ = t(:adjustments) - content_for :page_actions do - %li= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus' + - unless @order.canceled? + %li= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus' = render partial: 'spree/admin/shared/order_links' %li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' diff --git a/app/views/spree/admin/orders/_add_product.html.haml b/app/views/spree/admin/orders/_add_product.html.haml index 3f12c6c1a4..93594bd12f 100644 --- a/app/views/spree/admin/orders/_add_product.html.haml +++ b/app/views/spree/admin/orders/_add_product.html.haml @@ -4,8 +4,11 @@ %fieldset.no-border-bottom %legend{:align => "center"}= Spree.t(:add_product) - .field.twelve.columns.alpha{"data-hook" => "add_product_name"} - = label_tag :add_variant_id, Spree.t(:name_or_sku) - = hidden_field_tag :add_variant_id, "", :class => "variant_autocomplete fullwidth" - + - if @order.canceled? + = t(".cannot_add_item_to_canceled_order") + - else + .field.twelve.columns.alpha{"data-hook" => "add_product_name"} + = label_tag :add_variant_id, Spree.t(:name_or_sku) + = hidden_field_tag :add_variant_id, "", :class => "variant_autocomplete fullwidth" + #stock_details diff --git a/app/views/spree/admin/orders/_filters.html.haml b/app/views/spree/admin/orders/_filters.html.haml index 9d5860bd9e..dead6051d9 100644 --- a/app/views/spree/admin/orders/_filters.html.haml +++ b/app/views/spree/admin/orders/_filters.html.haml @@ -1,5 +1,5 @@ %div{"data-hook" => "admin_orders_index_search"} - = form_tag :admin_orders, {name: "orders_form", "ng-submit" => "fetchResults()"} do + = form_tag spree.admin_orders_url, {name: "orders_form", "ng-submit" => "fetchResults()"} do .field-block.alpha.four.columns .date-range-filter.field = label_tag nil, t(:date_range) @@ -35,7 +35,7 @@ .field = label_tag nil, t(:shipping_method) = select_tag("shipping_method_id", - options_for_select(Spree::ShippingMethod.managed_by(spree_current_user).collect {|s| [t("spree.shipping_method.#{s.name}"), s.id]}), + options_for_select(Spree::ShippingMethod.managed_by(spree_current_user).collect {|s| [t("spree.shipping_method_names.#{s.name}"), s.id]}), {include_blank: true, class: 'select2', 'ng-model' => 'shipping_method_id'}) .field-block.alpha.eight.columns = label_tag nil, t(:distributors) diff --git a/app/views/spree/admin/orders/_form.html.haml b/app/views/spree/admin/orders/_form.html.haml index 6f02721895..a0fac1bef3 100644 --- a/app/views/spree/admin/orders/_form.html.haml +++ b/app/views/spree/admin/orders/_form.html.haml @@ -12,14 +12,14 @@ %legend{ align: 'center' }= t(".order_total") %span.order-total= order.display_total - = form_for @order, url: admin_order_url(@order), method: :put do |f| + = form_for @order, url: spree.admin_order_url(@order), method: :put do |f| = render partial: 'spree/admin/orders/_form/distribution_fields' .filter-actions.actions{"ng-show" => "distributionChosen()"} = button t(:update_and_recalculate_fees), 'icon-refresh' %span.or = t(:or) - = link_to_with_icon 'button icon-arrow-left', t(:back), admin_orders_url + = link_to_with_icon 'button icon-arrow-left', t(:back), spree.admin_orders_url = javascript_tag do var order_number = '#{@order.number}'; diff --git a/app/views/spree/admin/orders/_shipment.html.haml b/app/views/spree/admin/orders/_shipment.html.haml index 3248e57655..72ef176c85 100644 --- a/app/views/spree/admin/orders/_shipment.html.haml +++ b/app/views/spree/admin/orders/_shipment.html.haml @@ -33,7 +33,7 @@ %tbody{ "data-shipment-number" => "#{shipment.number}", "data-order-number" => "#{order.number}" } = render 'spree/admin/orders/shipment_manifest', order: order, shipment: shipment - - unless shipment.shipped? + - if shipment.can_modify? %tr.edit-method.hidden.total %td{ :colspan => "5" } %div.field.alpha.five.columns @@ -69,7 +69,7 @@ %span = shipment.fee_adjustment.display_amount - - if shipment.fee_adjustment.present? && !shipment.shipped? + - if shipment.fee_adjustment.present? && shipment.can_modify? %td.actions - if can? :update, shipment = link_to '', '', :class => 'edit-method icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit') @@ -81,7 +81,7 @@ = text_field_tag :tracking, shipment.tracking %td.actions - - if can? :update, shipment + - if can?(:update, shipment) && !shipment.canceled? = link_to '', '', :class => 'save-tracking icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, :title => I18n.t('actions.save') = link_to '', '', :class => 'cancel-tracking icon_link icon-cancel no-text with-tip', :data => { :action => 'cancel' }, :title => I18n.t('actions.cancel') @@ -95,5 +95,5 @@ = Spree.t(:no_tracking_present) %td.actions - - if can? :update, shipment + - if can?(:update, shipment) && shipment.can_modify? = link_to '', '', :class => 'edit-tracking icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit') diff --git a/app/views/spree/admin/orders/_shipment_manifest.html.haml b/app/views/spree/admin/orders/_shipment_manifest.html.haml index 51d1571735..5393b4a5d3 100644 --- a/app/views/spree/admin/orders/_shipment_manifest.html.haml +++ b/app/views/spree/admin/orders/_shipment_manifest.html.haml @@ -14,12 +14,12 @@ = "#{count} x #{t(state.humanize.downcase, scope: [:spree, :shipment_states], default: [:missing, "none"])}" - unless shipment.shipped? %td.item-qty-edit.hidden - = number_field_tag :quantity, item.quantity, :min => 0, :class => "line_item_quantity", :size => 5, :max => item.variant.on_hand + item.quantity + = quantity_field_tag(item) %td.item-total.align-center = line_item_shipment_price(line_item, item.quantity) %td.cart-item-delete.actions{ "data-hook" => "cart_item_delete" } - - if !shipment.shipped? && can?(:update, shipment) + - if shipment.can_modify? && can?(:update, shipment) = link_to '', '#', :class => 'save-item icon_link icon-ok no-text with-tip', :data => {'shipment-number' => shipment.number, 'variant-id' => item.variant.id, :action => 'save'}, :title => t('actions.save'), :style => 'display: none' = link_to '', '#', :class => 'cancel-item icon_link icon-cancel no-text with-tip', :data => {:action => 'cancel'}, :title => t('actions.cancel'), :style => 'display: none' = link_to '', '#', :class => 'edit-item icon_link icon-edit no-text with-tip', :data => {:action => 'edit'}, :title => t('actions.edit') diff --git a/app/views/spree/admin/orders/index.html.haml b/app/views/spree/admin/orders/index.html.haml index 6ab4d5a238..758fc4dd07 100644 --- a/app/views/spree/admin/orders/index.html.haml +++ b/app/views/spree/admin/orders/index.html.haml @@ -3,7 +3,7 @@ - content_for :page_actions do %li - = button_link_to t('.new_order'), new_admin_order_url, icon: 'icon-plus', id: 'admin_new_order' + = button_link_to t('.new_order'), spree.new_admin_order_url, icon: 'icon-plus', id: 'admin_new_order' = render partial: 'spree/admin/shared/order_sub_menu' @@ -74,7 +74,8 @@ %span.state{'ng-class' => 'order.shipment_state', 'ng-if' => 'order.shipment_state'} {{'js.admin.orders.shipment_states.' + order.shipment_state | t}} %td - = mail_to "{{order.email}}" + %a{ ng: { href: "mailto:{{order.email}}" } } + {{order.email}} %br {{order.full_name}} %td.align-center diff --git a/app/views/spree/admin/products/new.html.haml b/app/views/spree/admin/products/new.html.haml index 5bc7530619..ddf877a8b2 100644 --- a/app/views/spree/admin/products/new.html.haml +++ b/app/views/spree/admin/products/new.html.haml @@ -4,7 +4,7 @@ = form_for [:admin, @product], :html => { :multipart => true } do |f| .twelve.columns.alpha - %fieldset.no-border-bottom{ id: "new_product" } + %fieldset.no-border-bottom{ id: "new_product", 'ng-controller' => 'unitsCtrl' } %legend{align: "center"}= t(".new_product") .sixteen.columns.alpha .eight.columns.alpha @@ -20,7 +20,7 @@ %br/ = f.text_field :name, :class => 'fullwidth title' = f.error_message_on :name - .sixteen.columns.alpha{ 'ng-controller' => 'unitsCtrl' } + .sixteen.columns.alpha .eight.columns.alpha = f.field_container :units do = f.label :variant_unit_with_scale, t(".units") @@ -31,7 +31,7 @@ %input{ type: 'hidden', 'ng-value' => 'product.variant_unit_scale', name: 'product[variant_unit_scale]' } .two.columns = f.field_container :unit_value do - = f.label :product_unit_value_with_description, t(".value"), 'ng-disabled' => "!hasUnit(product)" + = f.label :unit_value_with_description, t(".value"), 'ng-disabled' => "!hasUnit(product)" %span.required * %input.fullwidth{ id: 'product_unit_value_with_description', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', placeholder: "eg. 2", 'ng-disabled' => "!hasUnit(product)" } %input{ type: 'hidden', 'ng-value' => 'product.master.unit_value', name: 'product[unit_value]' } @@ -45,33 +45,47 @@ .sixteen.columns.alpha .eight.columns.alpha = render 'spree/admin/products/primary_taxon_form', f: f - .three.columns + .four.columns = f.field_container :price do = f.label :price, t(".price") %span.required * %br/ - = f.text_field :price, class: 'fullwidth' + = f.text_field :price, { "class" => "fullwidth", "ng-model" => "product.price" } = f.error_message_on :price + - if feature? :unit_price, spree_current_user + .four.columns{ ng: { app: 'ofn.admin'}} + = f.field_container :unit_price do + %div{style: "display: flex"} + = f.label :unit_price, t(".unit_price") + %question-mark-with-tooltip{"question-mark-with-tooltip" => "_", + "question-mark-with-tooltip-append-to-body" => "true", + "question-mark-with-tooltip-placement" => "top", + "question-mark-with-tooltip-animation" => true, + key: "'js.admin.unit_price_tooltip'"} + %input{ "type" => "text", "id" => "product_unit_price", "name" => "product[unit_price]", + "class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"} + %div{style: "color: black"} + = t(".unit_price_legend") + .sixteen.columns.alpha .three.columns + - if Spree::TaxCategory.any? + = render 'spree/admin/products/tax_category_form', f: f + - else +   + .five.columns.omega + = render 'spree/admin/products/shipping_category_form', f: f + .five.columns = f.field_container :on_hand do = f.label :on_hand, t(".on_hand") %br/ = f.text_field :on_hand, class: 'fullwidth' = f.error_message_on :on_hand - .two.columns.omega + .three.columns.omega = f.field_container :on_demand do = f.label :on_demand, t(".on_demand") %br/ = f.check_box :on_demand = f.error_message_on :on_demand - .sixteen.columns.alpha - .four.columns - - if Spree::TaxCategory.any? - = render 'spree/admin/products/tax_category_form', f: f - - else -   - .four.columns.omega - = render 'spree/admin/products/shipping_category_form', f: f .sixteen.columns.alpha = f.field_container :description do diff --git a/app/views/spree/admin/shared/_head.html.haml b/app/views/spree/admin/shared/_head.html.haml index 71e3170e59..e783e2f07e 100644 --- a/app/views/spree/admin/shared/_head.html.haml +++ b/app/views/spree/admin/shared/_head.html.haml @@ -21,7 +21,6 @@ %script = raw "var AUTH_TOKEN = \"#{form_authenticity_token}\";" -= render "layouts/bugherd_script" %link{'data-require' => "font-awesome@*", 'data-semver'=>"4.2.0", 'rel' => "stylesheet", 'href' => "//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css"} = render "layouts/auth_token_script" diff --git a/app/views/spree/admin/shared/_order_tabs.html.haml b/app/views/spree/admin/shared/_order_tabs.html.haml index f96a5dd140..4f4c70bfca 100644 --- a/app/views/spree/admin/shared/_order_tabs.html.haml +++ b/app/views/spree/admin/shared/_order_tabs.html.haml @@ -46,21 +46,21 @@ %ul - order_details_classes = "active" if current == "Order Details" %li{ class: order_details_classes } - = link_to_with_icon 'icon-edit', t(:order_details), edit_admin_order_url(@order) + = link_to_with_icon 'icon-edit', t(:order_details), spree.edit_admin_order_url(@order) - customer_details_classes = "active" if current == "Customer Details" %li{ class: customer_details_classes } - = link_to_with_icon 'icon-user', t(:customer_details), admin_order_customer_url(@order) + = link_to_with_icon 'icon-user', t(:customer_details), spree.admin_order_customer_url(@order) - adjustments_classes = "active" if current == "Adjustments" %li{ class: adjustments_classes } - = link_to_with_icon 'icon-cogs', t(:adjustments), admin_order_adjustments_url(@order) + = link_to_with_icon 'icon-cogs', t(:adjustments), spree.admin_order_adjustments_url(@order) - payments_classes = "active" if current == "Payments" %li{ class: payments_classes } - = link_to_with_icon 'icon-credit-card', t(:payments), admin_order_payments_url(@order) + = link_to_with_icon 'icon-credit-card', t(:payments), spree.admin_order_payments_url(@order) - if @order.completed? - authorizations_classes = "active" if current == "Return Authorizations" %li{ class: authorizations_classes } - = link_to_with_icon 'icon-share-alt', t(:return_authorizations), admin_order_return_authorizations_url(@order) + = link_to_with_icon 'icon-share-alt', t(:return_authorizations), spree.admin_order_return_authorizations_url(@order) diff --git a/app/views/spree/admin/shared/_routes.html.erb b/app/views/spree/admin/shared/_routes.html.erb index 438d257af9..418359b5e7 100644 --- a/app/views/spree/admin/shared/_routes.html.erb +++ b/app/views/spree/admin/shared/_routes.html.erb @@ -7,8 +7,8 @@ } Spree.routes = <%== { :variants_search => spree.admin_search_variants_path(:format => 'json'), - :taxons_search => main_app.api_taxons_path(:format => 'json'), - :orders_api => main_app.api_orders_path, - :states_search => main_app.api_states_path(:format => 'json') + :taxons_search => main_app.api_v0_taxons_path(:format => 'json'), + :orders_api => main_app.api_v0_orders_path, + :states_search => main_app.api_v0_states_path(:format => 'json') }.to_json %>; diff --git a/app/views/spree/admin/shipping_methods/_form.html.haml b/app/views/spree/admin/shipping_methods/_form.html.haml index ba11c45ecd..6e52ce1537 100644 --- a/app/views/spree/admin/shipping_methods/_form.html.haml +++ b/app/views/spree/admin/shipping_methods/_form.html.haml @@ -43,9 +43,16 @@ = f.hidden_field :tag_list, "ng-value" => "shippingMethod.tag_list" %tags-with-translation#something{ object: "shippingMethod", 'find-tags' => 'findTags(query)' } - + = render partial: 'spree/admin/shared/calculator_fields', locals: { f: f } + %fieldset.tax_categories.no-border-bottom + %legend{align: "center"}= t('.tax_category') + = f.field_container :tax_categories do + = f.select :tax_category_id, @tax_categories.map { |tc| [tc.name, tc.id] }, + { include_blank: t(:none) }, class: "select2 fullwidth" + = error_message_on :shipping_method, :tax_category_id + %fieldset.categories.no-border-bottom %legend{align: "center"}= t('.categories') = f.field_container :categories do @@ -56,7 +63,7 @@ %br/ = error_message_on :shipping_method, :shipping_category_id - + %fieldset.no-border-bottom %legend{align: "center"}= t('.zones') = f.field_container :zones do diff --git a/app/views/spree/admin/tax_settings/edit.html.haml b/app/views/spree/admin/tax_settings/edit.html.haml index edd5a3b401..7ad2a3cdc7 100644 --- a/app/views/spree/admin/tax_settings/edit.html.haml +++ b/app/views/spree/admin/tax_settings/edit.html.haml @@ -10,14 +10,5 @@ = check_box_tag 'preferences[products_require_tax_category]', '1', Spree::Config[:products_require_tax_category] = label_tag nil, t(:products_require_tax_category) - .field.align-center{"data-hook" => "shipment_vat"} - = hidden_field_tag 'preferences[shipment_inc_vat]', '0' - = check_box_tag 'preferences[shipment_inc_vat]', '1', Spree::Config[:shipment_inc_vat] - = label_tag nil, t(:shipment_inc_vat) - - .field.align-center{ "data-hook" => "shipping_tax_rate" } - = number_field_tag "preferences[shipping_tax_rate]", Spree::Config[:shipping_tax_rate].to_f, in: 0.0..1.0, step: 0.01 - = label_tag nil, t(:shipping_tax_rate) - .form-buttons{"data-hook" => "buttons"} = button t(:update), 'icon-refresh' diff --git a/app/views/spree/admin/taxonomies/edit.haml b/app/views/spree/admin/taxonomies/edit.haml index eb43b8fa84..7f37454aec 100755 --- a/app/views/spree/admin/taxonomies/edit.haml +++ b/app/views/spree/admin/taxonomies/edit.haml @@ -17,7 +17,7 @@ = label_tag nil, t("spree.tree") %br/ :javascript - Spree.routes.taxonomy_taxons_path = "#{main_app.api_taxonomy_taxons_path(@taxonomy)}"; + Spree.routes.taxonomy_taxons_path = "#{main_app.api_v0_taxonomy_taxons_path(@taxonomy)}"; Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}"; #taxonomy_tree.tree #progress{style: "display:none;"} diff --git a/app/views/spree/admin/variants/_form.html.haml b/app/views/spree/admin/variants/_form.html.haml index dd84560ec5..4ac03f7b54 100644 --- a/app/views/spree/admin/variants/_form.html.haml +++ b/app/views/spree/admin/variants/_form.html.haml @@ -1,4 +1,4 @@ -.label-block.left.six.columns.alpha{'ng-app' => 'admin.products'} +.label-block.left.six.columns.alpha{'ng-app' => 'admin.products', 'ng-controller' => 'variantUnitsCtrl'} .field = f.label :display_name, t('.display_name') = f.text_field :display_name, class: "fullwidth", placeholder: t('.display_name_placeholder') @@ -8,8 +8,8 @@ - if product_has_variant_unit_option_type?(@product) - if @product.variant_unit != 'items' - .field{'ng-controller' => 'variantUnitsCtrl'} - = f.label :unit_value, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})" + .field + = label_tag :unit_value_human, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})" = hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale = text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'} = f.text_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'} @@ -33,8 +33,23 @@ = f.text_field :sku, class: 'fullwidth' .field = f.label :price, t('.price') - = f.text_field :price, value: number_to_currency(@variant.price, unit: ''), class: 'fullwidth' - + = f.text_field :price, class: 'fullwidth', "ng-model" => "variant.price", "ng-init" => "variant.price = '#{number_to_currency(@variant.price, unit: '')}'" + - if feature? :unit_price, spree_current_user + .field + = hidden_field_tag 'product_variant_unit', @product.variant_unit + = hidden_field_tag 'product_variant_unit_name', @product.variant_unit_name + = f.field_container :unit_price do + %div{style: "display: flex"} + = f.label :unit_price, t(".unit_price"), {style: "display: inline-block"} + %question-mark-with-tooltip{"question-mark-with-tooltip" => "_", + "question-mark-with-tooltip-append-to-body" => "true", + "question-mark-with-tooltip-placement" => "top", + "question-mark-with-tooltip-animation" => true, + key: "'js.admin.unit_price_tooltip'"} + %input{ "type" => "text", "id" => "variant_unit_price", "name" => "variant[unit_price]", + "class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"} + %div{style: "color: black"} + = t("spree.admin.products.new.unit_price_legend") %div{ 'set-on-demand' => '' } .field.checkbox %label diff --git a/app/views/spree/admin/variants/index.html.haml b/app/views/spree/admin/variants/index.html.haml index 9be92b7d5c..f6ba802805 100644 --- a/app/views/spree/admin/variants/index.html.haml +++ b/app/views/spree/admin/variants/index.html.haml @@ -30,17 +30,9 @@ = link_to_with_icon('icon-edit', Spree.t(:edit), edit_object_url(variant, @url_filters), no_text: true) unless variant.deleted? = link_to_delete(variant, { url: object_url(variant, @url_filters), no_text: true }) unless variant.deleted? -- if @product.empty_option_values? - %p.first_add_option_types.no-objects-found - = t('.to_add_variants_you_must_first_define') - = link_to t('.option_types'), admin_product_url(@product) - = t('.and') - = link_to t('.option_values'), admin_option_types_url +- content_for :page_actions do + %ul.inline-menu + %li#new_var_link + = link_to_with_icon('icon-plus', t('.new_variant'), new_admin_product_variant_url(@product, @url_filters), class: 'button') -- else - - content_for :page_actions do - %ul.inline-menu - %li#new_var_link - = link_to_with_icon('icon-plus', t('.new_variant'), new_admin_product_variant_url(@product, @url_filters), class: 'button') - - %li= link_to_with_icon('icon-filter', @deleted.blank? ? t('.show_deleted') : t('.show_active'), admin_product_variants_url(@product, @url_filters.merge(deleted: @deleted.blank? ? "on" : "off")), class: 'button') + %li= link_to_with_icon('icon-filter', @deleted.blank? ? t('.show_deleted') : t('.show_active'), admin_product_variants_url(@product, @url_filters.merge(deleted: @deleted.blank? ? "on" : "off")), class: 'button') diff --git a/app/views/spree/orders/_adjustments.html.haml b/app/views/spree/orders/_adjustments.html.haml index 14fba90f72..915e1a3c39 100644 --- a/app/views/spree/orders/_adjustments.html.haml +++ b/app/views/spree/orders/_adjustments.html.haml @@ -3,7 +3,7 @@ %a{ href: "#" } = t :orders_fees -- checkout_line_item_adjustments(@order).each do |adjustment| +- checkout_line_item_fees(@order).each do |adjustment| %tr.cart_adjustment %td{colspan: "3"}= adjustment.label %td.text-right= adjustment.display_amount.to_html diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index 6c5837d5c1..0ddaf10644 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -22,6 +22,10 @@ %span.already-confirmed= t(:orders_bought_already_confirmed) %td.text-right.cart-item-price = line_item.single_display_amount_with_adjustments.to_html + - if feature? :unit_price, spree_current_user + %br + %span.unit-price + = line_item.unit_price_price_and_unit %td.text-center.cart-item-quantity = line_item.quantity %td.cart-item-total.text-right diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index b38327dd56..e7c83d1217 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -31,12 +31,12 @@ %td.text-right %span.order-total.item-total= display_checkout_subtotal(@order) %td - -if display_checkout_admin_and_handling_adjustments_total_for(@order) != Spree::Money.new(0 , currency: @order.currency) + -if display_line_item_fees_total_for(@order) != Spree::Money.new(0 , currency: @order.currency) %tr %td.text-right{colspan:"3"} = t :orders_form_admin %td.text-right - %span.order-total.distribution-total= display_checkout_admin_and_handling_adjustments_total_for(@order) + %span.order-total.distribution-total= display_line_item_fees_total_for(@order) %td - checkout_adjustments_for(@order, exclude: [:line_item, :admin_and_handling]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| diff --git a/app/views/spree/orders/form/_cart_actions_row.html.haml b/app/views/spree/orders/form/_cart_actions_row.html.haml index a7005a5eb6..e37adb037b 100644 --- a/app/views/spree/orders/form/_cart_actions_row.html.haml +++ b/app/views/spree/orders/form/_cart_actions_row.html.haml @@ -3,7 +3,7 @@ %td %button#update-button.secondary.radius.expand.small{"ng-class" => "{ alert: form.$dirty && form.$valid }"} %i.ofn-i_023-refresh - = t(:update) + = t(:orders_form_update_cart) %td %td#empty-cart.text-center %span#clear_cart_link{"data-hook" => ""} diff --git a/app/views/subscription_mailer/_summary_detail.html.haml b/app/views/subscription_mailer/_summary_detail.html.haml index 9e99633dcb..a566b2396d 100644 --- a/app/views/subscription_mailer/_summary_detail.html.haml +++ b/app/views/subscription_mailer/_summary_detail.html.haml @@ -19,3 +19,11 @@ - orders.each_with_index do |order, i| %a{ href: order_url(order) }>= order.number = ", " if i < orders.count - 1 + +- if summary.subscription_issues.any? + - subscription_issues = summary.subscription_issues + %h4= t(".other.title", count: subscription_issues.count) + %p= t(".other.explainer") + - subscription_issues.each_with_index do |subscription_id, i| + %a{ href: edit_admin_subscription_url(subscription_id) }>= subscription_id + = ", " if i < subscription_issues.count - 1 diff --git a/config/application.rb b/config/application.rb index 33638102f5..20fe4aa4b8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -39,10 +39,6 @@ module Openfoodnetwork Spree::Config = app.config.spree.preferences # legacy access end - initializer "spree.load_preferences", before: "spree.environment" do - ::ActiveRecord::Base.include Spree::Preferences::Preferable - end - initializer "spree.register.payment_methods" do |app| app.config.spree.payment_methods = [ Spree::Gateway::Bogus, @@ -79,7 +75,8 @@ module Openfoodnetwork initializer 'ofn.spree_locale_settings', before: 'spree.promo.environment' do |app| Spree::Config['checkout_zone'] = ENV['CHECKOUT_ZONE'] Spree::Config['currency'] = ENV['CURRENCY'] - if Spree::Country.table_exists? + + if ActiveRecord::Base.connected? && Spree::Country.table_exists? country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) Spree::Config['default_country_id'] = country.id if country.present? else @@ -200,5 +197,7 @@ module Openfoodnetwork config.active_support.escape_html_entities_in_json = true config.active_job.queue_adapter = :delayed_job + + config.generators.template_engine = :haml end end diff --git a/config/database.yml b/config/database.yml index 617ee5ae93..1a149be442 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,7 +1,7 @@ defaults: &defaults adapter: postgresql encoding: unicode - pool: <%= ENV.fetch('OFN_DB_POOL', 5) %> + pool: <%= ENV.fetch('OFN_DB_POOL', 6) %> host: <%= ENV.fetch('OFN_DB_HOST', 'localhost') %> username: <%= ENV.fetch('OFN_DB_USERNAME', 'ofn') %> password: <%= ENV.fetch('OFN_DB_PASSWORD', 'f00d') %> diff --git a/config/environments/development.rb b/config/environments/development.rb index dc7250eb4a..72c6e7d7cb 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -64,4 +64,6 @@ Openfoodnetwork::Application.configure do config.action_mailer.default_url_options = { host: "0.0.0.0:3000" } config.log_level = :debug + + config.view_component_storybook.stories_path = Rails.root.join("spec/components/stories") end diff --git a/config/environments/test.rb b/config/environments/test.rb index dd68bc0459..e5acc6e253 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -31,6 +31,9 @@ Openfoodnetwork::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test + # Tests should fail when translations are missing. + config.action_view.raise_on_missing_translations = true + config.time_zone = ENV.fetch("TIMEZONE", "UTC") # Tests assume English text on the site. diff --git a/config/initializers/bullet.rb b/config/initializers/bullet.rb index 89ba05a6c3..a1831aa7c8 100644 --- a/config/initializers/bullet.rb +++ b/config/initializers/bullet.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -if defined?(Bullet) +if defined?(Bullet) && ENV.fetch("ENABLE_BULLET", false) Rails.application.config.after_initialize do Bullet.enable = true Bullet.bullet_logger = true diff --git a/config/initializers/feature_toggles.rb b/config/initializers/feature_toggles.rb deleted file mode 100644 index a0f900c44a..0000000000 --- a/config/initializers/feature_toggles.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'open_food_network/feature_toggle' - -beta_testers = ENV['BETA_TESTERS']&.split(/[\s,]+/) || [] - -OpenFoodNetwork::FeatureToggle.enable(:customer_balance) do |user| - if beta_testers == ['all'] - true - else - beta_testers.include?(user.email) - end -end - -OpenFoodNetwork::FeatureToggle.enable(:unit_price) do - ['development', 'staging'].include?(ENV['RAILS_ENV']) -end diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb new file mode 100644 index 0000000000..80ed02e572 --- /dev/null +++ b/config/initializers/flipper.rb @@ -0,0 +1,22 @@ +require "flipper" +require "flipper/adapters/active_record" +require "flipper/instrumentation/log_subscriber" + +Flipper.configure do |config| + config.default do + adapter = Flipper::Adapters::ActiveRecord.new + instrumented = Flipper::Adapters::Instrumented.new(adapter, instrumenter: ActiveSupport::Notifications) + Flipper.new(instrumented, instrumenter: ActiveSupport::Notifications) + end +end + +if Rails.env.production? + Flipper::UI.configure do |config| + config.banner_text = '⚠️ Production environment: be aware that the changes have an impact on the application. Please, read the how-to before: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Feature-toggle-with-Flipper' + config.banner_class = 'danger' + end +end + +Rails.configuration.middleware.use Flipper::Middleware::Memoizer, preload_all: true + +Flipper.register(:admins) { |actor| actor.respond_to?(:admin?) && actor.admin? } diff --git a/config/initializers/storybook.rb b/config/initializers/storybook.rb new file mode 100644 index 0000000000..3f521af868 --- /dev/null +++ b/config/initializers/storybook.rb @@ -0,0 +1,14 @@ +# Adjust headers to allow running Storybook in development. +# Uses iframes and doesn't play nicely with CORS checks + +if Rails.env.development? + module PermissiveCORSHeaders + def self.before(response) + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Methods"] = "GET" + end + end + + ViewComponent::Storybook::StoriesController.before_action(PermissiveCORSHeaders) +end + diff --git a/config/initializers/wicked_pdf.rb b/config/initializers/wicked_pdf.rb index d460773073..05a63f325b 100644 --- a/config/initializers/wicked_pdf.rb +++ b/config/initializers/wicked_pdf.rb @@ -3,3 +3,11 @@ WickedPdf.config = { #:layout => "pdf.html", :exe_path => `bundle exec which wkhtmltopdf`.chomp } + +# A monkey-patch to remove WickedPdf's monkey-patch, as it clashes with ViewComponents. +class WickedPdf + module PdfHelper + remove_method(:render) + remove_method(:render_to_string) + end +end diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 9540545794..c1409604d4 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -85,6 +85,10 @@ ar: no_default_card: "^ لا توجد بطاقة متاحة لهذا العميل" shipping_method: not_available_to_shop: "غير متاح لـ %{shop}" + card_details: "معلومات البطاقة" + card_type: "نوع البطاقة" + cardholder_name: "إسم صاحب البطاقة" + customer_instructions: "تعليمات العملاء" devise: confirmations: send_instructions: "ستتلقى رسالة بريد إلكتروني تحتوي على إرشادات حول كيفية تأكيد حسابك في بضع دقائق." @@ -119,6 +123,8 @@ ar: cloned_order_cycle_name: "نسخة من %{order_cycle}" tax_rate: included_in_price: "مشمول في السعر" + sku: "SKU" + tax_rate: "معدل الضريبة" validators: date_time_string_validator: not_string_error: "يجب أن تكون احرف" @@ -264,7 +270,6 @@ ar: error: خطأ processing_payment: "معالجة الدفع..." no_pending_payments: "لا توجد دفعات معلقة" - invalid_payment_state: "حالة الدفع غير صالحة" filter_results: تصفية النتائج quantity: الكمية pick_up: النقل @@ -1144,6 +1149,7 @@ ar: yes_cancel_them: إلغاء no_keep_them: احتفظ بهم yes_i_am_sure: نعم أنا متأكد + number: "رقم " order_update_issues_msg: تعذر تحديث بعض الطلبات تلقائيًا ، وهذا على الأرجح لأنه تم تعديلها يدويًا. يرجى مراجعة المشكلات المذكورة أدناه وإجراء أي تعديلات على الطلبات الفردية إذا لزم الأمر. no_results: no_subscriptions: لا اشتراكات حتى الآن ... @@ -1176,8 +1182,10 @@ ar: message_html: "أوافق على %{terms_and_conditions_link} للبائع." link_text: "الأحكام والشروط" platform_terms_of_service: + message_html: "أوافق على المنصة %{tos_link}." terms_of_service: "شروط الخدمة" all_terms_and_conditions: + message_html: "أوافق على %{terms_and_conditions_link} البائع والمنصة %{tos_link}." terms_and_conditions: "الأحكام والشروط" terms_of_service: "شروط الخدمة" failed: "فشل الخروج. يرجى إعلامنا حتى نتمكن من معالجة طلبك." @@ -1569,7 +1577,9 @@ ar: shopping_tabs_home: "الصفحة الرئيسية" shopping_tabs_shop: "المتجر" shopping_tabs_about: "حول" + shopping_tabs_producers: "المنتجين" shopping_tabs_contact: "اتصل" + shopping_tabs_groups: "مجموعات" shopping_contact_address: "عنوان" shopping_contact_web: "اتصل" shopping_contact_social: "إتبع" @@ -1721,39 +1731,40 @@ ar: shops_signup_help: نحن على استعداد للمساعدة. shops_signup_help_text: أنت بحاجة إلى عائد أفضل. تحتاج لمشترين جدد وشركاء لوجستيين. تحتاج إلى سرد قصتك عبر الجملة والتجزئة وطاولة المطبخ. shops_signup_detail: هنا التفاصيل. - orders: الطلبات - orders_fees: رسوم ... - orders_edit_title: سلة التسوق - orders_edit_headline: سلة التسوق الخاصة بك - orders_edit_time: الطلب جاهز لل - orders_edit_continue: مواصلة التسوق - orders_edit_checkout: تابع للخروج + orders: "الطلبات" + orders_fees: "رسوم ..." + orders_edit_title: "سلة التسوق" + orders_edit_headline: "سلة التسوق الخاصة بك" + orders_edit_time: "الطلب جاهز لل" + orders_edit_continue: "مواصلة التسوق" + orders_edit_checkout: "تابع للخروج" orders_form_empty_cart: "السلة فارغة" - orders_form_subtotal: إنتاج المجموع الفرعي - orders_form_admin: الادارة و المعالجة - orders_form_total: مجموع - orders_oc_expired_headline: تم إغلاق الطلبات لدورة الطلب هذه + orders_form_update_cart: "تحديث" + orders_form_subtotal: "إنتاج المجموع الفرعي" + orders_form_admin: "الادارة و المعالجة" + orders_form_total: "مجموع" + orders_oc_expired_headline: "تم إغلاق الطلبات لدورة الطلب هذه" orders_oc_expired_text: "عفوًا ، تم إغلاق أوامر دورة الطلب هذه منذ %{time}! يرجى الاتصال بالمركز مباشرة لمعرفة ما إذا كان يمكنهم قبول الطلبات المتأخرة أم لا." orders_oc_expired_text_others_html: "عفوًا ، تم إغلاق أوامر دورة الطلب هذه منذ %{time}! يرجى الاتصال بالمركز مباشرة لمعرفة ما إذا كان يمكنهم قبول الطلبات المتأخرة %{link} ." orders_oc_expired_text_link: "أو راجع دورات الترتيب الأخرى المتاحة في هذا المركز" orders_oc_expired_email: "البريد الإلكتروني:" orders_oc_expired_phone: "هاتف:" - orders_show_title: تأكيد الطلب - orders_show_time: الطلب جاهز + orders_show_title: "تأكيد الطلب" + orders_show_time: "الطلب جاهز" orders_show_order_number: "الطلب # %{number}" - orders_show_cancelled: ألغيت - orders_show_confirmed: تم تأكيد + orders_show_cancelled: "ألغيت" + orders_show_confirmed: "تم تأكيد" orders_your_order_has_been_cancelled: "تم إلغاء طلبك" orders_could_not_cancel: "عذرًا ، تعذر إلغاء الطلب" orders_cannot_remove_the_final_item: "لا يمكن إزالة العنصر الأخير من الطلب ، يرجى إلغاء الطلب بدلاً من ذلك." orders_bought_items_notice: - one: تم بالفعل تأكيد عنصر إضافي لدورة الطلب هذه + one: "تم بالفعل تأكيد عنصر إضافي لدورة الطلب هذه" few: "%{count} البنود الإضافية المؤكدة بالفعل لدورة الطلب هذه" many: "%{count} البنود الإضافية المؤكدة بالفعل لدورة الطلب هذه" other: "%{count} البنود الإضافية المؤكدة بالفعل لدورة الطلب هذه" - orders_bought_edit_button: تحرير العناصر المؤكدة + orders_bought_edit_button: "تحرير العناصر المؤكدة" orders_bought_already_confirmed: "* أكد بالفعل" - orders_confirm_cancel: هل أنت متأكد أنك تريد إلغاء هذا الطلب؟ + orders_confirm_cancel: "هل أنت متأكد أنك تريد إلغاء هذا الطلب؟" order_processed_successfully: "تمت معالجة طلبك بنجاح" products_cart_distributor_choice: "الموزع لطلبك:" products_cart_distributor_change: "سيتم تغيير موزعك لهذا الطلب إلى %{name} إذا أضفت هذا المنتج إلى سلة التسوق الخاصة بك." @@ -2410,6 +2421,7 @@ ar: حدثت مشكلة أثناء إضافة هذا المنتج إلى عربة التسوق. ربما أصبح غير متوفر أو أن المحل يغلق. admin: + unit_price_tooltip: "يزيد سعر الوحدة من الشفافية من خلال السماح لعملائك بمقارنة الأسعار بسهولة بين المنتجات المختلفة وأحجام العبوات. لاحظ أن سعر الوحدة النهائي المعروض في واجهة المحل قد يختلف لأنه يشمل الضرائب والرسوم." enterprise_limit_reached: "لقد وصلت إلى الحد القياسي للمؤسسات لكل حساب. اكتب %{contact_email} إذا كنت بحاجة إلى زيادته." modals: got_it: "فهمتك" @@ -2894,6 +2906,9 @@ ar: start_free_profile: "ابدأ بملف تعريف مجاني ، وتوسع عندما تكون جاهزًا!" order_management: reports: + bulk_coop: + filters: + generate_report: "توليد تقرير" enterprise_fee_summaries: filters: date_range: "نطاق الموعد" @@ -2939,6 +2954,8 @@ ar: tax_category_name: "الفئة الضريبية" total_amount: "$$ مجموع" invalid_filter_parameters: "الفلاتر التي حددتها لهذا التقرير غير صالحة." + report: + none: "لا شيء" order: "طلب" distribution: "توزيع" order_details: "تفاصيل الطلب" @@ -2971,7 +2988,13 @@ ar: previous: "السابق" last: "الاخير" spree: + all: "الكل" + category: "الفئة" + credit: "اجل" more: "أكثر" + no_pending_payments: "لا توجد دفعات معلقة" + none: "لا شيء" + updating: "تحديث" your_order_is_empty_add_product: "طلبك فارغ ، يرجى البحث عن المنتج أعلاه وإضافته" add_product: "أضف منتج" name_or_sku: "الاسم أو SKU (أدخل أول 4 أحرف على الأقل من اسم المنتج)" @@ -2999,6 +3022,7 @@ ar: tracking_number: "أرقام التتبع" order_total: "مجموع الطلب " customer_details: "تفاصيل العميل" + customer_details_updated: "تم تحديث تفاصيل العميل" customer_search: "بحث العملاء" choose_a_customer: "اختيار العملاء" account: "الحساب" @@ -3149,6 +3173,8 @@ ar: payment_method: "طريقة الدفع او السداد" payment_processing_failed: "لا يمكن معالجة الدفع ، يرجى التحقق من التفاصيل التي أدخلتها" not_available: "غير متاح" + sku: "SKU" + there_are_no_items_for_this_order: "لا توجد عناصر لهذا الطلب." order_populator: out_of_stock: '%{item} غير متوفر.' actions: @@ -3176,7 +3202,17 @@ ar: login_nav: header: store: متجر + validation: + must_be_int: "يجب أن يكون رقما صحيحا" admin: + mail_methods: + send_testmail: "إرسال بريد إلكتروني تجريبي" + testmail: + delivery_success: "تم إرسال بريد إلكتروني تجريبي." + error: "حدث خطأ أثناء محاولة إرسال البريد الإلكتروني التجريبي." + unit_price_tooltip: "يزيد سعر الوحدة من الشفافية من خلال السماح لعملائك بمقارنة الأسعار بسهولة بين المنتجات المختلفة وأحجام العبوات. لاحظ أن سعر الوحدة النهائي المعروض في واجهة المحل قد يختلف لأنه يشمل الضرائب والرسوم." + subscriptions: + number: "رقم " tab: dashboard: "لوحة العرض" orders: "الطلبات" @@ -3245,6 +3281,8 @@ ar: received: "تم الاستلام" canceled: "ألغيت" orders: + add_product: + cannot_add_item_to_canceled_order: "لا يمكن إضافة عنصر إلى الطلب الملغى" index: listing_orders: "لائحة الطلبات" new_order: "طلب جديد" @@ -3287,6 +3325,8 @@ ar: overview: enterprises_header: ofn_with_tip: المؤسسات هم المنتجون و / أو محاور وهي الوحدة الأساسية للمؤسسة ضمن شبكة الغذاء المفتوح. + enterprise_row: + has_no_enterprise_fees: "لا توجد رسوم للمؤسسة" products: active_products: zero: "ليس لديك أي منتجات نشطة." @@ -3325,6 +3365,7 @@ ar: back_to_shipping_methods_list: "العودة إلى قائمة طرق الشحن" form: categories: "التصنيفات" + tax_category: "الفئة الضريبية" zones: "مناطق" both: "كل من تسجيل الخروج والمكتب الخلفي" back_end: "المكتب الخلفي فقط" @@ -3405,6 +3446,8 @@ ar: value: "القيمة" unit_name: "إسم الوحدة" price: "السعر" + unit_price: "سعر الوحدة" + unit_price_legend: "محسوبة على أساس سعر السلعة" on_hand: "متوفر" on_demand: "حسب الطلب" product_description: "وصف المنتج" @@ -3475,7 +3518,6 @@ ar: price: "السعر" options: "خيارات" no_results: "لا يوجد نتائج" - to_add_variants_you_must_first_define: "لإضافة المتغيرات ، يجب عليك أولاً تعريفها" option_types: "أنواع الخيارات" option_values: "قيم الخيارات" and: "و" @@ -3487,6 +3529,7 @@ ar: form: sku: "SKU" price: "السعر" + unit_price: "سعر الوحدة" display_as: "عرض ب" display_name: "اسم العرض" display_as_placeholder: 'على سبيل المثال 2 كجم' @@ -3510,6 +3553,7 @@ ar: cookies_consent_banner_toggle: "عرض راية موافقة ملفات تعريف الارتباط" privacy_policy_url: "رابط سياسة الخصوصية" enterprises_require_tos: "يجب على المؤسسات قبول شروط الخدمة" + shoppers_require_tos: "يجب على المتسوقين قبول شروط الخدمة" cookies_policy_matomo_section: "عرض قسم Matomo في صفحة سياسة ملفات تعريف الارتباط" footer_tos_url: "رابط شروط الخدمة " checkout: @@ -3726,3 +3770,90 @@ ar: few: المدفوعات many: المدفوعات other: الدفعات + datetime: + distance_in_words: + about_x_hours: + zero: حوالي %{count} ساعة + one: حوالي 1 ساعة + two: حوالي %{count} ساعة + few: حوالي %{count} ساعة + many: حوالي %{count} ساعة + other: حوالي %{count} ساعة + about_x_months: + zero: حوالي %{count} شهر + one: حوالي 1 شهر + two: حوالي %{count} شهر + few: حوالي %{count} شهر + many: حوالي %{count} شهر + other: حوالي %{count} شهر + about_x_years: + zero: حوالي %{count} سنوات + one: حوالي سنة واحدة + two: حوالي %{count} سنوات + few: حوالي %{count} سنوات + many: حوالي %{count} سنوات + other: حوالي %{count} سنوات + almost_x_years: + zero: تقريبا %{count} سنوات + one: ما يقرب من 1 سنة + two: تقريبا %{count} سنوات + few: تقريبا %{count} سنوات + many: تقريبا %{count} سنوات + other: تقريبا %{count} سنوات + half_a_minute: نصف دقيقة + less_than_x_seconds: + zero: أقل من %{count} ثانية + one: أقل من ثانية واحدة + two: أقل من %{count} ثانية + few: أقل من %{count} ثانية + many: أقل من %{count} ثانية + other: أقل من %{count} ثانية + less_than_x_minutes: + zero: أقل من %{count} دقيقة + one: أقل من دقيقة + two: أقل من %{count} دقيقة + few: أقل من %{count} دقيقة + many: أقل من %{count} دقيقة + other: أقل من %{count} دقيقة + over_x_years: + zero: أكثر من %{count} سنة + one: أكثر من 1 سنة + two: أكثر من %{count} سنة + few: أكثر من %{count} سنة + many: أكثر من %{count} سنة + other: أكثر من %{count} سنة + x_seconds: + zero: "%{count} ثانية" + one: "1 ثانية" + two: "%{count} ثانية" + few: "%{count} ثانية" + many: "%{count} ثانية" + other: "%{count} ثانية" + x_minutes: + zero: "%{count} دقيقة" + one: "1 دقيقة" + two: "%{count} دقيقة" + few: "%{count} دقيقة" + many: "%{count} دقيقة" + other: "%{count} دقيقة" + x_days: + zero: "%{count} أيام" + one: "يوم 1" + two: "%{count} أيام" + few: "%{count} أيام" + many: "%{count} أيام" + other: "%{count} أيام" + x_months: + zero: "%{count} شهور" + one: "شهر واحد" + two: "%{count} شهور" + few: "%{count} شهور" + many: "%{count} شهور" + other: "%{count} شهور" + x_years: + zero: "%{count} سنة" + one: "سنة واحدة" + two: "%{count} سنة" + few: "%{count} سنة" + many: "%{count} سنة" + other: "%{count} سنوات" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index f95db03692..71daf108af 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -85,6 +85,11 @@ ca: no_default_card: "^ No hi ha cap targeta predeterminada disponible per a aquesta consumidora" shipping_method: not_available_to_shop: "no està disponible per %{shop}" + card_details: "Dades de la targeta" + card_type: "Tipus de targeta" + cardholder_name: "Nom del titular de la targeta" + community_forum_url: "URL del fòrum de la comunitat" + customer_instructions: "Instruccions de la consumidora" devise: confirmations: send_instructions: "Rebreu un correu electrònic amb instruccions sobre com confirmar el vostre compte en pocs minuts." @@ -114,11 +119,39 @@ ca: updated_not_active: "La vostra contrasenya s'ha restablert, però el vostre correu electrònic encara no s'ha confirmat." updated: "La vostra contrasenya s'ha canviat correctament. Ja teniu la sessió iniciada." send_instructions: "Rebreu un correu electrònic amb instruccions sobre com confirmar el vostre compte en pocs minuts." + home_page_alert_html: "HTML banner d'alerta de la pàgina d'inici" + hub_signup_case_studies_html: "HTML casos d'estudi de hub" + hub_signup_detail_html: "HTML detall del registre de hub" + hub_signup_pricing_table_html: "HTML taula de preus de registre de hub" + group_signup_case_studies_html: "HTML casos d'estudi d’inscripció de grup" + group_signup_detail_html: "HTML informació detallada de registre de grup" + group_signup_pricing_table_html: "HTML taula de preus d'inscripció de grup" + item_description: "Descripció de l'article" + menu_1_icon_name: "Nom de la icona del menú 1" + menu_2_icon_name: "Nom de la icona del menú 2" + menu_3_icon_name: "Nom de la icona del menú 3" + menu_4_icon_name: "Nom de la icona del menú 4" + menu_5_icon_name: "Nom de la icona del menú 5" + menu_6_icon_name: "Nom de la icona del menú 6" + menu_7_icon_name: "Nom de la icona del menú 7" models: order_cycle: cloned_order_cycle_name: "CÒPIA DE %{order_cycle}" tax_rate: included_in_price: "Inclòs en el preu" + open_street_map_enabled: "S'ha activat Open Street Map" + open_street_map_default_latitude: "latitud predeterminada d'Open Street Map" + open_street_map_default_longitude: "longitud predeterminada d'Open Street Map" + open_street_map_provider_name: "nom del proveïdor d'Open Street Map" + open_street_map_provider_options: "opcions del proveïdor d'Open Street Map" + producer_signup_case_studies_html: "HTML estudis de casos de productora" + producer_signup_detail_html: "HTML detall del registre de la productora" + producer_signup_pricing_table_html: "HTML taula de preus d'inscripció de la productora" + producers_social: "Raó social de la productora" + resume_order: "Reprèn la comanda" + sku: "Número de referència (SKU)" + subtotal: "Subtotal" + tax_rate: "Taxa d'impost" validators: date_time_string_validator: not_string_error: "ha de ser una seqüència" @@ -144,6 +177,7 @@ ca: producer_mailer: order_cycle: subject: "Informe del cicle de comanda per %{producer}" + provider_settings: "Configuració del proveïdor" shipment_mailer: shipped_email: dear_customer: "Benvolguda consumidora:" @@ -264,7 +298,7 @@ ca: error: Error processing_payment: "S'està processant el pagament..." no_pending_payments: "No hi ha pagaments pendents" - invalid_payment_state: "Estat de pagament no vàlid" + invalid_payment_state: "Estat de pagament invàlid: %{state}" filter_results: Aplicar filtre quantity: Quantitat pick_up: Recollida @@ -298,8 +332,12 @@ ca: destroy: "Eliminar" rename: "Reanomenar" admin: + adjustments: + skipped_changing_canceled_order: "No podeu canviar una comanda cancel·lada." begins_at: Comença a begins_on: Comença + bill_address: "Adreça de factura" + ship_address: "Adreça d'enviament" customer: Consumidora date: Data email: E-mail @@ -1067,6 +1105,7 @@ ca: index: title: "Subscripcions" new: "Nova subscripció" + issue: "Incidència" new: title: "Nova subscripció" edit: @@ -1148,6 +1187,7 @@ ca: yes_cancel_them: Cancel·lar-les no_keep_them: Conservar-les yes_i_am_sure: Sí, n'estic segur + number: "Número" order_update_issues_msg: Algunes comandes no s'han pogut actualitzar automàticament, probablement perquè s'han editat manualment. Reviseu els problemes que es detallen a continuació i realitzeu els ajustaments a comandes individuals si és necessari. no_results: no_subscriptions: Encara no hi ha cap subscripció... @@ -1180,8 +1220,10 @@ ca: message_html: "Accepto el %{terms_and_conditions_link} del venedor." link_text: "Termes i condicions" platform_terms_of_service: + message_html: "Accepto els %{tos_link} de la plataforma." terms_of_service: "Termes del servei" all_terms_and_conditions: + message_html: "Accepto el %{terms_and_conditions_link} del venedor i la plataforma %{tos_link}." terms_and_conditions: "Termes i condicions" terms_of_service: "Termes del servei" failed: "La comanda ha fallat. Informeu-nos perquè puguem processar la vostra comanda." @@ -1573,7 +1615,9 @@ ca: shopping_tabs_home: "Inici" shopping_tabs_shop: "Botiga" shopping_tabs_about: "Sobre" + shopping_tabs_producers: "Productors" shopping_tabs_contact: "Contacte" + shopping_tabs_groups: "Xarxes/Grups" shopping_contact_address: "Adreça" shopping_contact_web: "Contacte" shopping_contact_social: "Segueix" @@ -1725,39 +1769,40 @@ ca: shops_signup_help: Estem preparadess per ajudar. shops_signup_help_text: Necessites un millor retorn. Necessites noves compradores i sòcies logístiques. Necessites la teva història explicada a través de majoristes, minoristes i de la taula de la cuina. shops_signup_detail: Aquest és el detall. - orders: Comandes - orders_fees: Comissions... - orders_edit_title: Cistella de la compra - orders_edit_headline: El teu cistell de la compra - orders_edit_time: Comanda llesta per - orders_edit_continue: Continuar comprant - orders_edit_checkout: Realitza la compra + orders: "Comandes" + orders_fees: "Comissions..." + orders_edit_title: "Cistella de la compra" + orders_edit_headline: "El teu cistell de la compra" + orders_edit_time: "Comanda llesta per" + orders_edit_continue: "Continuar comprant" + orders_edit_checkout: "Realitza la compra" orders_form_empty_cart: "Cistella buida" - orders_form_subtotal: Subtotal - orders_form_admin: Administració i manipulació - orders_form_total: Total - orders_oc_expired_headline: S'han tancat les comandes per a aquest cicle de comanda + orders_form_update_cart: "Actualitzar" + orders_form_subtotal: "Subtotal" + orders_form_admin: "Administració i manipulació" + orders_form_total: "Total" + orders_oc_expired_headline: "S'han tancat les comandes per a aquest cicle de comanda" orders_oc_expired_text: "Ho sentim, les comandes d'aquest cicle de comanda es van tancar fa %{time} ! Posa't en contacte amb el teu grup directament per veure si poden acceptar comandes fora de temps." orders_oc_expired_text_others_html: "Ho sentim, les comandes d'aquest cicle de comanda es van tancar fa %{time} ! Posa't en contacte amb el teu grup directament per veure si poden acceptar comandes fora de temps %{link} ." orders_oc_expired_text_link: "o consulta els altres cicles de comanda disponibles en aquest grup" orders_oc_expired_email: "Correu electrònic:" orders_oc_expired_phone: "Telèfon:" - orders_show_title: Confirmació de la comanda - orders_show_time: Comanda preparada + orders_show_title: "Confirmació de la comanda" + orders_show_time: "Comanda preparada" orders_show_order_number: "Comanda # %{number}" - orders_show_cancelled: Cancel·lada - orders_show_confirmed: Confirmada + orders_show_cancelled: "Cancel·lada" + orders_show_confirmed: "Confirmada" orders_your_order_has_been_cancelled: "S'ha cancel·lat la teva comanda" orders_could_not_cancel: "Disculpa, no s'ha pogut cancel·lar la teva comanda " orders_cannot_remove_the_final_item: "No es pot eliminar l'article final d'una comanda, si us plau, en comptes d'això cancel·leu la comanda." orders_bought_items_notice: - one: Ja s'ha confirmat un article addicional per a aquest cicle de comanda + one: "Ja s'ha confirmat un article addicional per a aquest cicle de comanda" few: "%{count}articles addicionals confirmats per a aquest cicle de comandes" many: "%{count}articles addicionals confirmats per a aquest cicle de comandes" other: "%{count}articles addicionals confirmats per a aquest cicle de comandes" - orders_bought_edit_button: Edita articles confirmats + orders_bought_edit_button: "Edita articles confirmats" orders_bought_already_confirmed: "* ja confirmat" - orders_confirm_cancel: Estàs segur que vols cancel·lar aquesta comanda? + orders_confirm_cancel: "Estàs segur que vols cancel·lar aquesta comanda?" order_processed_successfully: "La teva comanda s'ha processat amb èxit" products_cart_distributor_choice: "Distribuïdora de la teva comanda:" products_cart_distributor_change: "La teva distribuïdora d'aquesta comanda canviarà a %{name} si afegeixes aquest producte a la teva cistella." @@ -2416,6 +2461,7 @@ ca: S'ha produït un problema en afegir aquest producte a la cistella. Potser ha deixat d'estar disponible o la botiga a tancat. admin: + unit_price_tooltip: "El preu unitari augmenta la transparència, ja que permet als vostres clients comparar fàcilment preus entre diferents productes i mides d’envàs. Tingueu en compte que el preu unitari final que es mostra a l’aparador pot variar ja que inclou impostos i taxes." enterprise_limit_reached: "Has assolit el límit estàndard d'organitzacions per compte. Escriu a %{contact_email} si necessites augmentar-lo." modals: got_it: "Ho tinc" @@ -2810,6 +2856,15 @@ ca: start_free_profile: "Comença amb un perfil gratuït i amplia'l quan estiguis preparada." order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Compra grupal - Assignació" + bulk_coop_customer_payments: "Compra grupal - Pagaments de les consumidores" + bulk_coop_packing_sheets: "Compra grupal - Fulls de preparació de cistelles" + bulk_coop_supplier_report: "Compra grupal - Totals per proveïdor" + date_range: "Interval de dates" + generate_report: "Generar informe" + report_format_csv: "Descarrega com a CSV" enterprise_fee_summaries: filters: date_range: "Interval de dates" @@ -2855,6 +2910,8 @@ ca: tax_category_name: "Categoria d'impostos" total_amount: "€€ SUM" invalid_filter_parameters: "Els filtres que heu seleccionat per a aquest informe no són vàlids." + report: + none: "Cap" order: "Comanda" distribution: "Distribució" order_details: "Detalls de la comanda" @@ -2887,7 +2944,54 @@ ca: previous: "Anterior" last: "Últim" spree: + add_country: "Afegeix país" + add_state: "Afegeix estat" + adjustment: "Ajustament" + all: "Tots" + associated_adjustment_closed: "S'ha tancat l'ajustament associat" + authorization_failure: "Error d'autorització" + back_to_adjustments_list: "Torna als ajustaments" + back_to_users_list: "Tornar als usuaris" + back_to_zones_list: "Tornar a zones" + card_code: "Codi de la targeta" + card_number: "Número de targeta" + category: "Categoria" + created_successfully: "Creat correctament" + credit: "Crèdit" + editing_tax_category: "Editant la categoria fiscal" + editing_tax_rate: "Editant el tipus impositiu" + editing_zone: "Editant zona" + expiration: "Caducitat" + invalid_payment_provider: "Proveïdor de pagaments invàlid" + items_cannot_be_shipped: "Els articles no es poden enviar" + gateway_config_unavailable: "La configuració de la passarel·la no està disponible" + gateway_error: "El pagament ha fallat" more: "Més" + new_adjustment: "Nou ajustament" + new_order_completed: "S'ha completat la nova comanda" + new_tax_category: "Nova categoria fiscal" + new_taxon: "Nou tàxon" + new_user: "Nou usuari" + no_pending_payments: "No hi ha pagaments pendents" + none: "Cap" + not_found: "No trobat" + notice_messages: + variant_deleted: "Variant eliminada" + or: "O bé" + order_processed_successfully: "La comanda s'ha processat correctament" + payment_method_not_supported: "No s'admet la forma de pagament" + resend_authorization_email: "Torneu a enviar el correu electrònic d’autorització" + rma_credit: "credit RMA" + server_error: "Error del servidor" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Data d'inici" + successfully_removed: "S'ha suprimit correctament" + taxonomy_edit: "Edició de taxonomia" + taxonomy_tree_error: "Error d'arbre de taxonomia" + taxonomy_tree_instruction: "Instrucció d'arbre de taxonomia" + tree: "Arbre" + updating: "Actualitzant" your_order_is_empty_add_product: "La comanda està buida, si us plau cerca i afegeix un producte a dalt" add_product: "Afegeix un producte" name_or_sku: "Nom o codi (introduïu com a mínim els primers 4 caràcters del nom del producte)" @@ -2915,6 +3019,7 @@ ca: tracking_number: "Número de seguiment" order_total: "Total comanda" customer_details: "Detalls de la consumidora" + customer_details_updated: "S'han actualitzat les dades de la consumidora" customer_search: "Cerca la consumidora" choose_a_customer: "Tria una consumidora" account: "Compte" @@ -3065,6 +3170,8 @@ ca: payment_method: "Mètode de pagament" payment_processing_failed: "El pagament no s'ha pogut processar, comproveu les dades que heu introduït" not_available: "No disponible" + sku: "Número de referència (SKU)" + there_are_no_items_for_this_order: "No hi ha articles per a aquesta comanda." order_populator: out_of_stock: '%{item} està esgotat.' actions: @@ -3092,7 +3199,17 @@ ca: login_nav: header: store: Botiga + validation: + must_be_int: "ha de ser un nombre enter" admin: + mail_methods: + send_testmail: "Enviar correu electrònic de prova" + testmail: + delivery_success: "S'ha enviat el correu electrònic de prova." + error: "S'ha produït un error en intentar enviar el correu electrònic de prova." + unit_price_tooltip: "El preu unitari augmenta la transparència, ja que permet als vostres clients comparar fàcilment preus entre diferents productes i mides d’envàs. Tingueu en compte que el preu unitari final que es mostra a l’aparador pot variar ja que inclou impostos i taxes." + subscriptions: + number: "Número" tab: dashboard: "Panell" orders: "Comandes" @@ -3161,6 +3278,8 @@ ca: received: "Rebut" canceled: "Cancel·lat" orders: + add_product: + cannot_add_item_to_canceled_order: "No es pot afegir l'article a la comanda cancel·lada" index: listing_orders: "Llistat comandes" new_order: "Nova comanda" @@ -3203,6 +3322,10 @@ ca: overview: enterprises_header: ofn_with_tip: Les organitzacions són productores i/o grups de consum i són la unitat bàsica d'organització dins d'Open Food Network. + enterprise_row: + has_no_enterprise_fees: "no té comissions d'organització" + has_no_payment_methods: "no té mètodes de pagament" + has_no_shipping_methods: "no té mètodes d'enviament" products: active_products: zero: "No tens cap producte actiu." @@ -3241,6 +3364,7 @@ ca: back_to_shipping_methods_list: "Tornar al llistat de mètodes d'enviament" form: categories: "Categories" + tax_category: "Categoria d'impostos" zones: "Zones" both: "Comandes com administració" back_end: "Només pàgina administració (back office) " @@ -3321,6 +3445,8 @@ ca: value: "Valor" unit_name: "Nom de la unitat" price: "Preu" + unit_price: "Preu unitari" + unit_price_legend: "Calculat en funció del preu de l'article" on_hand: "Disponibles" on_demand: "Sota demanda" product_description: "Descripció del producte" @@ -3391,7 +3517,6 @@ ca: price: "Preu" options: "Opcions" no_results: "Sense resultats" - to_add_variants_you_must_first_define: "Per afegir variants, primer heu de definir" option_types: "Tipus d'opcions" option_values: "Valors d’opció" and: "i" @@ -3403,6 +3528,7 @@ ca: form: sku: "Número de referència (SKU)" price: "Preu" + unit_price: "Preu unitari" display_as: "Mostra com" display_name: "Nom de visualització" display_as_placeholder: 'per exemple. 2 kg' @@ -3426,6 +3552,7 @@ ca: cookies_consent_banner_toggle: "Mostra banner de consentiment de cookies" privacy_policy_url: "URL de la política de privacitat " enterprises_require_tos: "Les organitzacions han d'acceptar les condicions del servei" + shoppers_require_tos: "Els compradors han d’acceptar les condicions del servei" cookies_policy_matomo_section: "Mostra la secció de Matomo a la pàgina de política de cookies" footer_tos_url: "URL de les condicions d'ús" checkout: @@ -3638,3 +3765,42 @@ ca: spree/payment: one: Pagament other: Pagaments + datetime: + distance_in_words: + about_x_hours: + one: aproximadament 1 hora + other: aprox. %{count} hores + about_x_months: + one: aproximadament 1 mes + other: aprox. %{count} mesos + about_x_years: + one: aproximadament 1 any + other: aprox. %{count} anys + almost_x_years: + one: gairebé 1 any + other: gairebé %{count} anys + half_a_minute: mig minut + less_than_x_seconds: + one: menys d'1 segon + other: menys de %{count} segons + less_than_x_minutes: + one: menys d’un minut + other: menys de %{count} minuts + over_x_years: + one: més d’un any + other: més de %{count} anys + x_seconds: + one: "1 segon" + other: "%{count} segons" + x_minutes: + one: "1 minut" + other: "%{count} minuts" + x_days: + one: "1 dia" + other: "%{count} dies" + x_months: + one: "1 mes" + other: "%{count} mesos" + x_years: + one: "1 any" + other: "%{count} anys" diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 0247ec01ea..01d11e3152 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -85,6 +85,7 @@ cy: no_default_card: "^ Nid oes cerdyn diofyn ar gael i'r cwsmer hwn" shipping_method: not_available_to_shop: "ddim ar gael i %{shop}" + customer_instructions: "Cyfarwyddiadau cwsmeriaid" devise: confirmations: send_instructions: "Byddwch yn derbyn e-bost gyda chyfarwyddiadau ar sut i gadarnhau eich cyfrif mewn ychydig funudau." @@ -117,6 +118,8 @@ cy: models: order_cycle: cloned_order_cycle_name: "COPI %{order_cycle}" + sku: "SKU" + tax_rate: "Gyfradd dreth" validators: date_time_string_validator: not_string_error: "rhaid iddo fod yn llinyn" @@ -262,7 +265,6 @@ cy: error: Gwall processing_payment: "Prosesu taliad ..." no_pending_payments: "Dim taliadau yn yr arfaeth" - invalid_payment_state: "Cyflwr talu annilys" filter_results: Canlyniadau Hidlo quantity: Nifer pick_up: Codi @@ -1143,6 +1145,7 @@ cy: yes_cancel_them: Canslo nhw no_keep_them: Cadwch nhw yes_i_am_sure: Ydw, rwy'n siŵr + number: "Rhif" order_update_issues_msg: Ni ellid diweddaru rhai archebion yn awtomatig, mae hyn yn fwyaf tebygol oherwydd eu bod wedi'u golygu â llaw. Adolygwch y materion a restrir isod a gwnewch unrhyw addasiadau i archebion unigol os oes angen. no_results: no_subscriptions: Dim tanysgrifiadau eto ... @@ -1563,7 +1566,9 @@ cy: shopping_tabs_home: "Hafan" shopping_tabs_shop: "Siop" shopping_tabs_about: "Am" + shopping_tabs_producers: "Cynhyrchwyr" shopping_tabs_contact: "Cysylltwch" + shopping_tabs_groups: "Grwpiau" shopping_contact_address: "Cyfeiriad" shopping_contact_web: "Cysylltwch" shopping_contact_social: "Dilynwch" @@ -1714,39 +1719,40 @@ cy: shops_signup_help: Rydyn ni'n barod i helpu. shops_signup_help_text: Mae angen gwell dychweliad arnoch chi. Mae angen prynwyr a phartneriaid logisteg newydd arnoch chi. Mae angen i'ch stori gael ei hadrodd ar draws cyfanwerth, manwerthu a bwrdd y gegin. shops_signup_detail: Dyma'r manylion. - orders: Gorchmynion - orders_fees: Ffioedd ... - orders_edit_title: Cart Siopa - orders_edit_headline: Eich trol siopa - orders_edit_time: Archeb yn barod ar gyfer - orders_edit_continue: Parhewch i siopa - orders_edit_checkout: Til + orders: "Gorchmynion" + orders_fees: "Ffioedd ..." + orders_edit_title: "Cart Siopa" + orders_edit_headline: "Eich trol siopa" + orders_edit_time: "Archeb yn barod ar gyfer" + orders_edit_continue: "Parhewch i siopa" + orders_edit_checkout: "Til" orders_form_empty_cart: "Cart gwag" - orders_form_subtotal: Cynhyrchu subtotal - orders_form_admin: Gweinyddiaeth a Thrin - orders_form_total: Cyfanswm - orders_oc_expired_headline: Mae archebion wedi cau ar gyfer y cylch archebu hwn + orders_form_update_cart: "Diweddariad" + orders_form_subtotal: "Cynhyrchu subtotal" + orders_form_admin: "Gweinyddiaeth a Thrin" + orders_form_total: "Cyfanswm" + orders_oc_expired_headline: "Mae archebion wedi cau ar gyfer y cylch archebu hwn" orders_oc_expired_text: "Mae'n ddrwg gennym, caeodd archebion ar gyfer y cylch archebu hwn %{time} yn ôl! Cysylltwch â'ch canolbwynt yn uniongyrchol i weld a allan nhw dderbyn archebion hwyr." orders_oc_expired_text_others_html: "Mae'n ddrwg gennym, caeodd archebion ar gyfer y cylch archebu hwn %{time} yn ôl! Cysylltwch â'ch canolbwynt yn uniongyrchol i weld a allan nhw dderbyn archebion hwyr %{link} ." orders_oc_expired_text_link: "neu gwelwch y cylchoedd archebu eraill sydd ar gael yn y canolbwynt hwn" orders_oc_expired_email: "E-bost:" orders_oc_expired_phone: "Ffôn:" - orders_show_title: Cadarnhad Gorchymyn - orders_show_time: Archeb yn barod ymlaen + orders_show_title: "Cadarnhad Gorchymyn" + orders_show_time: "Archeb yn barod ymlaen" orders_show_order_number: "Gorchymyn # %{number}" - orders_show_cancelled: Wedi'i ganslo - orders_show_confirmed: Cadarnhawyd + orders_show_cancelled: "Wedi'i ganslo" + orders_show_confirmed: "Cadarnhawyd" orders_your_order_has_been_cancelled: "Mae eich archeb wedi'i ganslo" orders_could_not_cancel: "Mae'n ddrwg gennym, ni ellid canslo'r gorchymyn" orders_cannot_remove_the_final_item: "Ni all dynnu’r eitem olaf o orchymyn, canslwch yr archeb yn lle." orders_bought_items_notice: - one: Mae eitem ychwanegol eisoes wedi'i chadarnhau ar gyfer y cylch archebu hwn + one: "Mae eitem ychwanegol eisoes wedi'i chadarnhau ar gyfer y cylch archebu hwn" few: "%{count} eitemau ychwanegol a gadarnhawyd eisoes ar gyfer y cylch archebu hwn" many: "%{count} eitemau ychwanegol a gadarnhawyd eisoes ar gyfer y cylch archebu hwn" other: "%{count} eitemau ychwanegol a gadarnhawyd eisoes ar gyfer y cylch archebu hwn" - orders_bought_edit_button: Golygu eitemau wedi'u cadarnhau + orders_bought_edit_button: "Golygu eitemau wedi'u cadarnhau" orders_bought_already_confirmed: "* wedi'i gadarnhau eisoes" - orders_confirm_cancel: Ydych chi'n siŵr eich bod chi am ganslo'r gorchymyn hwn? + orders_confirm_cancel: "Ydych chi'n siŵr eich bod chi am ganslo'r gorchymyn hwn?" order_processed_successfully: "Mae eich archeb wedi'i phrosesu'n llwyddiannus" products_cart_distributor_choice: "Dosbarthwr ar gyfer eich archeb:" products_cart_distributor_change: "Bydd eich dosbarthwr ar gyfer y gorchymyn hwn yn cael ei newid i %{name} os ychwanegwch y cynnyrch hwn at eich trol." @@ -2838,6 +2844,9 @@ cy: start_free_profile: "Dechreuwch gyda phroffil am ddim, ac ehangwch pan fyddwch chi'n barod!" order_management: reports: + bulk_coop: + filters: + generate_report: "Cynhyrchu Adroddiad" enterprise_fee_summaries: filters: date_range: "Ystod Dyddiad" @@ -2883,6 +2892,8 @@ cy: tax_category_name: "Categori Treth" total_amount: "SUM $ $" invalid_filter_parameters: "Mae'r hidlwyr a ddewisoch ar gyfer yr adroddiad hwn yn annilys." + report: + none: "Dim" order: "Gorchymyn" distribution: "Dosbarthiad" order_details: "Manylion y Gorchymyn" @@ -2915,7 +2926,13 @@ cy: previous: "Blaenorol" last: "Diwethaf" spree: + all: "I gyd" + category: "Categori" + credit: "Credyd" more: "Mwy" + no_pending_payments: "Dim taliadau yn yr arfaeth" + none: "Dim" + updating: "Diweddaru" your_order_is_empty_add_product: "Mae eich archeb yn wag, chwiliwch am ac ychwanegwch gynnyrch uchod" add_product: "Ychwanegu Cynnyrch" name_or_sku: "Enw neu SKU (nodwch o leiaf 4 nod cyntaf enw'r cynnyrch)" @@ -3091,6 +3108,7 @@ cy: payment_method: "Dull talu" payment_processing_failed: "Ni ellid prosesu taliad, gwiriwch y manylion a nodwyd gennych" not_available: "Amherthnasol" + sku: "SKU" order_populator: out_of_stock: 'mae %{item} allan o stoc.' actions: @@ -3118,6 +3136,8 @@ cy: header: store: Storfa admin: + subscriptions: + number: "Rhif" tab: dashboard: "Dangosfwrdd" orders: "Gorchmynion" @@ -3266,6 +3286,7 @@ cy: back_to_shipping_methods_list: "Yn ôl i'r Rhestr Dulliau Llongau" form: categories: "Categorïau" + tax_category: "Categori Treth" zones: "Parthau" both: "Checkout a Swyddfa Gefn" back_end: "Swyddfa gefn yn unig" @@ -3339,6 +3360,7 @@ cy: value: "Gwerth" unit_name: "Enw'r uned" price: "Pris" + unit_price: "Pris Uned" on_hand: "Wrth Law" on_demand: "Ar alw" product_description: "Disgrifiad o'r Cynnyrch" @@ -3409,7 +3431,6 @@ cy: price: "Pris" options: "Opsiynau" no_results: "Dim canlyniadau" - to_add_variants_you_must_first_define: "I ychwanegu amrywiadau, rhaid i chi ddiffinio yn gyntaf" option_types: "Mathau Opsiwn" option_values: "Gwerthoedd Opsiwn" and: "a" @@ -3421,6 +3442,7 @@ cy: form: sku: "SKU" price: "Pris" + unit_price: "Pris Uned" display_as: "Arddangos Fel" display_name: "Enw Arddangos" display_as_placeholder: 'ee. 2 kg' diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index db645ba075..a371907184 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -85,13 +85,18 @@ de_DE: no_default_card: "^ Für diesen Kunden ist keine Standardkreditkarte verfügbar." shipping_method: not_available_to_shop: "ist nicht verfügbar für %{shop}" + card_details: "Kreditkartendaten" + card_type: "Kreditkartentyp" + cardholder_name: "Kreditkarteninhaber" + community_forum_url: "URL des Community-Forums" + customer_instructions: "Informationen für Kunden" devise: confirmations: send_instructions: "Sie erhalten in Kürze eine E-Mail mit Anweisungen zur Bestätigung Ihres Kontos." failed_to_send: "Beim Senden der E-Mail-Bestätigung ist ein Fehler aufgetreten." resend_confirmation_email: "E-Mail-Bestätigung erneut senden." confirmed: "Danke für die Bestätigung Ihrer E-Mail-Adresse! Sie können sich jetzt einloggen." - not_confirmed: "Ihre E-Mail-Adresse konnte nicht bestätigt werden. Haben Sie diesen Schritt vielleicht bereits abgeschlossen?" + not_confirmed: "Ihre E-Mail-Adresse konnte nicht bestätigt werden. Möglicherweise haben Sie diesen Schritt bereits abgeschlossen. Bitte versuchen Sie sich einzuloggen oder wählen Sie \"Passwort vergessen?\"." user_confirmations: spree_user: send_instructions: "Sie erhalten in Kürze eine E-Mail mit Anweisungen zur Bestätigung Ihres Kontos." @@ -99,7 +104,7 @@ de_DE: confirmation_not_sent: "Fehler beim Senden der E-Mail-Bestätigung" user_registrations: spree_user: - signed_up_but_unconfirmed: "Eine Nachricht mit einem Bestätigungslink wurde an Ihre E-Mail-Adresse gesendet. Bitte öffnen Sie den Link, um Ihr Konto zu aktivieren." + signed_up_but_unconfirmed: "Eine Nachricht mit einem Bestätigungslink wurde an Ihre E-Mail-Adresse gesendet. Bitte öffnen Sie den Link, um Ihr Konto zu aktivieren. Sollten Sie die E-Mail nach einigen Minuten nicht erhalten haben, schauen Sie bitte in Ihrem Spam-Ordner nach." unknown_error: "Beim Erstellen Ihres Kontos ist ein Fehler aufgetreten. Überprüfen Sie Ihre E-Mail-Adresse und versuchen Sie es erneut." failure: invalid: | @@ -114,11 +119,39 @@ de_DE: updated_not_active: "Ihr Passwort wurde zurückgesetzt, aber ihre E-Mail-Adresse muss noch bestätigt werden." updated: "Ihr Kennwort wurde erfolgreich geändert. Sie sind jetzt angemeldet." send_instructions: "Sie erhalten in Kürze eine E-Mail mit Anweisungen zur Bestätigung Ihres Kontos." + home_page_alert_html: "Startseite Banner HTML" + hub_signup_case_studies_html: "Registrierung für Läden - Beispiele HTML" + hub_signup_detail_html: "Registrierung für Läden - Details HTML" + hub_signup_pricing_table_html: "Registrierung für Läden - Preistabelle HTML" + group_signup_case_studies_html: "Registrierung für Gruppen - Beispiele HTML" + group_signup_detail_html: "Registrierung für Gruppen - Details HTML" + group_signup_pricing_table_html: "Registrierung für Gruppen - Preistabelle HTML" + item_description: "Artikelbeschreibung" + menu_1_icon_name: "Icon Hauptmenü Eintrag 1" + menu_2_icon_name: "Icon Hauptmenü Eintrag 2" + menu_3_icon_name: "Icon Hauptmenü Eintrag 3" + menu_4_icon_name: "Icon Hauptmenü Eintrag 4" + menu_5_icon_name: "Icon Hauptmenü Eintrag 5" + menu_6_icon_name: "Icon Hauptmenü Eintrag 6" + menu_7_icon_name: "Icon Hauptmenü Eintrag 7" models: order_cycle: cloned_order_cycle_name: "Kopie von %{order_cycle}" tax_rate: included_in_price: "im Preis inbegriffen" + open_street_map_enabled: "Open Street Map aktivieren" + open_street_map_default_latitude: "Open Street Map Standardbreitengrad" + open_street_map_default_longitude: "Open Street Map Standardlängengrad" + open_street_map_provider_name: "Open Street Map Anbieter" + open_street_map_provider_options: "Open Street Map Anbieteroptionen" + producer_signup_case_studies_html: "Registrierung für Produzenten - Beispiele HTML" + producer_signup_detail_html: "Registrierung für Produzenten - Details HTML" + producer_signup_pricing_table_html: "Registrierung für Produzenten - Preistabelle HTML" + producers_social: "Soziale Medien" + resume_order: "Abonnement fortsetzen" + sku: "Artikelnummer" + subtotal: "Zwischensumme" + tax_rate: "Steuersatz" validators: date_time_string_validator: not_string_error: "muss eine Zeichenfolge sein" @@ -128,22 +161,23 @@ de_DE: invalid_element_error: "darf nur ganze Zahlen enthalten" enterprise_mailer: confirmation_instructions: - subject: "Bitte bestätigen Sie die E-Mail-Adresse von %{enterprise} im Open Food Network DE" + subject: "Bitte bestätigen Sie die E-Mail-Adresse von %{enterprise} im Open Food Network" welcome: - subject: "%{enterprise} ist jetzt auf %{sitename}" + subject: "%{enterprise} ist jetzt im Open Food Network" email_welcome: "Willkommen" email_registered: "ist jetzt Teil des" email_userguide_html: "Das Benutzerhandbuch mit detaillierter Unterstützung für die Einrichtung Ihres Profils, Produzentenladens oder Hubs finden Sie hier: %{link}" userguide: "Open Food Network Benutzerhandbuch" email_admin_html: "Sie können Ihr Konto verwalten, indem Sie direkt den Link %{link} verwenden oder indem Sie sich auf der Startseite einloggen und im Menü \"Verwaltung\" auswählen." admin_panel: "Verwaltung" - email_community_html: "Wir haben auch ein Online-Forum für Diskussionen innerhalb der Community zuden Themen OFN-Software, Herausforderungen eines Lebensmittelunternehmens und mehr. Reden Sie doch mit. Wir entwickeln uns ständig weiter und mit Ihrem Beitrag in diesem Forum bestimmen Sie mit, was als nächstes passiert. %{link}" + email_community_html: "Wir haben auch ein Online-Forum für Diskussionen innerhalb der Community zu den Themen Open Food Network Software, Herausforderungen eines Lebensmittelunternehmens und mehr. Reden Sie doch mit. Wir entwickeln uns ständig weiter und mit Ihrem Beitrag in diesem Forum bestimmen Sie mit, was als nächstes passiert. %{link}" join_community: "Jetzt Teil der Community werden!" invite_manager: subject: "%{enterprise} hat Sie eingeladen, ein Manager zu sein" producer_mailer: order_cycle: subject: "Bestellzyklusbericht für %{producer}" + provider_settings: "Anbietereinstellungen" shipment_mailer: shipped_email: dear_customer: "Liebe Kundin, lieber Kunde," @@ -177,7 +211,7 @@ de_DE: title: Kein Lagerbestand (%{count} Bestellungen) explainer: Diese Bestellungen konnten nicht verarbeitet werden, da für die bestellten Artikel leider kein Lagerbestand verfügbar war. complete: - title: Bereits bearbeitet (%{count} Bestellungen) + title: Bereits verarbeitet (%{count} Bestellungen) explainer: Diese Bestellungen wurden bereits als vollständig markiert und daher nicht verändert. processing: title: Fehler aufgetreten (%{count} Bestellungen) @@ -264,7 +298,7 @@ de_DE: error: Fehler processing_payment: "Bezahlung wird verarbeitet ..." no_pending_payments: "Keine ausstehenden Zahlungen." - invalid_payment_state: "Ungültiger Zahlungsstatus" + invalid_payment_state: "Ungültiger Zahlungsstatus: %{state}" filter_results: Suchen quantity: Menge pick_up: Abholen @@ -298,8 +332,12 @@ de_DE: destroy: "Löschen" rename: "Umbenennen" admin: + adjustments: + skipped_changing_canceled_order: "Eine stornierte Bestellung kann nicht geändert werden." begins_at: Beginnt begins_on: Beginnt am + bill_address: "Rechnungsadresse" + ship_address: "Lieferadresse" customer: Kunde date: Datum email: E-Mail @@ -422,10 +460,10 @@ de_DE: edit: title: Inhalt header: Kopfzeile - home_page: Homepage + home_page: Startseite producer_signup_page: Registrierung für Produzenten - hub_signup_page: Registrierseite für Hubs - group_signup_page: Registrierung einer Gruppe + hub_signup_page: Registrierung für Läden + group_signup_page: Registrierung für Gruppen main_links: Hauptmenü-Links footer_and_external_links: Fußzeile und externe Links your_content: Ihr Inhalt @@ -802,7 +840,7 @@ de_DE: owner: 'Inhaber' contact: "Kontakt" contact_tip: "Der Manager, der Unternehmens-E-Mails für Bestellungen und Benachrichtigungen erhält. Er muss eine bestätigte E-Mail-Adresse haben." - owner_tip: Der Hauptnutzer, der für dieses Unternehmen verantwortlich ist. + owner_tip: Der Hauptbenutzer, der für dieses Unternehmen verantwortlich ist. notifications: Benachrichtigungen notifications_tip: Benachrichtigungen über Bestellungen werden an diese E-Mail-Adresse gesendet. notifications_placeholder: z. B. lisa@maier.de @@ -861,7 +899,7 @@ de_DE: status: "Status" new_form: owner: Inhaber - owner_tip: Der Hauptnutzer, der für dieses Unternehmen verantwortlich ist. + owner_tip: Der Hauptbenutzer, der für dieses Unternehmen verantwortlich ist. i_am_producer: Ich bin ein Produzent contact_name: Kontaktname edit: @@ -1066,6 +1104,7 @@ de_DE: index: title: "Abonnements" new: "Neues Abonnement" + issue: "Problem" new: title: "Neues Abonnement" edit: @@ -1147,7 +1186,8 @@ de_DE: yes_cancel_them: Stornieren no_keep_them: Erhalten yes_i_am_sure: Ja, ich bin mir sicher. - order_update_issues_msg: Einige Bestellungen konnten nicht automatisch aktualisiert werden. Dies liegt wahrscheinlich daran, dass sie manuell bearbeitet wurden. Bitte überprüfen Sie die unten aufgeführten Punkte und nehmen Sie gegebenenfalls Anpassungen an einzelnen Bestellungen vor. + number: "Bestellnummer" + order_update_issues_msg: Einige Bestellungen konnten nicht automatisch aktualisiert werden. Dies liegt wahrscheinlich daran, dass sie manuell bearbeitet wurden. Bitte überprüfen Sie die unten aufgeführten Probleme und nehmen Sie gegebenenfalls Anpassungen an einzelnen Bestellungen vor. no_results: no_subscriptions: Bisher gibt es noch keine Abonnements. why_dont_you_add_one: Warum fügen Sie nicht einige hinzu? @@ -1178,8 +1218,13 @@ de_DE: terms_and_conditions: message_html: "Ich stimme den %{terms_and_conditions_link} des Verkäufers zu." link_text: "Allgemeinen Geschäftsbedingungen" + platform_terms_of_service: + message_html: "Ich stimme den %{tos_link} des Open Food Network zu." + terms_of_service: "allgemeine Geschäftsbedingungen (AGB)" all_terms_and_conditions: + message_html: "Ich stimme den %{terms_and_conditions_link} des Verkäufers und den %{tos_link} des Open Food Network zu." terms_and_conditions: "Allgemeinen Geschäftsbedingungen" + terms_of_service: "allgemeine Geschäftsbedingungen (AGB)" failed: "Der Bestellabschluss ist fehlgeschlagen. Bitte geben Sie uns Bescheid, damit wir Ihre Bestellung dennoch bearbeiten können." shops: hubs: @@ -1237,7 +1282,7 @@ de_DE: require_login_2_html: "Möchten Sie hier einkaufen? Bitte %{contact} %{enterprise} und fragen Sie nach dem Beitritt." require_customer_html: "Wenn Sie hier einkaufen möchten, fragen Sie bitte %{contact} %{enterprise} nach dem Beitritt." select_oc: - select_oc_html: "Bitte wählen Sie, wann Sie Ihre Bestellung wünschen, um zu sehen, welche Produkte verfügbar sind." + select_oc_html: "Bitte wählen Sie zunächst oben aus, wann Sie Ihre Bestellung erhalten möchten, um die verfügbaren Produkte anzuzeigen." products: summary: bulk: "Gruppenkauf" @@ -1278,14 +1323,14 @@ de_DE: menu_4_url: "/groups" menu_5_title: "Verkaufen" menu_5_url: "https://openfoodnetwork.de/sell" - menu_6_title: "Über uns" + menu_6_title: "Über OFN" menu_6_url: "https://wp.openfoodnetwork.de/" menu_7_title: "Hilfe" menu_7_url: "https://wp.openfoodnetwork.de/support/" logo: "Logo (640x130)" logo_mobile: "Mobile Logo (75x26)" logo_mobile_svg: "Mobile Logo (SVG)" - home_hero: "Heldenbild" + home_hero: "Titelbild" home_show_stats: "Zeige Statistiken" footer_logo: "Logo (220x76)" footer_facebook_url: "Facebook URL" @@ -1409,7 +1454,7 @@ de_DE: cookies_usage: "Diese Website verwendet Cookies, um Ihr Kauferlebnis reibungslos und sicher zu gestalten und um darüber hinaus zu verstehen, wie Sie die Website verwenden, um die von uns angebotenen Funktionen zu verbessern." cookies_definition: "Cookies sind sehr kleine Textdateien, die beim Besuch einiger Websites auf Ihrem Computer gespeichert werden." cookies_desc: "Wir verwenden nur die Cookies, die notwendig sind, um Ihnen den Service des Online-Kaufs/-Verkaufs von Lebensmitteln zu bieten. Wir verkaufen keine Ihrer Daten. Wir verwenden Cookies hauptsächlich, um uns daran zu erinnern, wer Sie sind, wenn Sie sich bei unserem Dienst einloggen, oder um uns die Artikel merken zu können, die Sie in Ihren Warenkorb legen, auch wenn Sie nicht eingeloggt sind. Wenn Sie die Weite nutzen, ohne auf \"Cookies akzeptieren\" zu klicken, nehmen wir an, dass Sie uns die Speicherung von Cookies erlauben, die für das Funktionieren der Website notwendig sind." - cookies_policy_link_desc: "Wenn Sie mehr erfahren möchten, besuchen Sie unsere" + cookies_policy_link_desc: "Wenn Sie mehr erfahren möchten, lesen Sie unsere" cookies_policy_link: "Hinweise zu Cookies" cookies_accept_button: "Cookies akzeptieren" home_shop: Jetzt regional einkaufen @@ -1476,7 +1521,7 @@ de_DE: order_pickup_instructions: Informationen zur Abholung order_produce: Produkte order_total_price: Summe - order_includes_tax: (inkl. Steuern) + order_includes_tax: (enthaltene Steuern) order_payment_paypal_successful: Ihre Zahlung mit PayPal wurde erfolgreich abgewickelt. order_hub_info: Informationen über den Laden order_back_to_store: Zurück zum Laden @@ -1494,19 +1539,19 @@ de_DE: email_confirmation_profile_created: "Das Profil für %{name} wurde erfolgreich erstellt! Zur Aktivierung des Profils, bitten wir Sie diese E-Mail-Adresse zu bestätigen." email_confirmation_click_link: "Bitte klicken Sie auf den untenstehenden Link, um Ihre E-Mail-Adresse zu bestätigen und mit der Einrichtung Ihres Profils fortzufahren." email_confirmation_link_label: "E-Mail-Adresse bestätigen" - email_confirmation_help_html: "Nachdem Sie Ihre E-Mail-Adresse bestätigt haben, können Sie auf die Einstellungen dieses Unternehmens zugreifen. Sehen Sie sich die %{link} an, um mehr über die Funktionen von %{sitename} zu erfahren und Ihr Profil oder Ihren Online-Shop zu verwenden." - email_confirmation_notice_unexpected: "Sie haben diese Nachricht erhalten, weil Sie sich bei %{sitename} angemeldet haben oder von einer Person eingeladen wurden, die Sie wahrscheinlich kennen. Wenn Sie nicht verstehen, warum Sie diese E-Mail erhalten, schreiben Sie bitte an %{contact}." + email_confirmation_help_html: "Nachdem Sie Ihre E-Mail-Adresse bestätigt haben, können Sie auf die Einstellungen dieses Unternehmens zugreifen. Sehen Sie sich die %{link} an, um mehr über die Funktionen des Open Food Networks zu erfahren und Ihr Profil oder Ihren Online-Shop einzurichten." + email_confirmation_notice_unexpected: "Sie haben diese Nachricht erhalten, weil Sie sich im Open Food Network angemeldet haben oder von einer Person dazu eingeladen wurden. Wenn Sie nicht verstehen, warum Sie diese E-Mail erhalten, schreiben Sie bitte an %{contact}." email_social: "Verbinden Sie sich mit uns:" - email_contact: "Schreib uns eine E-Mail:" - email_signoff: "Mit freundlichen Grüßen," - email_signature: "das Team von %{sitename}" + email_contact: "Schreiben Sie uns eine E-Mail:" + email_signoff: "Viele Grüße," + email_signature: "das Team vom Open Food Network" email_confirm_customer_greeting: "Hallo %{name}," email_confirm_customer_intro_html: "vielen Dank für Ihren Einkauf bei %{distributor}!" email_confirm_customer_number_html: "Bestellbestätigung #%{number}" email_confirm_customer_details_html: "Nachfolgend finden Sie Ihre Bestelldaten bei %{distributor}:" - email_confirm_customer_signoff: "Mit freundlichen Grüßen," + email_confirm_customer_signoff: "Viele Grüße," email_confirm_shop_greeting: "Hallo %{name}," - email_confirm_shop_order_html: "Gut gemacht! Sie haben eine neue Bestellung bei %{distributor} erhalten!" + email_confirm_shop_order_html: "gut gemacht! %{distributor} hat eine neue Bestellung erhalten!" email_confirm_shop_number_html: "Bestellbestätigung #%{number}" email_order_summary_item: "Artikel" email_order_summary_quantity: "Menge" @@ -1545,11 +1590,11 @@ de_DE: email_shipping_collection_instructions: "Informationen zur Abholung:" email_special_instructions: "Ihre Notizen:" email_signup_greeting: Hallo! - email_signup_welcome: "Willkommen bei %{sitename}!" + email_signup_welcome: "Willkommen im Open Food Network!" email_signup_confirmed_email: "Vielen Dank für die Bestätigung Ihrer E-Mail-Adresse." email_signup_shop_html: "Sie können sich jetzt unter %{link} einloggen." email_signup_text: "Danke, dass Sie dem Netzwerk beigetreten sind. Wenn Sie ein Kunde sind, freuen wir uns, Ihnen viele fantastische Landwirte, wunderbare Läden und leckeres Essen vorzustellen! Wenn Sie ein Produzent oder ein Lebensmittelunternehmer sind, freuen wir uns, Sie als Teil des Netzwerks zu begrüßen." - email_signup_help_html: "Wir freuen und über Ihre Fragen und Rückmeldungen. Schreiben Sie uns gerne eine E-Mail an %{email}." + email_signup_help_html: "Wir freuen uns über Ihre Fragen und Rückmeldungen. Schreiben Sie uns gerne eine E-Mail an %{email}." invite_email: greeting: "Hallo!" invited_to_manage: "Sie wurden eingeladen, %{enterprise} auf %{instance} zu verwalten." @@ -1560,16 +1605,18 @@ de_DE: producer_mail_text_before: "Nachfolgend senden wir Ihnen eine Aktualisierung des Bestellzyklus, bereit am:" producer_mail_order_text: "Nachfolgend finden Sie eine Zusammenfassung der Bestellungen Ihrer Produkte:" producer_mail_delivery_instructions: "Informationen zur Abholung/Lieferung:" - producer_mail_signoff: "Mit freundlichen Grüßen," + producer_mail_signoff: "Viele Grüße," shopping_oc_closed: Bestellzyklen sind derzeit geschlossen! shopping_oc_closed_description: "Bitte warten Sie, bis der nächste Bestellzyklus öffnet (oder kontaktieren Sie uns direkt, um zu erfahren, ob wir verspätete Bestellungen annehmen können)." shopping_oc_last_closed: "Der letzte Bestellzyklus wurde vor %{distance_of_time} geschlossen." shopping_oc_next_open: "Der nächste Bestellzyklus wird in %{distance_of_time} geöffnet" shopping_oc_select: "Auswählen ..." shopping_tabs_home: "Startseite" - shopping_tabs_shop: "Einkaufen" + shopping_tabs_shop: "Produkte" shopping_tabs_about: "Über uns" + shopping_tabs_producers: "Unsere Produzenten" shopping_tabs_contact: "Kontakt" + shopping_tabs_groups: "Unsere Gruppen" shopping_contact_address: "Adresse" shopping_contact_web: "Kontakt" shopping_contact_social: "Folgen" @@ -1594,8 +1641,8 @@ de_DE: hubs_filter_type: "Kategorie" hubs_filter_delivery: "Lieferoptionen" hubs_filter_property: "Eigenschaften" - hubs_matches: "Meinten Sie?" - hubs_intro: Regional einkaufen + hubs_matches: "Ergebnisse für" + hubs_intro: Wo möchten Sie regional einkaufen? hubs_distance: In der Nähe von hubs_distance_filter: "Läden in der Nähe von %{location} suchen" shop_changeable_orders_alert_html: @@ -1648,7 +1695,7 @@ de_DE: groups_contact_email: Schreiben Sie uns eine E-Mail groups_contact_website: Besuchen Sie unsere Homepage groups_contact_facebook: Folgen Sie uns auf Facebook - groups_signup_title: Melden Sie eine Gruppe an + groups_signup_title: Schließen Sie sich mit anderen Produzenten und Läden zu einer Gruppe zusammen groups_signup_headline: Registrierung einer Gruppe groups_signup_intro: "Wir sind eine großartige Plattform für kollaboratives Marketing - der einfachste Weg für die Mitglieder Ihrer Gruppe neue Märkte zu erreichen. Wir sind gemeinnützig, erschwinglich und transparent." groups_signup_email: Schreiben Sie uns eine E-Mail @@ -1678,8 +1725,8 @@ de_DE: producers_filter_property: Eigenschaften producers_title: Produzenten producers_headline: Finden Sie regionale Produzenten - producers_signup_title: Melden Sie sich als Produzent an - producers_signup_headline: Lebensmittelproduzenten nehmen ihr Geschäft wieder in die eigene Hand. + producers_signup_title: Verkaufen Sie Ihre eigenen Produkte im kostenlosen Online-Shop + producers_signup_headline: Direktvermarktung für regionale Produkte und faire Preise producers_signup_motivation: Verkaufen Sie Ihre Produkte und erzählen Sie Ihre Geschichten. Sparen Sie Zeit und Geld in der Verwaltung. Wir unterstützen Ihre Innovation ohne Risiko. Es ist alles vorbereitet. producers_signup_send: Jetzt beitreten producers_signup_enterprise: Unternehmenskonten @@ -1706,13 +1753,13 @@ de_DE: sell_hubs_detail: "Richten Sie im Open Food Network ein Profil für Ihr Lebensmittelunternehmen oder Ihre Organisation ein. Sie können Ihr Profil jederzeit erweitern und Produkte von anderen Produzenten und Läden direkt an Kunden verkaufen." sell_groups_detail: "Richten Sie eine Gruppe von Unternehmen ein, um Ihren Kunden den Zugang zu den Läden Ihrer Gruppe zu erleichtern. Fassen Sie in der Gruppe z. B. Produzenten und andere Lebensmittelunternehmen Ihrer Region, Ihres Bauernmarktes oder Ihrer Organisation zusammen." sell_user_guide: "Erfahren Sie mehr in unserem Benutzerhandbuch." - sell_listing_price: "Die Aufnahme ins Open Food Network ist kostenlos. Das Eröffnen und Betreiben eines Ladens im OFN ist während einer Einführungsphase kostenlos." + sell_listing_price: "Die Aufnahme ins Open Food Network ist kostenlos. Das Eröffnen und Betreiben eines Online-Shops ist für Unternehmen mit einem monatlichen Umsatz unter 500 € kostenlos. Bei höherem Umsatz erlauben wir uns nach einer 3-monatigen kostenlosen Testphase die Berechnung von 3 % Gebühr, um unsere Kosten zu decken." sell_embed: "Wir bieten noch weitere Dienste rund um Ihr Unternehmen an." sell_ask_services: "Fragen Sie uns nach OFN-Dienstleistungen." shops_title: Regional Einkaufen - shops_headline: Einkaufen, neu gedacht. - shops_text: Pflanzen wachsen in Zyklen, Landwirte ernten in Zyklen und wir bestellen Lebensmittel in Zyklen. Ist ein Bestellzyklus gerade geschlossen, schauen Sie bald wieder vorbei. - shops_signup_title: Laden registrieren + shops_headline: Wählen Sie einen Laden aus der Liste. + shops_text: Pflanzen wachsen in Zyklen, Landwirte ernten in Zyklen und bei uns bestellen Sie Lebensmittel in Zyklen. Ist ein Bestellzyklus gerade geschlossen, wählen Sie einen anderen Laden oder schauen Sie später wieder vorbei. + shops_signup_title: Verkaufen Sie Ihre eigenen oder die Produkte anderer Produzenten im kostenlosen Online-Shop shops_signup_headline: Lebensmittel-Hubs, unbegrenzt. shops_signup_motivation: Was auch immer Ihr Modell ist, wir unterstützen Sie. Wie auch immer Sie sich ändern, wir sind bei Ihnen. Wir sind gemeinnützig, unabhängig und Open-Source. Wir sind die Software-Partner, von denen Sie schon immer geträumt haben. shops_signup_action: Jetzt beitreten @@ -1721,40 +1768,41 @@ de_DE: shops_signup_help: Wir sind bereit zu helfen. shops_signup_help_text: Du brauchst eine bessere Rendite. Sie brauchen neue Käufer und Logistikpartner. Sie müssen Ihre Geschichte über den Großhandel, den Einzelhandel und den Küchentisch erzählen. shops_signup_detail: Weitere Details folgen. - orders: Bestellungen - orders_fees: Gebühren ... - orders_edit_title: Warenkorb - orders_edit_headline: Ihr Warenkorb - orders_edit_time: Bestellung bereit am - orders_edit_continue: Weiter einkaufen - orders_edit_checkout: Zur Kasse + orders: "Bestellungen" + orders_fees: "Gebühren ..." + orders_edit_title: "Warenkorb" + orders_edit_headline: "Ihr Warenkorb" + orders_edit_time: "Bestellung bereit am" + orders_edit_continue: "Weiter einkaufen" + orders_edit_checkout: "Zur Kasse" orders_form_empty_cart: "Warenkorb leeren" - orders_form_subtotal: Zwischensumme - orders_form_admin: Bearbeitung - orders_form_total: Summe - orders_oc_expired_headline: Bestellannahme für diesen Bestellzyklus bereits geschlossen! + orders_form_update_cart: "Aktualisieren" + orders_form_subtotal: "Zwischensumme" + orders_form_admin: "Bearbeitung" + orders_form_total: "Summe" + orders_oc_expired_headline: "Bestellannahme für diesen Bestellzyklus bereits geschlossen!" orders_oc_expired_text: "Der Bestellzyklus wurde vor %{time} geschlossen! Bitte kontaktieren Sie den Laden direkt, um zu erfahren, ob er verspätete Bestellungen annehmen kann." orders_oc_expired_text_others_html: "Der Bestellzyklus wurde vor %{time} geschlossen! Bitte kontaktieren Sie den Laden direkt, um zu erfahren, ob er verspätete Bestellungen annehmen kann (%{link})." - orders_oc_expired_text_link: "oder sehen Sie sich die anderen Bestellzyklen dieses Hubs an." + orders_oc_expired_text_link: "oder sehen Sie sich die anderen Bestellzyklen dieses Ladens an." orders_oc_expired_email: "E-Mail-Adresse:" orders_oc_expired_phone: "Telefonnummer:" - orders_show_title: Bestellbestätigung - orders_show_time: Bestellung bereit am + orders_show_title: "Bestellbestätigung" + orders_show_time: "Bestellung bereit am" orders_show_order_number: "Bestellung #%{number}" - orders_show_cancelled: Storniert - orders_show_confirmed: Bestätigt + orders_show_cancelled: "Storniert" + orders_show_confirmed: "Bestätigt" orders_your_order_has_been_cancelled: "Ihre Bestellung wurde storniert." orders_could_not_cancel: "Die Bestellung konnte nicht storniert werden." orders_cannot_remove_the_final_item: "Der letzte verbleibende Artikel einer Bestellung kann nicht entfernt werden. Bitte stornieren Sie stattdessen die Bestellung." orders_bought_items_notice: - one: Ein zusätzlicher Artikel ist bereits für diesen Bestellzyklus bestätigt. - few: "%{count} zusätzliche Artikel, sind bereits für diesen Bestellzyklus bestätigt." - many: "%{count} zusätzliche Artikel, sind bereits für diesen Bestellzyklus bestätigt." - other: "%{count} zusätzliche Artikel, sind bereits für diesen Bestellzyklus bestätigt." - orders_bought_edit_button: Bestätigte Artikel bearbeiten + one: "Ein zusätzlicher Artikel ist bereits für diesen Bestellzyklus bestätigt." + few: "%{count} zusätzliche Artikel sind bereits für diesen Bestellzyklus bestätigt." + many: "%{count} zusätzliche Artikel sind bereits für diesen Bestellzyklus bestätigt." + other: "%{count} zusätzliche Artikel sind bereits für diesen Bestellzyklus bestätigt." + orders_bought_edit_button: "Bestätigte Artikel bearbeiten" orders_bought_already_confirmed: "* schon bestätigt" - orders_confirm_cancel: Sind Sie sicher, dass Sie diese Bestellung stornieren möchten? - order_processed_successfully: "Ihre Bestellung wurde erfolgreich bearbeitet." + orders_confirm_cancel: "Sind Sie sicher, dass Sie diese Bestellung stornieren möchten?" + order_processed_successfully: "Ihre Bestellung wurde erfolgreich verarbeitet." products_cart_distributor_choice: "Verteilstelle Ihrer Bestellung:" products_cart_distributor_change: "Die Verteilstelle für diese Bestellung wird in %{name} geändert, wenn Sie dieses Produkt zu Ihrem Warenkorb hinzufügen." products_cart_distributor_is: "Die Verteilstelle dieser Bestellung ist %{name}." @@ -1794,7 +1842,7 @@ de_DE: error_not_found_in_database: "%{name} wurde nicht in der Datenbank gefunden" error_not_primary_producer: "%{name} ist nicht als Produzent aktiviert" error_no_permission_for_enterprise: "%{name}: Sie sind nicht berechtigt, Produkte dieses Unternehmens zu verwalten" - item_handling_fees: "Bearbeitungsgebühren des Artikels (in den Artikelsummen enthalten)" + item_handling_fees: "Bearbeitungsgebühren des Artikels (im Artikelpreis enthalten)" january: "Januar" february: "Februar" march: "März" @@ -1812,7 +1860,7 @@ de_DE: email_required: "Sie müssen eine E-Mail-Adresse angeben." logging_in: "Einen Moment bitte, wir loggen Sie ein ..." signup_email: "Ihre E-Mail-Adresse" - choose_password: "Ihr Passwort" + choose_password: "Wählen Sie ein Passwort" confirm_password: "Passwort erneut eingeben" action_signup: "Jetzt registrieren" forgot_password: "Passwort vergessen?" @@ -2043,7 +2091,7 @@ de_DE: notify_producers: 'Produzenten benachrichtigen' edit_order_cycle: "Bestellzyklus bearbeiten" roles: "Rollen" - update: "Aktualisieren" + update: "Speichern" delete: Löschen add_producer_property: "Produzenteneigenschaft hinzufügen" in_progress: "In Bearbeitung" @@ -2141,7 +2189,7 @@ de_DE: report_customers_supplier: "Lieferant" report_customers_cycle: "Bestellzyklus" report_customers_type: "Berichtsart" - report_customers_csv: "Download als csv-Datei" + report_customers_csv: "Als csv-Datei herunterladen" report_producers: "Produzenten:" report_type: "Berichtsart" report_hubs: "Hubs:" @@ -2339,8 +2387,8 @@ de_DE: validation_msg_tax_category_cant_be_blank: "^ Steuerkategorie darf nicht leer sein." validation_msg_is_associated_with_an_exising_customer: "ist mit einem bestehenden Kunden verbunden" content_configuration_pricing_table: "(TODO: Preistabelle)" - content_configuration_case_studies: "(TODO: Fallstudien)" - content_configuration_detail: "(Todo: Detail)" + content_configuration_case_studies: "(TODO: Beispiele)" + content_configuration_detail: "(TODO: Detail)" enterprise_name_error: "wurde bereits vergeben. Wenn dies Ihr Unternehmen ist und Sie die Eigentumsrechte beanspruchen möchten oder wenn Sie mit diesem Unternehmen handeln möchten, wenden Sie sich bitte an den aktuellen Manager dieses Profils unter %{email}." enterprise_owner_error: "^ %{email} darf keine weiteren Unternehmen besitzen (maximale Anzahl ist %{enterprise_limit})." enterprise_role_uniqueness_error: "^ Diese Rolle ist bereits vorhanden." @@ -2412,6 +2460,7 @@ de_DE: Beim Hinzufügen dieses Produkts zum Warenkorb ist ein Fehler aufgetreten. Möglicherweise ist es nicht mehr verfügbar oder der Laden schließt gerade. admin: + unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Packungsgröße und -gewicht. Der im Online-Shop angezeigte Grundpreis kann ggf. aufgrund hinzukommender Gebühren abweichen." enterprise_limit_reached: "Sie haben die maximale Anzahl der Unternehmen pro Konto erreicht. Schreiben Sie an %{contact_email}, wenn Sie das Limit erhöhen möchten." modals: got_it: "Verstanden" @@ -2664,7 +2713,7 @@ de_DE: min_quantity: "Minimale Menge" max_quantity: "Maximale Menge" price_breakdown: "Preisaufschlüsselung" - unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Verpackungsgröße und -gewicht." + unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Packungsgröße und -gewicht." variants: on_demand: 'yes': "Auf Anfrage" @@ -2727,7 +2776,7 @@ de_DE: order: "Bestellung" registration: welcome_to_ofn: "Willkommen im Open Food Network!" - signup_or_login: "Beginnen Sie mit der Registrierung (oder loggen Sie sich ein)." + signup_or_login: "Beginnen Sie mit der Registrierung oder loggen Sie sich ein" have_an_account: "Haben Sie bereits ein Konto?" action_login: "Jetzt einloggen." stripe_elements: @@ -2812,6 +2861,15 @@ de_DE: start_free_profile: "Beginnen Sie mit einem kostenlosen Profil und erweitern Sie es, wann Sie möchten!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Gruppenkäufe - Zuteilung" + bulk_coop_customer_payments: "Gruppenkäufe - Kundenzahlungen" + bulk_coop_packing_sheets: "Gruppenkäufe - Packlisten" + bulk_coop_supplier_report: "Gruppenkäufe - Lieferanten" + date_range: "Datumsbereich" + generate_report: "Suche" + report_format_csv: "Als csv-Datei herunterladen" enterprise_fee_summaries: filters: date_range: "Datumsbereich" @@ -2857,6 +2915,8 @@ de_DE: tax_category_name: "Steuerkategorie" total_amount: "SUMME" invalid_filter_parameters: "Die für diesen Bericht ausgewählten Filter sind ungültig." + report: + none: "Keine" order: "Bestellung" distribution: "Verteilung" order_details: "Bestelldetails" @@ -2889,7 +2949,54 @@ de_DE: previous: "Vorherige" last: "Letzte" spree: + add_country: "Neues Land" + add_state: "Neues Bundesland" + adjustment: "Anpassung" + all: "Alle" + associated_adjustment_closed: "Zugehörige Anpassung geschlossen" + authorization_failure: "Fehler bei der Autorisierung" + back_to_adjustments_list: "Zurück zu Anpassungen" + back_to_users_list: "Zurück zur Benutzerliste" + back_to_zones_list: "Zurück zur Zonenliste" + card_code: "Kartenprüfnummer (3-stellig)" + card_number: "Kreditkartennummer" + category: "Produktkategorie" + created_successfully: "Erfolgreich erstellt" + credit: "Guthaben" + editing_tax_category: "Steuerkategorie bearbeiten" + editing_tax_rate: "Steuersatz bearbeiten" + editing_zone: "Zone bearbeiten" + expiration: "Ablaufdatum" + invalid_payment_provider: "Ungültiger Zahlungsanbieter" + items_cannot_be_shipped: "Artikel können nicht geliefert werden" + gateway_config_unavailable: "Gateway-Konfiguration nicht verfügbar" + gateway_error: "Zahlung fehlgeschlagen" more: "Mehr" + new_adjustment: "Neue Anpassung" + new_order_completed: "Neue Bestellung abgeschlossen" + new_tax_category: "Neue Steuerkategorie" + new_taxon: "Neue Kategorie" + new_user: "Neuer Benutzer" + no_pending_payments: "Keine ausstehenden Zahlungen." + none: "Keine" + not_found: "Nicht gefunden" + notice_messages: + variant_deleted: "Variante wurde gelöscht" + or: "oder" + order_processed_successfully: "Ihre Bestellung wurde erfolgreich verarbeitet." + payment_method_not_supported: "Zahlungsart wird nicht unterstützt" + resend_authorization_email: "Autorisierungs-E-Mail erneut senden" + rma_credit: "Gutschrift aus Retour" + server_error: "Serverfehler" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Anfangsdatum" + successfully_removed: "Erfolgreich gelöscht" + taxonomy_edit: "Kategorien bearbeiten" + taxonomy_tree_error: "Fehler in Struktur der Kategorien" + taxonomy_tree_instruction: "Anleitung zur Struktur der Kategorien" + tree: "Struktur" + updating: "Aktualisierung" your_order_is_empty_add_product: "Ihre Bestellung ist leer. Suchen Sie oben ein Produkt und fügen Sie es hinzu." add_product: "Produkt hinzufügen" name_or_sku: "Produktname oder Artikelnummer (geben Sie mindestens die ersten 3 Zeichen des Produktnamens ein)" @@ -2917,6 +3024,7 @@ de_DE: tracking_number: "Sendungscode" order_total: "Bestellung insgesamt" customer_details: "Kundendetails" + customer_details_updated: "Kundendetails gespeichert" customer_search: "Kundensuche" choose_a_customer: "Wählen Sie einen Kunden aus." account: "Konto" @@ -3065,8 +3173,10 @@ de_DE: successfully_created: '%{resource} wurde erfolgreich erstellt.' successfully_updated: '%{resource} wurde erfolgreich gespeichert.' payment_method: "Zahlungsart" - payment_processing_failed: "Die Zahlung konnte nicht bearbeitet werden. Bitte überprüfen Sie die von Ihnen eingegebenen Daten." + payment_processing_failed: "Die Zahlung konnte nicht verarbeitet werden. Bitte überprüfen Sie die von Ihnen eingegebenen Daten." not_available: "N / A" + sku: "Artikelnummer" + there_are_no_items_for_this_order: "Diese Bestellung enthält keine Artikel." order_populator: out_of_stock: '%{item} ist leider nicht mehr vorrätig.' actions: @@ -3094,7 +3204,17 @@ de_DE: login_nav: header: store: openfoodnetwork.de + validation: + must_be_int: "muss eine ganze Zahl sein" admin: + mail_methods: + send_testmail: "Test-E-Mail senden" + testmail: + delivery_success: "Test-E-Mail wurde gesendet." + error: "Beim Senden der Test-E-Mail ist ein Fehler aufgetreten." + unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Packungsgröße und -gewicht. Der im Online-Shop angezeigte Grundpreis kann ggf. aufgrund hinzukommender Gebühren abweichen." + subscriptions: + number: "Bestellnummer" tab: dashboard: "Übersicht" orders: "Bestellungen" @@ -3163,6 +3283,8 @@ de_DE: received: "Empfangen" canceled: "abgebrochen" orders: + add_product: + cannot_add_item_to_canceled_order: "Artikel kann nicht zu stornierter Bestellung hinzugefügt werden" index: listing_orders: "Bestellungen verwalten" new_order: "Neue Bestellung" @@ -3205,6 +3327,10 @@ de_DE: overview: enterprises_header: ofn_with_tip: Unternehmen sind Produzenten und/oder Hubs und sind die grundlegende Organisationseinheit innerhalb des Open Food Network. + enterprise_row: + has_no_enterprise_fees: "hat keine Unternehmensgebühren" + has_no_payment_methods: "hat keine Zahlungsarten" + has_no_shipping_methods: "hat keine Lieferoptionen" products: active_products: zero: "Sie haben keine aktiven Produkte." @@ -3243,6 +3369,7 @@ de_DE: back_to_shipping_methods_list: "Zurück zur Liste der Lieferoptionen" form: categories: "Kategorien" + tax_category: "Steuerkategorie" zones: "Zonen" both: "Sowohl an der Kasse als auch im Backoffice" back_end: "Nur im Backoffice" @@ -3323,6 +3450,8 @@ de_DE: value: "Menge" unit_name: "Einheitenname" price: "Preis" + unit_price: "Grundpreis" + unit_price_legend: "Berechnet aus Preis und Menge." on_hand: "Verfügbar" on_demand: "Unbegrenzt" product_description: "Produktbeschreibung" @@ -3361,10 +3490,10 @@ de_DE: table: select_and_search: "Treffen Sie Ihre Auswahl und klicken Sie auf %{option}, um den Bericht zu erstellen." bulk_coop: - bulk_coop_supplier_report: 'Gruppenkauf - Summen nach Lieferanten' - bulk_coop_allocation: 'Gruppenkauf - Zuteilung' - bulk_coop_packing_sheets: 'Gruppenkauf - Packlisten' - bulk_coop_customer_payments: 'Gruppenkauf - Kundenzahlungen' + bulk_coop_supplier_report: 'Gruppenkäufe - Lieferanten' + bulk_coop_allocation: 'Gruppenkäufe - Zuteilung' + bulk_coop_packing_sheets: 'Gruppenkäufe - Packlisten' + bulk_coop_customer_payments: 'Gruppenkäufe - Kundenzahlungen' customer_names_message: customer_names_tip: "Wenn Kundennamen für von Ihnen gelieferte Bestellungen ausgeblendet sind, können Sie sich an den Händler wenden und ihn bitten, seine Ladeneinstellungen anzupassen, damit seine Lieferanten Kundennamen anzeigen können." users: @@ -3393,7 +3522,6 @@ de_DE: price: "Preis" options: "Varianten" no_results: "Keine Ergebnisse gefunden." - to_add_variants_you_must_first_define: "Um Varianten hinzuzufügen, müssen Sie zuerst definieren" option_types: "Optionstypen" option_values: "Optionswerte" and: "und" @@ -3405,6 +3533,7 @@ de_DE: form: sku: "Artikelnummer" price: "Preis" + unit_price: "Grundpreis" display_as: "Anzeigen als" display_name: "Variantenname" display_as_placeholder: 'z. B. 2 kg' @@ -3428,6 +3557,7 @@ de_DE: cookies_consent_banner_toggle: "Zustimmungsbanner für Cookies anzeigen" privacy_policy_url: "URL der Datenschutzerklärung" enterprises_require_tos: "Unternehmen müssen die AGB akzeptieren" + shoppers_require_tos: "Kunden müssen den Allgemeinen Geschäftsbedingungen (AGB) zustimmen" cookies_policy_matomo_section: "Matomo auf der Richtlinienseite für Cookies anzeigen" footer_tos_url: "URL der Allgemeinen Geschäftsbedingungen" checkout: @@ -3510,10 +3640,10 @@ de_DE: Falls dies nicht funktionieren sollte, bitte den Link kopieren und in die Adresszeile Ihres Browsers einfügen. subject: "Anweisungen zum Zurücksetzen des Passworts" confirmation_instructions: - subject: "Bitte bestätigen Sie Ihre Registrierung bei Open Food Network DE" + subject: "Bitte bestätigen Sie Ihre Registrierung im Open Food Network" payment_mailer: authorize_payment: - subject: "Bitte bestätigen Sie Ihre Zahlung an %{distributor} im Open Food Network DE" + subject: "Bitte bestätigen Sie Ihre Zahlung an %{distributor} im Open Food Network" instructions: "Ihre Zahlung in Höhe von %{amount} an %{distributor} erfordert Ihre zusätzliche Bestätigung. Bitte klicken Sie auf den folgenden Link, um Ihre Zahlung zu bestätigen:" authorization_required: subject: "Eine Zahlung muss durch den Kunden bestätigt werden" @@ -3639,3 +3769,42 @@ de_DE: spree/payment: one: Zahlung other: Zahlungen + datetime: + distance_in_words: + about_x_hours: + one: etwa 1 Stunde + other: etwa %{count} Stunden + about_x_months: + one: etwa 1 Monat + other: etwa %{count} Monaten + about_x_years: + one: etwa 1 Jahr + other: etwa %{count} Jahren + almost_x_years: + one: fast 1 Jahr + other: fast %{count} Jahren + half_a_minute: 30 Sekunden + less_than_x_seconds: + one: weniger als 1 Sekunde + other: weniger als %{count} Sekunden + less_than_x_minutes: + one: weniger als einer Minute + other: weniger als %{count} Minuten + over_x_years: + one: über 1 Jahr + other: über %{count} Jahren + x_seconds: + one: "1 Sekunde" + other: "%{count} Sekunden" + x_minutes: + one: "1 Minute" + other: "%{count} Minuten" + x_days: + one: "1 Tag" + other: "%{count} Tagen" + x_months: + one: "1 Monat" + other: "%{count} Monaten" + x_years: + one: "1 Jahr" + other: "%{count} Jahren" diff --git a/config/locales/en.yml b/config/locales/en.yml index e1536771d2..65a115db46 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -107,6 +107,11 @@ en: shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -137,12 +142,40 @@ en: updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -169,6 +202,7 @@ en: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -294,7 +328,7 @@ en: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state: %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -332,9 +366,13 @@ en: rename: "Rename" admin: + adjustments: + skipped_changing_canceled_order: "You can't change a cancelled order." # Common properties / models begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1122,6 +1160,7 @@ en: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1203,6 +1242,7 @@ en: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1686,7 +1726,9 @@ See the %{link} to find out more about %{sitename}'s features and to start using shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1855,39 +1897,40 @@ See the %{link} to find out more about %{sitename}'s features and to start using shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" @@ -2562,6 +2605,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using There was a problem adding this product to the cart. Perhaps it has become unavailable or the shop is closing. admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2962,6 +3006,15 @@ See the %{link} to find out more about %{sitename}'s features and to start using order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -3007,6 +3060,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + "none": "None" order: "Order" distribution: "Distribution" @@ -3044,7 +3099,54 @@ See the %{link} to find out more about %{sitename}'s features and to start using last: "Last" spree: + add_country: "Add country" + add_state: "Add state" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Associated adjustment closed" + authorization_failure: "Authorization failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + "none": "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorization email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -3072,6 +3174,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3238,6 +3341,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "SKU" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: ! '%{item} is out of stock.' @@ -3266,7 +3371,19 @@ See the %{link} to find out more about %{sitename}'s features and to start using login_nav: header: store: Store + + validation: + must_be_int: "must be an integer" + admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent." + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3335,6 +3452,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "Cannot add item to canceled order" index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3377,6 +3496,10 @@ See the %{link} to find out more about %{sitename}'s features and to start using overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3415,6 +3538,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3495,6 +3619,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3565,7 +3691,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3577,6 +3702,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3813,3 +3939,42 @@ See the %{link} to find out more about %{sitename}'s features and to start using spree/payment: one: Payment other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: 1 second + other: "%{count} seconds" + x_minutes: + one: 1 minute + other: "%{count} minutes" + x_days: + one: 1 day + other: "%{count} days" + x_months: + one: 1 month + other: "%{count} months" + x_years: + one: 1 year + other: "%{count} years" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index edf5e847f8..4ef0dec591 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -85,6 +85,7 @@ en_AU: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -117,6 +118,8 @@ en_AU: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -262,7 +265,6 @@ en_AU: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -1153,6 +1155,7 @@ en_AU: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1573,7 +1576,9 @@ en_AU: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1724,39 +1729,40 @@ en_AU: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2800,6 +2806,9 @@ en_AU: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2845,6 +2854,8 @@ en_AU: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2877,7 +2888,13 @@ en_AU: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + no_pending_payments: "No pending payments" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -3053,6 +3070,7 @@ en_AU: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "SKU" order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3080,6 +3098,8 @@ en_AU: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3228,6 +3248,7 @@ en_AU: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3301,6 +3322,7 @@ en_AU: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3371,7 +3393,6 @@ en_AU: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3383,6 +3404,7 @@ en_AU: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index ea3ff0db94..dad11c87dc 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -75,6 +75,7 @@ en_BE: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -106,6 +107,8 @@ en_BE: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -1072,6 +1075,7 @@ en_BE: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1471,7 +1475,9 @@ en_BE: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1613,28 +1619,29 @@ en_BE: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." @@ -1642,9 +1649,9 @@ en_BE: few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2574,6 +2581,9 @@ en_BE: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2619,6 +2629,8 @@ en_BE: tax_category_name: "Tax Category" total_amount: "€€ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2648,7 +2660,12 @@ en_BE: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2798,6 +2815,7 @@ en_BE: successfully_updated: '%{resource} has been successfully updated!' payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" + sku: "SKU" actions: update: "Update" cancel: "Cancel" @@ -2815,6 +2833,8 @@ en_BE: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -2931,6 +2951,7 @@ en_BE: back_to_shipping_methods_list: "No shipping methods found" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" payment_methods: index: @@ -2992,6 +3013,7 @@ en_BE: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3063,6 +3085,7 @@ en_BE: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" autocomplete: out_of_stock: "Out of Stock" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 821275641b..baa1b69f9b 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -85,6 +85,11 @@ en_CA: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -114,11 +119,39 @@ en_CA: updated_not_active: "Your password has been reset, but your email has not been confirmed yet." updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF%{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -144,6 +177,7 @@ en_CA: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer, " @@ -264,7 +298,7 @@ en_CA: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -298,8 +332,12 @@ en_CA: destroy: "Destroy" rename: "Rename" admin: + adjustments: + skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1064,6 +1102,7 @@ en_CA: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1145,6 +1184,7 @@ en_CA: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1177,8 +1217,10 @@ en_CA: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}" terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}" terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1255,11 +1297,11 @@ en_CA: invoice_column_price_with_taxes: "Total price (Incl. tax)" invoice_column_price_without_taxes: "Total price (Excl. tax)" invoice_column_tax_rate: "Tax rate" - invoice_tax_total: "Sales Tax (on product):" + invoice_tax_total: "Sales Tax:" tax_invoice: "TAX INVOICE" tax_total: "Total tax (%{rate}):" - total_excl_tax: "Total (incl. shipping tax if applicable)" - total_incl_tax: "Total (Incl. tax):" + total_excl_tax: "Total (Excl. tax):" + total_incl_tax: "Total " abn: "Business Number:" acn: "Business Number:" invoice_issued_on: "Invoice issued on:" @@ -1570,7 +1612,9 @@ en_CA: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Markets" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1722,39 +1766,40 @@ en_CA: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle. + one: "An additional item is already confirmed for this order cycle." few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2413,6 +2458,7 @@ en_CA: There was a problem adding this product to the cart. Perhaps it has become unavailable or the shop is closing admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ. For example, shopfront prices might include enterprise fees (mark-ups) if you are using them." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2805,6 +2851,15 @@ en_CA: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2850,6 +2905,8 @@ en_CA: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2882,7 +2939,54 @@ en_CA: previous: "Previous" last: "Last" spree: + add_country: "Add country" + add_state: "Add state" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Associated adjustment closed" + authorization_failure: "Authorization failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + none: "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorization email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2910,6 +3014,7 @@ en_CA: tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3060,6 +3165,8 @@ en_CA: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered." not_available: "N/A" + sku: "SKU" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3087,7 +3194,17 @@ en_CA: login_nav: header: store: Store + validation: + must_be_int: "must be an integer" admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent" + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ. For example, shopfront prices might include enterprise fees (mark-ups) if you are using them." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3156,6 +3273,8 @@ en_CA: received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "You cannot add an item to a cancelled order." index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3198,6 +3317,10 @@ en_CA: overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3236,6 +3359,7 @@ en_CA: back_to_shipping_methods_list: "Back to Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3316,6 +3440,8 @@ en_CA: value: "Value" unit_name: "Unit Name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price." on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3386,7 +3512,6 @@ en_CA: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3398,6 +3523,7 @@ en_CA: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3421,6 +3547,7 @@ en_CA: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3633,3 +3760,42 @@ en_CA: spree/payment: one: Payment other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: "1 second" + other: "%{count} seconds" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 day" + other: "%{count} days" + x_months: + one: "1 month" + other: "%{count} months" + x_years: + one: "1 year" + other: "%{count} years" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 4209a8e524..d1ab0c0ca4 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -75,6 +75,7 @@ en_DE: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -107,6 +108,8 @@ en_DE: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -1082,6 +1085,7 @@ en_DE: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1481,7 +1485,9 @@ en_DE: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1623,28 +1629,29 @@ en_DE: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." @@ -1652,9 +1659,9 @@ en_DE: few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2584,6 +2591,9 @@ en_DE: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2629,6 +2639,8 @@ en_DE: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2659,7 +2671,12 @@ en_DE: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2813,6 +2830,7 @@ en_DE: successfully_updated: '%{resource} has been successfully updated!' payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" + sku: "SKU" actions: update: "Update" cancel: "Cancel" @@ -2830,6 +2848,8 @@ en_DE: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -2948,6 +2968,7 @@ en_DE: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" payment_methods: index: @@ -3009,6 +3030,7 @@ en_DE: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3080,6 +3102,7 @@ en_DE: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" autocomplete: out_of_stock: "Out of Stock" diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 30e7011b48..c2d96f6919 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -85,6 +85,11 @@ en_FR: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -114,11 +119,39 @@ en_FR: updated_not_active: "Your password has been reset, but your email has not been confirmed yet." updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -144,6 +177,7 @@ en_FR: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -264,7 +298,7 @@ en_FR: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state: %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -298,8 +332,12 @@ en_FR: destroy: "Destroy" rename: "Rename" admin: + adjustments: + skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1064,6 +1102,7 @@ en_FR: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1145,6 +1184,7 @@ en_FR: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1177,8 +1217,10 @@ en_FR: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}." terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}." terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1570,7 +1612,9 @@ en_FR: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1722,39 +1766,40 @@ en_FR: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2413,6 +2458,7 @@ en_FR: There was a problem adding this product to the cart. Perhaps it has become unavailable or the shop is closing. admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2806,6 +2852,15 @@ en_FR: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2851,6 +2906,8 @@ en_FR: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2883,7 +2940,54 @@ en_FR: previous: "Previous" last: "Last" spree: + add_country: "Add country" + add_state: "Add state" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Associated adjustment closed" + authorization_failure: "Authorization failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + none: "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorization email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2911,6 +3015,7 @@ en_FR: tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3061,6 +3166,8 @@ en_FR: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "SKU" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3088,7 +3195,17 @@ en_FR: login_nav: header: store: Store + validation: + must_be_int: "must be an integer" admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent." + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3157,6 +3274,8 @@ en_FR: received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "Cannot add item to canceled order" index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3199,6 +3318,10 @@ en_FR: overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3237,6 +3360,7 @@ en_FR: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3317,6 +3441,8 @@ en_FR: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3387,7 +3513,6 @@ en_FR: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3399,6 +3524,7 @@ en_FR: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3422,6 +3548,7 @@ en_FR: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3634,3 +3761,42 @@ en_FR: spree/payment: one: Payments other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: "1 second" + other: "%{count} seconds" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 day" + other: "%{count} days" + x_months: + one: "1 month" + other: "%{count} months" + x_years: + one: "1 year" + other: "%{count} years" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index 1edefdeba8..46db7e5662 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -58,7 +58,7 @@ en_GB: start_at: "Start" end_at: "End" distributor_ids: "Hubs" - producer_ids: "Pricing" + producer_ids: "Producers" order_cycle_ids: "Order Cycles" enterprise_fee_ids: "Fees Names" shipping_method_ids: "Shipping Methods" @@ -85,6 +85,11 @@ en_GB: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -114,11 +119,39 @@ en_GB: updated_not_active: "Your password has been reset, but your email has not been confirmed yet." updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "Product Code" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -144,6 +177,7 @@ en_GB: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -264,7 +298,7 @@ en_GB: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state: %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -298,8 +332,12 @@ en_GB: destroy: "Destroy" rename: "Rename" admin: + adjustments: + skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1064,6 +1102,7 @@ en_GB: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1145,6 +1184,7 @@ en_GB: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1177,8 +1217,10 @@ en_GB: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}." terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}." terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1570,7 +1612,9 @@ en_GB: shopping_tabs_home: "Notices" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1722,39 +1766,40 @@ en_GB: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2413,6 +2458,7 @@ en_GB: There was a problem adding this product to your basket. Perhaps it has become unavailable or the shop is closing. admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2812,6 +2858,15 @@ en_GB: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2857,6 +2912,8 @@ en_GB: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2889,7 +2946,54 @@ en_GB: previous: "Previous" last: "Last" spree: + add_country: "Add country" + add_state: "Add county" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Perform associated adjustment" + authorization_failure: "Authorisation failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + none: "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorisation email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2917,6 +3021,7 @@ en_GB: tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3067,6 +3172,8 @@ en_GB: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "Product Code" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3094,7 +3201,17 @@ en_GB: login_nav: header: store: Store + validation: + must_be_int: "must be an integer" admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent." + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3163,6 +3280,8 @@ en_GB: received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "Cannot add item to canceled order" index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3205,6 +3324,10 @@ en_GB: overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3243,6 +3366,7 @@ en_GB: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3323,6 +3447,8 @@ en_GB: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price" on_hand: "In Stock" on_demand: "Unlimited" product_description: "Product Description" @@ -3393,7 +3519,6 @@ en_GB: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3405,6 +3530,7 @@ en_GB: form: sku: "Product Code" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3428,6 +3554,7 @@ en_GB: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3640,3 +3767,42 @@ en_GB: spree/payment: one: Payment other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: "1 second" + other: "%{count} seconds" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 day" + other: "%{count} days" + x_months: + one: "1 month" + other: "%{count} months" + x_years: + one: "1 year" + other: "%{count} years" diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index b62bc6d195..902d228098 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -85,6 +85,11 @@ en_IE: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -114,11 +119,39 @@ en_IE: updated_not_active: "Your password has been reset, but your email has not been confirmed yet." updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "Product Code" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -144,6 +177,7 @@ en_IE: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -264,7 +298,7 @@ en_IE: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state: %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -300,6 +334,8 @@ en_IE: admin: begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1064,6 +1100,7 @@ en_IE: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1145,6 +1182,7 @@ en_IE: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1177,8 +1215,10 @@ en_IE: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}." terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}." terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1570,7 +1610,9 @@ en_IE: shopping_tabs_home: "Notices" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1722,39 +1764,40 @@ en_IE: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2413,6 +2456,7 @@ en_IE: There was a problem adding this product to the cart. Perhaps it has become unavailable or the shop is closing. admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2812,6 +2856,15 @@ en_IE: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2857,6 +2910,8 @@ en_IE: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2889,7 +2944,54 @@ en_IE: previous: "Previous" last: "Last" spree: + add_country: "Add country" + add_state: "Add state" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Associated adjustment closed" + authorization_failure: "Authorization failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + none: "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorization email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2917,6 +3019,7 @@ en_IE: tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3067,6 +3170,8 @@ en_IE: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "Product Code" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3094,7 +3199,17 @@ en_IE: login_nav: header: store: Store + validation: + must_be_int: "must be an integer" admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent." + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3163,6 +3278,8 @@ en_IE: received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "Cannot add item to canceled order" index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3205,6 +3322,10 @@ en_IE: overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3243,6 +3364,7 @@ en_IE: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3323,6 +3445,8 @@ en_IE: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price" on_hand: "In Stock" on_demand: "Unlimited" product_description: "Product Description" @@ -3393,7 +3517,6 @@ en_IE: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3405,6 +3528,7 @@ en_IE: form: sku: "Product Code" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3428,6 +3552,7 @@ en_IE: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3640,3 +3765,42 @@ en_IE: spree/payment: one: Payment other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: "1 second" + other: "%{count} seconds" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 day" + other: "%{count} days" + x_months: + one: "1 month" + other: "%{count} months" + x_years: + one: "1 year" + other: "%{count} years" diff --git a/config/locales/en_IN.yml b/config/locales/en_IN.yml index af4de0197f..956bc63fae 100644 --- a/config/locales/en_IN.yml +++ b/config/locales/en_IN.yml @@ -81,6 +81,7 @@ en_IN: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -113,6 +114,8 @@ en_IN: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "Product Code" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -257,7 +260,6 @@ en_IN: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -1118,6 +1120,7 @@ en_IN: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1531,7 +1534,9 @@ en_IN: shopping_tabs_home: "Notices" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1681,28 +1686,29 @@ en_IN: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." @@ -1710,9 +1716,9 @@ en_IN: few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2739,6 +2745,9 @@ en_IN: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2784,6 +2793,8 @@ en_IN: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2814,7 +2825,13 @@ en_IN: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + no_pending_payments: "No pending payments" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2983,6 +3000,7 @@ en_IN: successfully_updated: '%{resource} has been successfully updated!' payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" + sku: "Product Code" actions: update: "Update" cancel: "Cancel" @@ -3006,6 +3024,8 @@ en_IN: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3154,6 +3174,7 @@ en_IN: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3225,6 +3246,7 @@ en_IN: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "In Stock" on_demand: "Unlimited" product_description: "Product Description" @@ -3293,7 +3315,6 @@ en_IN: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3305,6 +3326,7 @@ en_IN: form: sku: "Product Code" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index 74537e5a26..9dba96175e 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -85,6 +85,7 @@ en_NZ: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -117,6 +118,10 @@ en_NZ: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + tax_rate: + included_in_price: "Included in price" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -262,7 +267,6 @@ en_NZ: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -1143,6 +1147,7 @@ en_NZ: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1175,8 +1180,10 @@ en_NZ: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}." terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}." terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1189,6 +1196,7 @@ en_NZ: mailers: powered_by: open_food_network: "Open Food Network" + powered_html: "Your shopping experience is powered by the %{open_food_network}." menu: cart: cart: "Cart" @@ -1555,6 +1563,7 @@ en_NZ: set_a_password: "You will then be prompted to set a password before you are able to administer the enterprise." mistakenly_sent: "Not sure why you have received this email? Please contact %{owner_email} for more information." producer_mail_greeting: "Dear" + producer_mail_text_before: "Please find below an update about the order cycle ready for:" producer_mail_order_text: "Here is a summary of the orders for your products:" producer_mail_delivery_instructions: "Stock pickup/delivery instructions:" producer_mail_signoff: "Thanks and best wishes" @@ -1566,7 +1575,9 @@ en_NZ: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1718,39 +1729,40 @@ en_NZ: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2324,6 +2336,8 @@ en_NZ: payment_processing_failed: "Payment could not be processed, please check the details you entered" payment_method_not_supported: "That payment method is unsupported. Please choose another one." payment_updated: "Payment Updated" + cannot_perform_operation: "Could not update the payment" + action_required: "Action required" inventory_settings: "Inventory Settings" tag_rules: "Tag Rules" shop_preferences: "Shop Preferences" @@ -2385,6 +2399,7 @@ en_NZ: js: saving: 'Saving...' changes_saved: 'Changes saved.' + authorising: "Authorising..." save_changes_first: Save changes first. all_changes_saved: All changes saved unsaved_changes: You have unsaved changes @@ -2592,6 +2607,8 @@ en_NZ: processing: "processing" void: "void" invalid: "invalid" + quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity." + quantity_unchanged: "Quantity unchanged from previous amount." resend_user_email_confirmation: resend: "Resend" sending: "Resend..." @@ -2648,6 +2665,7 @@ en_NZ: min_quantity: "Min quantity" max_quantity: "Max quantity" price_breakdown: "Price breakdown" + unit_price_tooltip: "This is the unit price of this product. It allows you to compare the price of products independent of packaging sizes & weights." variants: on_demand: 'yes': "On demand" @@ -2796,6 +2814,9 @@ en_NZ: start_free_profile: "Start with a basic profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2841,6 +2862,8 @@ en_NZ: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2873,12 +2896,19 @@ en_NZ: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + no_pending_payments: "No pending payments" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" resend: "Resend" back_to_orders_list: "Back To Orders List" + back_to_payments_list: "Back To Payments List" return_authorizations: "Return Authorizations" cannot_create_returns: "Cannot create returns as this order has no shipped units." select_stock: "Select stock" @@ -2952,6 +2982,7 @@ en_NZ: display_currency: "Display currency" choose_currency: "Choose Currency" mail_method_settings: "Mail Method Settings" + mail_settings_notice_html: "Some of the following settings can't be edited and are listed here just for debugging purposes. Changes can be made by updating the instance's secrets and provisioning them using ofn-install. Reach out to the OFN global team for further details." general: "General" enable_mail_delivery: "Enable Mail Delivery" send_mails_as: "Send Mails As" @@ -3049,6 +3080,7 @@ en_NZ: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "SKU" order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3069,6 +3101,7 @@ en_NZ: payment_state: "Payment State" errors: messages: + included_price_validation: "cannot be selected unless you have set a Default Tax Zone" blank: "can't be blank" layouts: admin: @@ -3076,6 +3109,8 @@ en_NZ: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3224,6 +3259,7 @@ en_NZ: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3279,6 +3315,13 @@ en_NZ: deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." providers: provider: "Provider" + check: "Cash/EFT/etc. (payments for which automatic validation is not required)" + pin: "Pin Payments" + paypalexpress: "PayPal Express" + stripeconnect: "Stripe" + stripesca: "Stripe SCA" + bogus: "Bogus" + bogussimple: "BogusSimple" payments: source_forms: stripe: @@ -3297,6 +3340,7 @@ en_NZ: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3367,7 +3411,6 @@ en_NZ: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3379,6 +3422,7 @@ en_NZ: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'eg. 2 kg' @@ -3402,6 +3446,7 @@ en_NZ: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3419,6 +3464,9 @@ en_NZ: or_enter_new_card: "Or, enter details for a new card:" remember_this_card: Remember this card? date_picker: + flatpickr_date_format: "Y-m-d" + flatpickr_datetime_format: "Y-m-d H:i" + today: "Today" now: "Now" orders: error_flash_for_unavailable_items: "An item in your cart has become unavailable. Please update the selected quantities." @@ -3436,6 +3484,7 @@ en_NZ: pending: pending ready: ready shipped: shipped + canceled: canceled payment_states: balance_due: balance due completed: completed @@ -3447,6 +3496,7 @@ en_NZ: processing: processing void: void invalid: invalid + authorise: authorise order_mailer: cancel_email: customer_greeting: "Dear %{name}," @@ -3461,6 +3511,8 @@ en_NZ: cancel_email_for_shop: greeting: "Dear %{name}," subject: "Cancellation of Order" + intro: "A customer has cancelled their order #%{number}." + view_cancelled_order: "View cancelled order" confirm_email: subject: "Order Confirmation" invoice_email: @@ -3479,6 +3531,13 @@ en_NZ: subject: "Reset password instructions" confirmation_instructions: subject: "Please confirm your OFN account" + payment_mailer: + authorize_payment: + subject: "Please authorize your payment to %{distributor} on OFN" + instructions: "Your payment of %{amount} to %{distributor} requires additional authentication. Please visit the following URL to authorize your payment:" + authorization_required: + subject: "A payment requires authorization from the customer" + message: "A payment for order %{order_number} requires additional authorization from the customer. The customer has been notified via email and the payment will appear as pending until it is authorized." shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -3515,7 +3574,23 @@ en_NZ: paused: paused canceled: cancelled paypal: + already_refunded: "This payment has been refunded and no further action can be taken on it." + no_payment_via_admin_backend: "You cannot charge PayPal accounts through the admin backend at this time." + transaction: "PayPal Transaction" + payer_id: "Payer ID" + transaction_id: "Transaction ID" + token: "Token" + refund: "Refund" refund_amount: "Amount" + original_amount: "Original amount: %{amount}" + refund_successful: "PayPal refund successful" + refund_unsuccessful: "PayPal refund unsuccessful" + actions: + refund: "Refund" + flash: + cancel: "Don't want to use PayPal? No problems." + connection_failed: "Could not connect to PayPal." + generic_error: "PayPal failed. %{reasons}" users: form: account_settings: Account Settings @@ -3531,6 +3606,8 @@ en_NZ: past_orders: Past Orders transactions: transaction_history: Transaction History + authorisation_required: Authorisation Required + authorise: Authorize open_orders: order: Order shop: Shop diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index 4e8c126122..0bf6c0604d 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -81,6 +81,7 @@ en_PH: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -113,6 +114,8 @@ en_PH: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -256,7 +259,6 @@ en_PH: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -1110,6 +1112,7 @@ en_PH: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1514,7 +1517,9 @@ en_PH: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Fees" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1657,28 +1662,29 @@ en_PH: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping Cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping Cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." @@ -1686,9 +1692,9 @@ en_PH: few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2701,6 +2707,9 @@ en_PH: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2746,6 +2755,8 @@ en_PH: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2776,7 +2787,13 @@ en_PH: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + no_pending_payments: "No pending payments" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2939,6 +2956,7 @@ en_PH: successfully_updated: '%{resource} has been successfully updated!' payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" + sku: "SKU" actions: update: "Update" cancel: "Cancel" @@ -2956,6 +2974,8 @@ en_PH: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3102,6 +3122,7 @@ en_PH: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" payment_methods: index: @@ -3163,6 +3184,7 @@ en_PH: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3231,7 +3253,6 @@ en_PH: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3243,6 +3264,7 @@ en_PH: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" autocomplete: diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index 0b7a64d68c..8def1ff7f0 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -85,6 +85,11 @@ en_US: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + card_details: "Card details" + card_type: "Card type" + cardholder_name: "Cardholder name" + community_forum_url: "Community forum URL" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -114,11 +119,39 @@ en_US: updated_not_active: "Your password has been reset, but your email has not been confirmed yet." updated: "Your password was changed successfully. You are now signed in." send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + home_page_alert_html: "Home page alert HTML" + hub_signup_case_studies_html: "Hub signup case studies HTML" + hub_signup_detail_html: "Hub signup detail HTML" + hub_signup_pricing_table_html: "Hub signup pricing table HTML" + group_signup_case_studies_html: "Group signup case studies HTML" + group_signup_detail_html: "Group signup detail HTML" + group_signup_pricing_table_html: "Group signup pricing table HTML" + item_description: "Item description" + menu_1_icon_name: "Menu 1 icon name" + menu_2_icon_name: "Menu 2 icon name" + menu_3_icon_name: "Menu 3 icon name" + menu_4_icon_name: "Menu 4 icon name" + menu_5_icon_name: "Menu 5 icon name" + menu_6_icon_name: "Menu 6 icon name" + menu_7_icon_name: "Menu 7 icon name" models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" tax_rate: included_in_price: "Included in price" + open_street_map_enabled: "Open Street Map enabled" + open_street_map_default_latitude: "Open Street Map default latitude" + open_street_map_default_longitude: "Open Street Map default longitude" + open_street_map_provider_name: "Open Street Map provider name" + open_street_map_provider_options: "Open Street Map provider options" + producer_signup_case_studies_html: "Producer signup case studies HTML" + producer_signup_detail_html: "Producer signup detail HTML" + producer_signup_pricing_table_html: "Producer signup pricing table HTML" + producers_social: "Producers social" + resume_order: "Resume order" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -130,7 +163,7 @@ en_US: confirmation_instructions: subject: "Please confirm the email address for %{enterprise}" welcome: - subject: "%{enterprise}is now on %{sitename}" + subject: "%{enterprise} is now on %{sitename}" email_welcome: "Welcome" email_registered: "is now part of" email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}" @@ -144,6 +177,7 @@ en_US: producer_mailer: order_cycle: subject: "Order cycle report for %{producer}" + provider_settings: "Provider settings" shipment_mailer: shipped_email: dear_customer: "Dear Customer," @@ -264,7 +298,7 @@ en_US: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" + invalid_payment_state: "Invalid payment state: %{state}" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -298,8 +332,12 @@ en_US: destroy: "Destroy" rename: "Rename" admin: + adjustments: + skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At begins_on: Begins On + bill_address: "Bill address" + ship_address: "Ship address" customer: Customer date: Date email: Email @@ -1064,6 +1102,7 @@ en_US: index: title: "Subscriptions" new: "New Subscription" + issue: "Issue" new: title: "New Subscription" edit: @@ -1145,6 +1184,7 @@ en_US: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1177,8 +1217,10 @@ en_US: message_html: "I agree to the seller's %{terms_and_conditions_link}." link_text: "Terms and Conditions" platform_terms_of_service: + message_html: "I agree to the platform %{tos_link}." terms_of_service: "Terms of Service" all_terms_and_conditions: + message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}." terms_and_conditions: "Terms and Conditions" terms_of_service: "Terms of Service" failed: "The checkout failed. Please let us know so that we can process your order." @@ -1278,7 +1320,7 @@ en_US: menu_4_title: "Groups" menu_4_url: "/groups" menu_5_title: "About" - menu_5_url: "https://about.openfoodnetwork.net" + menu_5_url: "https://about.openfoodnetwork.net/" menu_6_title: "Connect" menu_6_url: "https://openfoodnetwork.org/au/connect/" menu_7_title: "Learn" @@ -1570,7 +1612,9 @@ en_US: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Producers" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1707,7 +1751,7 @@ en_US: sell_hubs_detail: "Set up a profile for your food enterprise or organization on the OFN. At any time you can upgrade your profile to a multi-producer shop." sell_groups_detail: "Set up a tailored directory of enterprises (producers and other food enterprises) for your region or for your organisation." sell_user_guide: "Find out more in our user guide." - sell_listing_price: "Listing on the OFN is free. When you start selling your products, we invite you to contribute a small percentage of your sales or some volunteer time to help support the platform and the people taking care of it. Please contact us for more information. " + sell_listing_price: "Listing on the OFN is free. When you start selling your products, we invite you to contribute to platform upkeep. For more detail on pricing visit the Software Platform section via the About link in the top menu." sell_embed: "We can also embed an OFN shop in your personal website or build a customized local food network website for your region." sell_ask_services: "Ask us about OFN services." shops_title: Stores @@ -1722,39 +1766,40 @@ en_US: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: - one: An additional item is already confirmed for this order cycle + one: "An additional item is already confirmed for this order cycle" few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2413,6 +2458,7 @@ en_US: There was a problem adding this product to the cart. Perhaps it has become unavailable or the shop is closing. admin: + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ if it includes taxes & fees." enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: got_it: "Got it" @@ -2806,6 +2852,15 @@ en_US: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Allocation" + bulk_coop_customer_payments: "Bulk Co-op Customer Payments" + bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets" + bulk_coop_supplier_report: "Bulk Co-op Supplier Report" + date_range: "Date range" + generate_report: "Generate Report" + report_format_csv: "Report format CSV" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2851,6 +2906,8 @@ en_US: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2883,7 +2940,54 @@ en_US: previous: "Previous" last: "Last" spree: + add_country: "Add country" + add_state: "Add state" + adjustment: "Adjustment" + all: "All" + associated_adjustment_closed: "Associated adjustment closed" + authorization_failure: "Authorization failure" + back_to_adjustments_list: "Back to adjustments" + back_to_users_list: "Back to users" + back_to_zones_list: "Back to zones" + card_code: "Card code" + card_number: "Card number" + category: "Category" + created_successfully: "Created Successfully" + credit: "Credit" + editing_tax_category: "Editing tax category" + editing_tax_rate: "Editing tax rate" + editing_zone: "Editing zone" + expiration: "Expiration" + invalid_payment_provider: "Invalid payment provider" + items_cannot_be_shipped: "Items cannot be shipped" + gateway_config_unavailable: "Gateway config unavailable" + gateway_error: "Payment failed" more: "More" + new_adjustment: "New adjustment" + new_order_completed: "New order completed" + new_tax_category: "New Tax Category" + new_taxon: "New taxon" + new_user: "New user" + no_pending_payments: "No pending payments" + none: "None" + not_found: "Not found" + notice_messages: + variant_deleted: "Variant deleted" + or: "Or" + order_processed_successfully: "Order processed successfully" + payment_method_not_supported: "Payment method not supported" + resend_authorization_email: "Resend authorization email" + rma_credit: "RMA credit" + server_error: "Server error" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Start date" + successfully_removed: "Successfully Removed" + taxonomy_edit: "Taxonomy edit" + taxonomy_tree_error: "Taxonomy tree error" + taxonomy_tree_instruction: "Taxonomy tree instruction" + tree: "Tree" + updating: "Updating" your_order_is_empty_add_product: "Your cart is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2911,6 +3015,7 @@ en_US: tracking_number: "Tracking Number" order_total: "Order Total" customer_details: "Customer Details" + customer_details_updated: "Customer Details updated" customer_search: "Customer Search" choose_a_customer: "Choose a customer" account: "Account" @@ -3061,6 +3166,8 @@ en_US: payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" not_available: "N/A" + sku: "SKU" + there_are_no_items_for_this_order: "There are no items for this order." order_populator: out_of_stock: '%{item} is out of stock.' actions: @@ -3088,7 +3195,17 @@ en_US: login_nav: header: store: Store + validation: + must_be_int: "must be an integer" admin: + mail_methods: + send_testmail: "Send test email" + testmail: + delivery_success: "Test email sent." + error: "An error occurred trying to send the test email." + unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ if it includes taxes & fees." + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3157,6 +3274,8 @@ en_US: received: "Received" canceled: "Canceled" orders: + add_product: + cannot_add_item_to_canceled_order: "Cannot add item to canceled order" index: listing_orders: "Listing Orders" new_order: "New Order" @@ -3199,6 +3318,10 @@ en_US: overview: enterprises_header: ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organization within the Open Food Network. + enterprise_row: + has_no_enterprise_fees: "has no enterprise fees" + has_no_payment_methods: "has no payment methods" + has_no_shipping_methods: "has no shipping methods" products: active_products: zero: "You don't have any active products." @@ -3237,6 +3360,7 @@ en_US: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" @@ -3317,6 +3441,8 @@ en_US: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" + unit_price_legend: "Calculated based on the item price" on_hand: "On Hand" on_demand: "On Demand" product_description: "Product Description" @@ -3387,7 +3513,6 @@ en_US: price: "Price" options: "Options" no_results: "No results" - to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" option_values: "Option Values" and: "and" @@ -3399,6 +3524,7 @@ en_US: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" display_name: "Display Name" display_as_placeholder: 'For example, 2 kg' @@ -3422,6 +3548,7 @@ en_US: cookies_consent_banner_toggle: "Display cookies consent banner" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Enterprises must accept Terms of Service" + shoppers_require_tos: "Shoppers must accept Terms of Service" cookies_policy_matomo_section: "Display Matomo section on cookies policy page" footer_tos_url: "Terms of Service URL" checkout: @@ -3634,3 +3761,42 @@ en_US: spree/payment: one: Payment other: Payments + datetime: + distance_in_words: + about_x_hours: + one: about 1 hour + other: about %{count} hours + about_x_months: + one: about 1 month + other: about %{count} months + about_x_years: + one: about 1 year + other: about %{count} years + almost_x_years: + one: almost 1 year + other: almost %{count} years + half_a_minute: half a minute + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + over_x_years: + one: over 1 year + other: over %{count} years + x_seconds: + one: "1 second" + other: "%{count} seconds" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 day" + other: "%{count} days" + x_months: + one: "1 month" + other: "%{count} months" + x_years: + one: "1 year" + other: "%{count} years" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 123a1dc191..5996667bdf 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -81,6 +81,7 @@ en_ZA: no_default_card: "^No default card available for this customer" shipping_method: not_available_to_shop: "is not available to %{shop}" + customer_instructions: "Customer instructions" devise: confirmations: send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." @@ -113,6 +114,8 @@ en_ZA: models: order_cycle: cloned_order_cycle_name: "COPY OF %{order_cycle}" + sku: "SKU" + tax_rate: "Tax rate" validators: date_time_string_validator: not_string_error: "must be a string" @@ -256,7 +259,6 @@ en_ZA: error: Error processing_payment: "Processing payment..." no_pending_payments: "No pending payments" - invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -1112,6 +1114,7 @@ en_ZA: yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure + number: "Number" order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. no_results: no_subscriptions: No subscriptions yet... @@ -1520,7 +1523,9 @@ en_ZA: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" + shopping_tabs_producers: "Pricing" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groups" shopping_contact_address: "Address" shopping_contact_web: "Contact" shopping_contact_social: "Follow" @@ -1670,28 +1675,29 @@ en_ZA: shops_signup_help: We're ready to help. shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. shops_signup_detail: Here's the detail. - orders: Orders - orders_fees: Fees... - orders_edit_title: Shopping cart - orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for - orders_edit_continue: Continue shopping - orders_edit_checkout: Checkout + orders: "Orders" + orders_fees: "Fees..." + orders_edit_title: "Shopping cart" + orders_edit_headline: "Your shopping cart" + orders_edit_time: "Order ready for" + orders_edit_continue: "Continue shopping" + orders_edit_checkout: "Checkout" orders_form_empty_cart: "Empty cart" - orders_form_subtotal: Produce subtotal - orders_form_admin: Admin & Handling - orders_form_total: Total - orders_oc_expired_headline: Orders have closed for this order cycle + orders_form_update_cart: "Update" + orders_form_subtotal: "Produce subtotal" + orders_form_admin: "Admin & Handling" + orders_form_total: "Total" + orders_oc_expired_headline: "Orders have closed for this order cycle" orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." orders_oc_expired_text_link: "or see the other order cycles available at this hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Phone:" - orders_show_title: Order Confirmation - orders_show_time: Order ready on + orders_show_title: "Order Confirmation" + orders_show_time: "Order ready on" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: Cancelled - orders_show_confirmed: Confirmed + orders_show_cancelled: "Cancelled" + orders_show_confirmed: "Confirmed" orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." @@ -1699,9 +1705,9 @@ en_ZA: few: "%{count} additional items already confirmed for this order cycle" many: "%{count} additional items already confirmed for this order cycle" other: "%{count} additional items already confirmed for this order cycle" - orders_bought_edit_button: Edit confirmed items + orders_bought_edit_button: "Edit confirmed items" orders_bought_already_confirmed: "* already confirmed" - orders_confirm_cancel: Are you sure you want to cancel this order? + orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." @@ -2648,6 +2654,9 @@ en_ZA: start_free_profile: "Start with a free profile, and expand when you're ready!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generate Report" enterprise_fee_summaries: filters: date_range: "Date Range" @@ -2693,6 +2702,8 @@ en_ZA: tax_category_name: "Tax Category" total_amount: "$$ SUM" invalid_filter_parameters: "The filters you selected for this report are invalid." + report: + none: "None" order: "Order" distribution: "Distribution" order_details: "Order Details" @@ -2722,7 +2733,13 @@ en_ZA: previous: "Previous" last: "Last" spree: + all: "All" + category: "Category" + credit: "Credit" more: "More" + no_pending_payments: "No pending payments" + none: "None" + updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" @@ -2873,6 +2890,7 @@ en_ZA: successfully_updated: '%{resource} has been successfully updated!' payment_method: "Payment Method" payment_processing_failed: "Payment could not be processed, please check the details you entered" + sku: "SKU" actions: update: "Update" cancel: "Cancel" @@ -2890,6 +2908,8 @@ en_ZA: header: store: Store admin: + subscriptions: + number: "Number" tab: dashboard: "Dashboard" orders: "Orders" @@ -3006,6 +3026,7 @@ en_ZA: back_to_shipping_methods_list: "Back To Shipping Methods List" form: categories: "Categories" + tax_category: "Tax Category" zones: "Zones" payment_methods: index: @@ -3067,6 +3088,7 @@ en_ZA: value: "Value" unit_name: "Unit name" price: "Price" + unit_price: "Unit Price" on_hand: "In Stock" on_demand: "Unlimited" product_description: "Product Description" @@ -3139,6 +3161,7 @@ en_ZA: form: sku: "SKU" price: "Price" + unit_price: "Unit Price" display_as: "Display As" autocomplete: out_of_stock: "Out of Stock" diff --git a/config/locales/es.yml b/config/locales/es.yml index bbeddb4f0f..53d5579e1e 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -85,6 +85,11 @@ es: no_default_card: "^ Ninguna tarjeta predeterminada disponible para esta consumidora" shipping_method: not_available_to_shop: "no está disponible para %{shop}" + card_details: "Detalles de tarjeta" + card_type: "Tipo de tarjeta" + cardholder_name: "Nombre del titular de la tarjeta" + community_forum_url: "URL del foro de la comunidad" + customer_instructions: "Instrucciones del Consumidor" devise: confirmations: send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." @@ -114,11 +119,39 @@ es: updated_not_active: "Su contraseña ha sido restablecida, pero su correo electrónico aún no ha sido confirmado." updated: "Su contraseña ha sido cambiada con éxito. Ya tienes la sesión iniciada." send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + home_page_alert_html: "HTML de alerta de página de inicio" + hub_signup_case_studies_html: "HTML casos de estudio de registro de hub" + hub_signup_detail_html: "HTML detalle de registro de hub" + hub_signup_pricing_table_html: "HTML tabla de precios de registro de hub" + group_signup_case_studies_html: "HTML casos de estudio de registro de grupo" + group_signup_detail_html: "HTML detalle de registro de grupo" + group_signup_pricing_table_html: "HTML tabla de precios de registro de grupo" + item_description: "Descripción del artículo" + menu_1_icon_name: "Nombre del icono del menú 1" + menu_2_icon_name: "Nombre del icono del menú 2" + menu_3_icon_name: "Nombre del icono del menú 3" + menu_4_icon_name: "Nombre del icono del menú 4" + menu_5_icon_name: "Nombre del icono del menú 5" + menu_6_icon_name: "Nombre del icono del menú 6" + menu_7_icon_name: "Nombre del icono del menú 7" models: order_cycle: cloned_order_cycle_name: "COPIA DE %{order_cycle}" tax_rate: included_in_price: "Incluido en el precio" + open_street_map_enabled: "Open Street Map habilitado" + open_street_map_default_latitude: "Latitud predeterminada de Open Street Map" + open_street_map_default_longitude: "Longitud predeterminada de Open Street Map" + open_street_map_provider_name: "Nombre del proveedor de Open Street Map" + open_street_map_provider_options: "Opciones de proveedor de Open Street Map" + producer_signup_case_studies_html: "HTML casos de estudio de registro de productoras" + producer_signup_detail_html: "HTML detalle de registro de productora" + producer_signup_pricing_table_html: "HTML de tabla de precios de registro de productora" + producers_social: "Razón social de la productora" + resume_order: "Reanudar pedido" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "% Impuestos" validators: date_time_string_validator: not_string_error: "debe ser una cadena" @@ -144,6 +177,7 @@ es: producer_mailer: order_cycle: subject: "Informe Ciclo de Pedido para %{producer}" + provider_settings: "Configuración del proveedor" shipment_mailer: shipped_email: dear_customer: "Estimada consumidora," @@ -264,7 +298,7 @@ es: error: Error processing_payment: "Procesando el pago..." no_pending_payments: "No tiene pagos pendientes" - invalid_payment_state: "Estado de pago no válido" + invalid_payment_state: "Estado de pago inválido: %{state}" filter_results: Filtrar resultados quantity: Cantidad pick_up: Recogida @@ -298,8 +332,12 @@ es: destroy: "Eliminar" rename: "Renombrar" admin: + adjustments: + skipped_changing_canceled_order: "No puede cambiar un pedido cancelado." begins_at: Empieza en begins_on: Comienza en + bill_address: "Dirección de factura" + ship_address: "Dirección de envío" customer: Consumidora date: Fecha email: Email @@ -1066,6 +1104,7 @@ es: index: title: "Suscripciones" new: "Nueva suscripción" + issue: "Incidéncia" new: title: "Nueva suscripción" edit: @@ -1147,6 +1186,7 @@ es: yes_cancel_them: Cancelarlos no_keep_them: Guárdalos yes_i_am_sure: Sí estoy seguro + number: "Número" order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. no_results: no_subscriptions: Aún no hay suscripciones ... @@ -1179,8 +1219,10 @@ es: message_html: "Acepto el %{terms_and_conditions_link} del vendedor." link_text: "Términos y Condiciones" platform_terms_of_service: + message_html: "Acepto los %{tos_link} de la plataforma." terms_of_service: "Términos de servicio" all_terms_and_conditions: + message_html: "Acepto el %{terms_and_conditions_link} del vendedor y la plataforma %{tos_link}." terms_and_conditions: "Términos y Condiciones" terms_of_service: "Términos de servicio" failed: "La finalización de compra falló, por favor comunicate con nosotros para procesar la orden." @@ -1572,7 +1614,9 @@ es: shopping_tabs_home: "Inicio" shopping_tabs_shop: "Tienda" shopping_tabs_about: "Acerca de" + shopping_tabs_producers: "Productoras" shopping_tabs_contact: "Contacto" + shopping_tabs_groups: "Redes" shopping_contact_address: "Dirección" shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" @@ -1724,39 +1768,40 @@ es: shops_signup_help: Estamos listos para ayudar. shops_signup_help_text: Usted necesita un mejor retorno. Usted necesita nuevos compradores y socios de logística. Usted necesita que su historia sea contada a través de ventas al por mayor, al detalle y en la mesa de la cocina. shops_signup_detail: Aquí está el detalle. - orders: Pedidos - orders_fees: Comisiones... - orders_edit_title: Carrito de compras - orders_edit_headline: Su carrito de compras - orders_edit_time: Pedido listo para - orders_edit_continue: Continuar comprando - orders_edit_checkout: Validar + orders: "Pedidos" + orders_fees: "Comisiones..." + orders_edit_title: "Carrito de compras" + orders_edit_headline: "Su carrito de compras" + orders_edit_time: "Pedido listo para" + orders_edit_continue: "Continuar comprando" + orders_edit_checkout: "Validar" orders_form_empty_cart: "Vaciar carrito" - orders_form_subtotal: Subtotal de productos - orders_form_admin: Administrar y Gestionar - orders_form_total: Total - orders_oc_expired_headline: Los pedidos están cerrados para este ciclo + orders_form_update_cart: "Actualizar" + orders_form_subtotal: "Subtotal de productos" + orders_form_admin: "Administrar y Gestionar" + orders_form_total: "Total" + orders_oc_expired_headline: "Los pedidos están cerrados para este ciclo" orders_oc_expired_text: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos." orders_oc_expired_text_others_html: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos %{link}." orders_oc_expired_text_link: "o visitar otros ciclos de pedidos disponibles en este grupo de consumo" orders_oc_expired_email: "Correo electrónico:" orders_oc_expired_phone: "Teléfono:" - orders_show_title: Confirmación del pedido - orders_show_time: Pedido listo en + orders_show_title: "Confirmación del pedido" + orders_show_time: "Pedido listo en" orders_show_order_number: "Pedido #%{number}" - orders_show_cancelled: Cancelado - orders_show_confirmed: Confirmado + orders_show_cancelled: "Cancelado" + orders_show_confirmed: "Confirmado" orders_your_order_has_been_cancelled: "Su pedido ha sido cancelado" orders_could_not_cancel: "Lo sentimos, no se pudo cancelar el pedido" orders_cannot_remove_the_final_item: "No se puede quitar el último artículo de un pedido, en su lugar, por favor cancele el pedido." orders_bought_items_notice: - one: Ya se ha confirmado un artículo adicional para este ciclo de pedido + one: "Ya se ha confirmado un artículo adicional para este ciclo de pedido" few: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" many: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" other: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" - orders_bought_edit_button: Editar artículos confirmados + orders_bought_edit_button: "Editar artículos confirmados" orders_bought_already_confirmed: "* ya confirmados" - orders_confirm_cancel: Seguro que desea cancelar este pedido? + orders_confirm_cancel: "Seguro que desea cancelar este pedido?" order_processed_successfully: "Su pedido ha sido procesado con éxito." products_cart_distributor_choice: "Distribuidora para tu pedido:" products_cart_distributor_change: "Su distribuidora para este pedido se cambiará a %{name} si agregas este producto al carrito." @@ -2415,6 +2460,7 @@ es: Ha habido un problema al añadir este producto en el carrito. Puede que haya dejado de estar disponible o que la tinda haya cerrado. admin: + unit_price_tooltip: "El precio unitario aumenta la transparencia al permitir a sus clientes comparar fácilmente los precios entre diferentes productos y tamaños de envase. Tenga en cuenta que el precio unitario final que se muestra en el escaparate puede diferir, ya que incluye impuestos y tarifas." enterprise_limit_reached: "Has alcanzado el límite estándar de organizaciones por cuenta. Escriba a %{contact_email} si necesita aumentarlo." modals: got_it: "Lo entiendo" @@ -2810,6 +2856,15 @@ es: start_free_profile: "Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Compra grupal - Assignación" + bulk_coop_customer_payments: "Compra grupal - Pagos de las consumidoras" + bulk_coop_packing_sheets: "Compra grupal - Hojas de embalaje" + bulk_coop_supplier_report: "Compra grupal - Totales por proveedor" + date_range: "Rango de fechas" + generate_report: "Generar informe" + report_format_csv: "Descargar como CSV" enterprise_fee_summaries: filters: date_range: "Rango de fechas" @@ -2855,6 +2910,8 @@ es: tax_category_name: "Categoría de impuestos" total_amount: "€€ SUM" invalid_filter_parameters: "Los filtros que seleccionó para este informe no son válidos." + report: + none: "Ninguno" order: "Pedido" distribution: "Distribución" order_details: "Detalles del pedido" @@ -2887,7 +2944,54 @@ es: previous: "Anterior" last: "Último" spree: + add_country: "Agregar pais" + add_state: "Agregar estado" + adjustment: "Ajuste" + all: "Todos" + associated_adjustment_closed: "Ajuste asociado cerrado" + authorization_failure: "Fallo de autorización" + back_to_adjustments_list: "Volver a ajustes" + back_to_users_list: "Volver a los usuarios" + back_to_zones_list: "Volver a zonas" + card_code: "Código de la tarjeta" + card_number: "Número de tarjeta" + category: "Categoría" + created_successfully: "Creado con éxito" + credit: "Crédito" + editing_tax_category: "Editando categoría fiscal" + editing_tax_rate: "Editando la tasa de impuestos" + editing_zone: "Editando zona" + expiration: "Vencimiento" + invalid_payment_provider: "Proveedor de pago inválido" + items_cannot_be_shipped: "Los artículos no se pueden enviar" + gateway_config_unavailable: "Configuración de la pasarela no disponible" + gateway_error: "Pago fallido" more: "Más" + new_adjustment: "Nuevo ajuste" + new_order_completed: "Nuevo pedido completado" + new_tax_category: "Nueva categoría de impuestos" + new_taxon: "Nuevo taxón" + new_user: "Nuevo usuario" + no_pending_payments: "No tiene pagos pendientes" + none: "Ninguno" + not_found: "No encontrado" + notice_messages: + variant_deleted: "Variante eliminada" + or: "O" + order_processed_successfully: "Pedido procesado correctamente" + payment_method_not_supported: "Método de pago no admitido" + resend_authorization_email: "Reenviar correo electrónico de autorización" + rma_credit: "Crédito RMA" + server_error: "Error del Servidor" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Fecha de inicio" + successfully_removed: "Eliminado con éxito" + taxonomy_edit: "editar taxonomía" + taxonomy_tree_error: "Error del árbol de taxonomía" + taxonomy_tree_instruction: "Instrucción del árbol de taxonomía" + tree: "Árbol" + updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" name_or_sku: "Nombre o código SKU (ingrese al menos los primeros 4 caracteres del nombre del producto)" @@ -2915,6 +3019,7 @@ es: tracking_number: "Número de seguimiento" order_total: "Total del pedido" customer_details: "Detalles de la consumidora" + customer_details_updated: "Datos de la consumidora actualizados" customer_search: "Búsqueda de consumidores" choose_a_customer: "Elige una consumidora " account: "Cuenta" @@ -3065,6 +3170,8 @@ es: payment_method: "Método de pago" payment_processing_failed: "No se pudo procesar el pago, por favor verifique los detalles que introdujo" not_available: "No disponible" + sku: "SKU" + there_are_no_items_for_this_order: "No hay artículos para este pedido." order_populator: out_of_stock: '%{item} está agotado.' actions: @@ -3092,7 +3199,17 @@ es: login_nav: header: store: Tienda + validation: + must_be_int: "debe ser un entero" admin: + mail_methods: + send_testmail: "Enviar correo electrónico de prueba" + testmail: + delivery_success: "Se envió el correo electrónico de prueba." + error: "Se produjo un error al intentar enviar el correo electrónico de prueba." + unit_price_tooltip: "El precio unitario aumenta la transparencia al permitir a sus clientes comparar fácilmente los precios entre diferentes productos y tamaños de envase. Tenga en cuenta que el precio unitario final que se muestra en el escaparate puede diferir, ya que incluye impuestos y tarifas." + subscriptions: + number: "Número" tab: dashboard: "Panel de inicio" orders: "Pedidos" @@ -3161,6 +3278,8 @@ es: received: "recibido" canceled: "cancelado" orders: + add_product: + cannot_add_item_to_canceled_order: "No se puede agregar el artículo al pedido cancelado" index: listing_orders: "Pedidos de listado" new_order: "Nuevo pedido" @@ -3203,6 +3322,10 @@ es: overview: enterprises_header: ofn_with_tip: Las Organizaciones son Productoras y/o Grupos y son la unidad básica de organización dentro de la Open Food Network. + enterprise_row: + has_no_enterprise_fees: "no tiene comisiones de organización" + has_no_payment_methods: "no tiene métodos de pago" + has_no_shipping_methods: "no tiene métodos de envío" products: active_products: zero: "No tienes ningún producto activo" @@ -3241,6 +3364,7 @@ es: back_to_shipping_methods_list: "Volver a la lista de métodos de envío" form: categories: "Categorías" + tax_category: "Categoría de impuestos" zones: "Zonas" both: "Tanto en Hacer pedido como en Administración" back_end: "Solo en Administración" @@ -3321,6 +3445,8 @@ es: value: "Valor" unit_name: "Nombre de la unidad" price: "Precio" + unit_price: "Precio por unidad" + unit_price_legend: "Calculado en base al precio del artículo" on_hand: "Disponibles" on_demand: "Bajo demanda" product_description: "Descripción del producto" @@ -3391,7 +3517,6 @@ es: price: "Precio" options: "Opciones" no_results: "No hay resultados" - to_add_variants_you_must_first_define: "para agregar variantes, se debe primero definir" option_types: "Tipos de opciones" option_values: "valores de opción" and: "y" @@ -3403,6 +3528,7 @@ es: form: sku: "SKU" price: "Precio" + unit_price: "Precio por unidad" display_as: "Mostrar como" display_name: "Nombre para mostrar" display_as_placeholder: 'p. ej. 2 Kg' @@ -3426,6 +3552,7 @@ es: cookies_consent_banner_toggle: "Mostrar el banner de consentimiento de cookies" privacy_policy_url: "Vínculo con la Política de privacidad" enterprises_require_tos: "Las organizaciones deben aceptar los Términos del Servicio" + shoppers_require_tos: "Los compradores deben aceptar los términos de servicio" cookies_policy_matomo_section: "Mostrar la sección de Matomo en la página de política de cookies" footer_tos_url: "URL de términos y servicios" checkout: @@ -3638,3 +3765,42 @@ es: spree/payment: one: Pago other: Pagos + datetime: + distance_in_words: + about_x_hours: + one: alrededor de 1 hora + other: aprox. %{count} horas + about_x_months: + one: alrededor de 1 mes + other: aprox. %{count} meses + about_x_years: + one: alrededor de 1 año + other: aprox. %{count} años + almost_x_years: + one: casi 1 año + other: casi %{count} años + half_a_minute: medio minuto + less_than_x_seconds: + one: menos de 1 segundo + other: menos de %{count} segundos + less_than_x_minutes: + one: menos de un minuto + other: menos de %{count} minutos + over_x_years: + one: más de 1 año + other: más de %{count} años + x_seconds: + one: "1 segundo" + other: "%{count} segundos" + x_minutes: + one: "1 minuto" + other: "%{count} minutos" + x_days: + one: "1 día" + other: "%{count} días" + x_months: + one: "1 mes" + other: "%{count} meses" + x_years: + one: "1 año" + other: "%{count} años" diff --git a/config/locales/es_CO.yml b/config/locales/es_CO.yml index 079928f7d1..b6a0fc313f 100644 --- a/config/locales/es_CO.yml +++ b/config/locales/es_CO.yml @@ -82,6 +82,7 @@ es_CO: no_default_card: "^No hay una tarjeta predeterminada disponible para este cliente" shipping_method: not_available_to_shop: "no está disponible para %{shop}" + customer_instructions: "Instrucciones del cliente" devise: confirmations: send_instructions: "En unos minutos recibirá un correo electrónico con instrucciones sobre cómo confirmar su cuenta." @@ -114,6 +115,8 @@ es_CO: models: order_cycle: cloned_order_cycle_name: "COPIA DE %{order_cycle}" + sku: "SKU" + tax_rate: "Tarifa de impuestos" validators: date_time_string_validator: not_string_error: "debe ser una cadena" @@ -186,7 +189,7 @@ es_CO: home: "OFN" title: "Open Food Network" welcome_to: "Bienvenido a" - site_meta_description: "Nosotros empezamos desde abajo. Con granjeros y productores listos para contar sus historias con orgullo y autenticidad. Con distribuidores listos para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..." + site_meta_description: "Nosotros empezamos desde abajo. Con cultivadores y productores listos para contar sus historias con orgullo y autenticidad. Con distribuidores listos para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..." search_by_name: Buscar por nombre o municipio... producers_join: Los productores colombianos ahora son bienvenidos a unirse a Open Food Network. charges_sales_tax: ¿Cargos de IVA? @@ -259,7 +262,6 @@ es_CO: error: Error processing_payment: "Procesando el pago..." no_pending_payments: "No tiene pagos pendientes" - invalid_payment_state: "Estado de pago no válido" filter_results: Filtrar resultados quantity: Cantidad pick_up: Recoger @@ -1127,6 +1129,7 @@ es_CO: yes_cancel_them: Cancelarlos no_keep_them: Guárdalos yes_i_am_sure: Si, estoy seguro + number: "Número" order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. no_results: no_subscriptions: Aún no hay suscripciones ... @@ -1249,11 +1252,11 @@ es_CO: menu_4_title: "Grupos" menu_4_url: "/groups" menu_5_title: "Acerca de" - menu_5_url: "https://about.openfoodnetwork.org.au/" + menu_5_url: "https://cutt.ly/Sporos-openfoodcolombia" menu_6_title: "Conectar" menu_6_url: " " menu_7_title: "Aprender" - menu_7_url: " " + menu_7_url: " https://www.facebook.com/groups/ofncolombia" logo: "Logo (640x130)" logo_mobile: "Logo para móvil (75x26)" logo_mobile_svg: "Logo para móvil (SVG)" @@ -1540,7 +1543,9 @@ es_CO: shopping_tabs_home: "Bienvenidos" shopping_tabs_shop: "Tienda" shopping_tabs_about: "Acerca de" + shopping_tabs_producers: "Productoras" shopping_tabs_contact: "Contacto" + shopping_tabs_groups: "Grupos" shopping_contact_address: "Dirección" shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" @@ -1690,28 +1695,29 @@ es_CO: shops_signup_help: Estamos listos para ayudar. shops_signup_help_text: Usted necesita un mejor retorno. Usted necesita nuevos compradores y socios de logística. Usted necesita que su historia sea contada a través de ventas al por mayor, al detalle y en la mesa de la cocina. shops_signup_detail: Aquí está el detalle. - orders: Pedidos - orders_fees: Comisiones... - orders_edit_title: Carrito de compras - orders_edit_headline: Su carrito de compras - orders_edit_time: Pedido listo para - orders_edit_continue: Continuar comprando - orders_edit_checkout: Validar + orders: "Pedidos" + orders_fees: "Comisiones..." + orders_edit_title: "Carrito de compras" + orders_edit_headline: "Su carrito de compras" + orders_edit_time: "Pedido listo para" + orders_edit_continue: "Continuar comprando" + orders_edit_checkout: "Validar" orders_form_empty_cart: "Vaciar carrito" - orders_form_subtotal: Subtotal de productos - orders_form_admin: Administrar y Gestionar - orders_form_total: Total - orders_oc_expired_headline: Los pedidos están cerrados para este ciclo + orders_form_update_cart: "Actualizar" + orders_form_subtotal: "Subtotal de productos" + orders_form_admin: "Administrar y Gestionar" + orders_form_total: "Total" + orders_oc_expired_headline: "Los pedidos están cerrados para este ciclo" orders_oc_expired_text: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu nodo directamente para ver si pueden aceptar pedidos tardíos." orders_oc_expired_text_others_html: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu nodo directamente para ver si pueden aceptar pedidos tardíos %{link}." orders_oc_expired_text_link: "o vea los otros ciclos de pedidos disponibles en este nodo" orders_oc_expired_email: "Correo electrónico:" orders_oc_expired_phone: "Teléfono:" - orders_show_title: Confirmación del pedido - orders_show_time: Pedido listo en + orders_show_title: "Confirmación del pedido" + orders_show_time: "Pedido listo en" orders_show_order_number: "Pedido #%{number}" - orders_show_cancelled: Cancelado - orders_show_confirmed: Confirmado + orders_show_cancelled: "Cancelado" + orders_show_confirmed: "Confirmado" orders_your_order_has_been_cancelled: "Su pedido ha sido cancelado" orders_could_not_cancel: "Lo sentimos, no se pudo cancelar el pedido" orders_cannot_remove_the_final_item: "No se puede quitar el último artículo de un pedido, en su lugar, por favor cancele el pedido." @@ -1719,9 +1725,9 @@ es_CO: few: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" many: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" other: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" - orders_bought_edit_button: Editar artículos confirmados + orders_bought_edit_button: "Editar artículos confirmados" orders_bought_already_confirmed: "* ya confirmados" - orders_confirm_cancel: Seguro que desea cancelar este pedido? + orders_confirm_cancel: "Seguro que desea cancelar este pedido?" order_processed_successfully: "Su pedido ha sido procesado con éxito." products_cart_distributor_choice: "Distribuidora para tu pedido:" products_cart_distributor_change: "Su distribuidora para este pedido se cambiará a %{name} si agregas este producto al carrito." @@ -2753,6 +2759,9 @@ es_CO: start_free_profile: "¡Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generar reporte" enterprise_fee_summaries: filters: date_range: "Rango de fechas" @@ -2798,6 +2807,8 @@ es_CO: tax_category_name: "Categoría de impuestos" total_amount: "$$ SUM" invalid_filter_parameters: "Los filtros que seleccionó para este reporte no son válidos." + report: + none: "Ninguno" order: "Pedido" distribution: "Distribución" order_details: "Detalles del pedido" @@ -2830,7 +2841,13 @@ es_CO: previous: "Anterior" last: "Último" spree: + all: "Todos" + category: "Categoría" + credit: "Crédito" more: "Más" + no_pending_payments: "No tiene pagos pendientes" + none: "Ninguno" + updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" name_or_sku: "Nombre o código SKU (ingrese al menos los primeros 4 caracteres del nombre del producto)" @@ -2999,6 +3016,7 @@ es_CO: successfully_updated: '%{resource} ha sido actualizado exitosamente!' payment_method: "Método de pago" payment_processing_failed: "No se pudo procesar el pago, por favor verifique los detalles que introdujo" + sku: "SKU" actions: update: "Actualizar" cancel: "Cancelar" @@ -3019,6 +3037,8 @@ es_CO: header: store: Tienda admin: + subscriptions: + number: "Número" tab: dashboard: "Panel de inicio" orders: "Pedidos" @@ -3167,6 +3187,7 @@ es_CO: back_to_shipping_methods_list: "Volver a la lista de métodos de envío" form: categories: "Categorías" + tax_category: "Categoría de impuestos" zones: "Zonas" both: "Tanto Checkout como Back office" back_end: "Back office solamente" @@ -3240,6 +3261,7 @@ es_CO: value: "Valor" unit_name: "Nombre de la unidad" price: "Precio" + unit_price: "Precio por unidad" on_hand: "Disponibles" on_demand: "Bajo demanda" product_description: "Descripción del producto" @@ -3310,7 +3332,6 @@ es_CO: price: "Precio" options: "Opciones" no_results: "No hay resultados" - to_add_variants_you_must_first_define: "Para agregar variantes, usted debe primero definir" option_types: "Tipos de opciones" option_values: "Valores de opción" and: "y" @@ -3322,6 +3343,7 @@ es_CO: form: sku: "SKU" price: "Precio" + unit_price: "Precio por unidad" display_as: "Mostrar como" display_name: "Nombre para mostrar" display_as_placeholder: 'p.ej. 2 kilogramos' diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index deb450048b..6158f374fe 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -81,6 +81,7 @@ es_CR: no_default_card: "^No hay una tarjeta predeterminada disponible para este cliente" shipping_method: not_available_to_shop: "no está disponible para %{shop}" + customer_instructions: "Instrucciones del cliente" devise: confirmations: send_instructions: "En unos minutos recibirá un correo electrónico con instrucciones sobre cómo confirmar su cuenta." @@ -113,6 +114,8 @@ es_CR: models: order_cycle: cloned_order_cycle_name: "COPIA DE %{order_cycle}" + sku: "SKU" + tax_rate: "Tarifa de impuestos" validators: date_time_string_validator: not_string_error: "debe ser una cadena" @@ -256,7 +259,6 @@ es_CR: error: Error processing_payment: "Procesando el pago..." no_pending_payments: "No tiene pagos pendientes" - invalid_payment_state: "Estado de pago no válido" filter_results: Filtrar resultados quantity: Cantidad pick_up: Recoger @@ -1113,6 +1115,7 @@ es_CR: yes_cancel_them: Cancelarlos no_keep_them: Guárdalos yes_i_am_sure: Sí estoy seguro + number: "Número" order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. no_results: no_subscriptions: Aún no hay suscripciones ... @@ -1517,7 +1520,9 @@ es_CR: shopping_tabs_home: "Inicio" shopping_tabs_shop: "Tienda" shopping_tabs_about: "Acerca de" + shopping_tabs_producers: "Productores" shopping_tabs_contact: "Contacto" + shopping_tabs_groups: "Grupos" shopping_contact_address: "Dirección" shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" @@ -1660,28 +1665,29 @@ es_CR: shops_signup_help: Estamos listos para ayudar. shops_signup_help_text: Usted necesita un mejor retorno. Usted necesita nuevos compradores y socios de logística. Usted necesita que su historia sea contada a través de ventas al por mayor, al detalle y en la mesa de la cocina. shops_signup_detail: Aquí está el detalle. - orders: Pedidos - orders_fees: Comisiones... - orders_edit_title: Carrito de compras - orders_edit_headline: Su carrito de compras - orders_edit_time: Pedido listo para - orders_edit_continue: Continuar comprando - orders_edit_checkout: Validar + orders: "Pedidos" + orders_fees: "Comisiones..." + orders_edit_title: "Carrito de compras" + orders_edit_headline: "Su carrito de compras" + orders_edit_time: "Pedido listo para" + orders_edit_continue: "Continuar comprando" + orders_edit_checkout: "Validar" orders_form_empty_cart: "Vaciar carrito" - orders_form_subtotal: Subtotal de productos - orders_form_admin: Administrar y Gestionar - orders_form_total: Total - orders_oc_expired_headline: Los pedidos están cerrados para este ciclo + orders_form_update_cart: "Actualizar" + orders_form_subtotal: "Subtotal de productos" + orders_form_admin: "Administrar y Gestionar" + orders_form_total: "Total" + orders_oc_expired_headline: "Los pedidos están cerrados para este ciclo" orders_oc_expired_text: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos." orders_oc_expired_text_others_html: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos %{link}." orders_oc_expired_text_link: "o visitar otros ciclos de pedidos disponibles en este grupo de consumo" orders_oc_expired_email: "Correo electrónico:" orders_oc_expired_phone: "Teléfono:" - orders_show_title: Confirmación del pedido - orders_show_time: Pedido listo en + orders_show_title: "Confirmación del pedido" + orders_show_time: "Pedido listo en" orders_show_order_number: "Pedido #%{number}" - orders_show_cancelled: Cancelado - orders_show_confirmed: Confirmado + orders_show_cancelled: "Cancelado" + orders_show_confirmed: "Confirmado" orders_your_order_has_been_cancelled: "Su pedido ha sido cancelado" orders_could_not_cancel: "Lo sentimos, no se pudo cancelar el pedido" orders_cannot_remove_the_final_item: "No se puede quitar el último artículo de un pedido, en su lugar, por favor cancele el pedido." @@ -1689,9 +1695,9 @@ es_CR: few: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" many: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" other: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" - orders_bought_edit_button: Editar artículos confirmados + orders_bought_edit_button: "Editar artículos confirmados" orders_bought_already_confirmed: "* ya confirmados" - orders_confirm_cancel: Seguro que desea cancelar este pedido? + orders_confirm_cancel: "Seguro que desea cancelar este pedido?" order_processed_successfully: "Su pedido ha sido procesado con éxito." products_cart_distributor_choice: "Distribuidora para tu pedido:" products_cart_distributor_change: "Su distribuidora para este pedido se cambiará a %{name} si agregas este producto al carrito." @@ -2709,6 +2715,9 @@ es_CR: start_free_profile: "¡Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generar reporte" enterprise_fee_summaries: filters: date_range: "Rango de fechas" @@ -2754,6 +2763,8 @@ es_CR: tax_category_name: "Categoría de impuestos" total_amount: "€€ SUM" invalid_filter_parameters: "Los filtros que seleccionó para este reporte no son válidos." + report: + none: "Ninguno" order: "Pedido" distribution: "Distribución" order_details: "Detalles del pedido" @@ -2784,7 +2795,13 @@ es_CR: previous: "Anterior" last: "Último" spree: + all: "Todos" + category: "Categoría" + credit: "Crédito" more: "Más" + no_pending_payments: "No tiene pagos pendientes" + none: "Ninguno" + updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" name_or_sku: "Nombre o código SKU (ingrese al menos los primeros 4 caracteres del nombre del producto)" @@ -2947,6 +2964,7 @@ es_CR: successfully_updated: '%{resource} ha sido actualizado exitosamente!' payment_method: "Método de pago" payment_processing_failed: "No se pudo procesar el pago, por favor verifique los detalles que introdujo" + sku: "SKU" actions: update: "Actualizar" cancel: "Cancelar" @@ -2964,6 +2982,8 @@ es_CR: header: store: Tienda admin: + subscriptions: + number: "Número" tab: dashboard: "Panel de inicio" orders: "Pedidos" @@ -3110,6 +3130,7 @@ es_CR: back_to_shipping_methods_list: "Volver a la lista de métodos de envío" form: categories: "Categorías" + tax_category: "Categoría de impuestos" zones: "Zonas" payment_methods: index: @@ -3171,6 +3192,7 @@ es_CR: value: "Valor" unit_name: "Nombre de la unidad" price: "Precio" + unit_price: "Precio por unidad" on_hand: "Disponibles" on_demand: "Bajo demanda" product_description: "Descripción del producto" @@ -3239,7 +3261,6 @@ es_CR: price: "Precio" options: "Opciones" no_results: "No hay resultados" - to_add_variants_you_must_first_define: "Para agregar variantes, usted debe primero definir" option_types: "Tipos de opciones" option_values: "Valores de opción" and: "y" @@ -3251,6 +3272,7 @@ es_CR: form: sku: "SKU" price: "Precio" + unit_price: "Precio por unidad" display_as: "Mostrar como" display_name: "Nombre para mostrar" autocomplete: diff --git a/config/locales/es_US.yml b/config/locales/es_US.yml index 139adf765a..c979c2f91b 100644 --- a/config/locales/es_US.yml +++ b/config/locales/es_US.yml @@ -1,5 +1,5 @@ es_US: - language_name: "Castellano" + language_name: "Español" activerecord: attributes: enterprise_fee: @@ -85,6 +85,7 @@ es_US: no_default_card: "^ Ninguna tarjeta predeterminada disponible para esta consumidora" shipping_method: not_available_to_shop: "no está disponible para %{shop}" + customer_instructions: "Instrucciones del Consumidor" devise: confirmations: send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." @@ -119,6 +120,8 @@ es_US: cloned_order_cycle_name: "COPIA DE %{order_cycle}" tax_rate: included_in_price: "Incluido en el precio" + sku: "SKU" + tax_rate: "% Impuestos" validators: date_time_string_validator: not_string_error: "debe ser una cadena" @@ -264,7 +267,6 @@ es_US: error: Error processing_payment: "Procesando el pago..." no_pending_payments: "No tiene pagos pendientes" - invalid_payment_state: "Estado de pago no válido" filter_results: Filtrar resultados quantity: Cantidad pick_up: Recogida @@ -1147,6 +1149,7 @@ es_US: yes_cancel_them: Cancelarlos no_keep_them: Guárdalos yes_i_am_sure: Sí estoy seguro + number: "Número" order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. no_results: no_subscriptions: Aún no hay suscripciones ... @@ -1276,7 +1279,7 @@ es_US: menu_4_title: "Redes" menu_4_url: "/groups" menu_5_title: "Acerca de" - menu_5_url: "http://katuma.org/" + menu_5_url: "https://about.openfoodnetwork.net/" menu_6_title: "Conectar" menu_6_url: " " menu_7_title: "Aprender" @@ -1568,7 +1571,9 @@ es_US: shopping_tabs_home: "Inicio" shopping_tabs_shop: "Tienda" shopping_tabs_about: "Acerca de" + shopping_tabs_producers: "Productoras" shopping_tabs_contact: "Contacto" + shopping_tabs_groups: "Redes" shopping_contact_address: "Dirección" shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" @@ -1720,39 +1725,40 @@ es_US: shops_signup_help: Estamos listos para ayudar. shops_signup_help_text: Usted necesita un mejor retorno. Usted necesita nuevos compradores y socios de logística. Usted necesita que su historia sea contada a través de ventas al por mayor, al detalle y en la mesa de la cocina. shops_signup_detail: Aquí está el detalle. - orders: Pedidos - orders_fees: Comisiones... - orders_edit_title: Carrito de compras - orders_edit_headline: Su carrito de compras - orders_edit_time: Pedido listo para - orders_edit_continue: Continuar comprando - orders_edit_checkout: Validar + orders: "Pedidos" + orders_fees: "Comisiones..." + orders_edit_title: "Carrito de compras" + orders_edit_headline: "Su carrito de compras" + orders_edit_time: "Pedido listo para" + orders_edit_continue: "Continuar comprando" + orders_edit_checkout: "Validar" orders_form_empty_cart: "Vaciar carrito" - orders_form_subtotal: Subtotal de productos - orders_form_admin: Administrar y Gestionar - orders_form_total: Total - orders_oc_expired_headline: Los pedidos están cerrados para este ciclo + orders_form_update_cart: "Actualizar" + orders_form_subtotal: "Subtotal de productos" + orders_form_admin: "Administrar y Gestionar" + orders_form_total: "Total" + orders_oc_expired_headline: "Los pedidos están cerrados para este ciclo" orders_oc_expired_text: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos." orders_oc_expired_text_others_html: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos %{link}." orders_oc_expired_text_link: "o visitar otros ciclos de pedidos disponibles en este grupo de consumo" orders_oc_expired_email: "Correo electrónico:" orders_oc_expired_phone: "Teléfono:" - orders_show_title: Confirmación del pedido - orders_show_time: Pedido listo en + orders_show_title: "Confirmación del pedido" + orders_show_time: "Pedido listo en" orders_show_order_number: "Pedido #%{number}" - orders_show_cancelled: Cancelado - orders_show_confirmed: Confirmado + orders_show_cancelled: "Cancelado" + orders_show_confirmed: "Confirmado" orders_your_order_has_been_cancelled: "Su pedido ha sido cancelado" orders_could_not_cancel: "Lo sentimos, no se pudo cancelar el pedido" orders_cannot_remove_the_final_item: "No se puede quitar el último artículo de un pedido, en su lugar, por favor cancele el pedido." orders_bought_items_notice: - one: Ya se ha confirmado un artículo adicional para este ciclo de pedido + one: "Ya se ha confirmado un artículo adicional para este ciclo de pedido" few: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" many: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" other: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" - orders_bought_edit_button: Editar artículos confirmados + orders_bought_edit_button: "Editar artículos confirmados" orders_bought_already_confirmed: "* ya confirmados" - orders_confirm_cancel: Seguro que desea cancelar este pedido? + orders_confirm_cancel: "Seguro que desea cancelar este pedido?" order_processed_successfully: "Su pedido ha sido procesado con éxito." products_cart_distributor_choice: "Distribuidora para tu pedido:" products_cart_distributor_change: "Su distribuidora para este pedido se cambiará a %{name} si agregas este producto al carrito." @@ -2806,6 +2812,9 @@ es_US: start_free_profile: "Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" order_management: reports: + bulk_coop: + filters: + generate_report: "Generar informe" enterprise_fee_summaries: filters: date_range: "Rango de fechas" @@ -2851,6 +2860,8 @@ es_US: tax_category_name: "Categoría de impuestos" total_amount: "€€ SUM" invalid_filter_parameters: "Los filtros que seleccionó para este informe no son válidos." + report: + none: "Ninguno" order: "Pedido" distribution: "Distribución" order_details: "Detalles del pedido" @@ -2883,7 +2894,13 @@ es_US: previous: "Anterior" last: "Último" spree: + all: "Todos" + category: "Categoría" + credit: "Crédito" more: "Más" + no_pending_payments: "No tiene pagos pendientes" + none: "Ninguno" + updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" name_or_sku: "Nombre o código SKU (ingrese al menos los primeros 4 caracteres del nombre del producto)" @@ -3060,6 +3077,7 @@ es_US: payment_method: "Método de pago" payment_processing_failed: "No se pudo procesar el pago, por favor verifique los detalles que introdujo" not_available: "No disponible" + sku: "SKU" order_populator: out_of_stock: '%{item} está agotado.' actions: @@ -3088,6 +3106,8 @@ es_US: header: store: Tienda admin: + subscriptions: + number: "Número" tab: dashboard: "Panel de inicio" orders: "Pedidos" @@ -3236,6 +3256,7 @@ es_US: back_to_shipping_methods_list: "Volver a la lista de métodos de envío" form: categories: "Categorías" + tax_category: "Categoría del impuesto" zones: "Zonas" both: "Tanto en Hacer pedido como en Administración" back_end: "Solo en Administración" @@ -3316,6 +3337,7 @@ es_US: value: "Valor" unit_name: "Nombre de la unidad" price: "Precio" + unit_price: "Precio por unidad" on_hand: "Disponibles" on_demand: "Bajo demanda" product_description: "Descripción del producto" @@ -3386,7 +3408,6 @@ es_US: price: "Precio" options: "Opciones" no_results: "No hay resultados" - to_add_variants_you_must_first_define: "para agregar variantes, se debe primero definir" option_types: "Tipos de opciones" option_values: "valores de opción" and: "y" @@ -3398,6 +3419,7 @@ es_US: form: sku: "SKU" price: "Precio" + unit_price: "Precio por unidad" display_as: "Mostrar como" display_name: "Nombre para mostrar" display_as_placeholder: 'p. ej. 2 Kg' diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index f40b0001a4..30b99f1716 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -81,6 +81,7 @@ fil_PH: no_default_card: "^Walang default card na maaaring gamitin para sa customer na ito" shipping_method: not_available_to_shop: "ay hindi magagamit para%{shop}" + customer_instructions: "panuto ng Customer" devise: confirmations: send_instructions: "Kayo ay makakatanggap ng email na may panuto kung paano kumpirmahin ang inyong account sa loob ng ilang minuto." @@ -113,6 +114,8 @@ fil_PH: models: order_cycle: cloned_order_cycle_name: "KOPYA NG%{order_cycle}" + sku: "SKU" + tax_rate: "rate ng tax" validators: date_time_string_validator: not_string_error: "ay dapat String" @@ -256,7 +259,6 @@ fil_PH: error: Error processing_payment: "Pinoproseso ang bayad..." no_pending_payments: "walang nakabinbin na mga bayad" - invalid_payment_state: "hindi valid na status ng pagbabayad" filter_results: I-filter ang mga resulta quantity: Dami pick_up: Pick up @@ -1113,6 +1115,7 @@ fil_PH: yes_cancel_them: kanselahin no_keep_them: ituloy yes_i_am_sure: oo, sigurado ako + number: "Bilang" order_update_issues_msg: "ang ibang mga order ay hindi awtomatikong ma-update, sapagkat ito ay manwal na inayos. Tignan ang mga isyu na nakalista sa baba at gawin ang nararapat na pag-aayos sa bawat indibiduwal na \norder kung kinakailangan." no_results: no_subscriptions: wala pang mga subscription.... @@ -1517,7 +1520,9 @@ fil_PH: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "tungkol sa" + shopping_tabs_producers: "Mga Producer" shopping_tabs_contact: "Makipag-ugnayan" + shopping_tabs_groups: "Mga Bayarin" shopping_contact_address: "tirahan" shopping_contact_web: "Makipag-ugnayan" shopping_contact_social: "sumunod" @@ -1660,28 +1665,29 @@ fil_PH: shops_signup_help: handa kaming tumulong. shops_signup_help_text: kailangan mo ng mas malaking kita. kailangan mo ng bagong mga mamimili at mga katulong sa operasyon. kailangang malaman ng lahat ang tungkol sa iyong produkto. shops_signup_detail: 'ito ang mga detalye:' - orders: mga order - orders_fees: Mga bayarin... - orders_edit_title: Cart para sa pamimili - orders_edit_headline: ang iyong cart sa pamimili - orders_edit_time: ang order ay handa na para sa - orders_edit_continue: magpatuloy sa pamimili - orders_edit_checkout: checkout + orders: "mga order" + orders_fees: "Mga bayarin..." + orders_edit_title: "Cart para sa pamimili" + orders_edit_headline: "ang iyong cart sa pamimili" + orders_edit_time: "ang order ay handa na para sa" + orders_edit_continue: "magpatuloy sa pamimili" + orders_edit_checkout: "checkout" orders_form_empty_cart: "alisin ang laman ng cart" - orders_form_subtotal: bahagyang kabuuan ng mga produkto - orders_form_admin: Admin & Handling - orders_form_total: kabuuan - orders_oc_expired_headline: ang mga order ay nagsara na para sa order cycle na ito. + orders_form_update_cart: "i-update" + orders_form_subtotal: "bahagyang kabuuan ng mga produkto" + orders_form_admin: "Admin & Handling" + orders_form_total: "kabuuan" + orders_oc_expired_headline: "ang mga order ay nagsara na para sa order cycle na ito." orders_oc_expired_text: "Paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong%{time}! Direktang makipag-ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order." orders_oc_expired_text_others_html: "paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong %{time}! direktang makipag ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order%{link}." orders_oc_expired_text_link: "o tignan ang iba pang order cycle mula sa hub na ito." orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Telepono:" - orders_show_title: Kumpirmasyon ng order - orders_show_time: 'ang order ay handa na sa:' + orders_show_title: "Kumpirmasyon ng order" + orders_show_time: "ang order ay handa na sa:" orders_show_order_number: "Order #%{number}" - orders_show_cancelled: kanselado - orders_show_confirmed: Kumpirmado + orders_show_cancelled: "kanselado" + orders_show_confirmed: "Kumpirmado" orders_your_order_has_been_cancelled: "ang inyong order ay nakansela" orders_could_not_cancel: "paumanhin, hindi makansela ang inyong order" orders_cannot_remove_the_final_item: "hindi matanggal ang huling item mula sa isang order, maaaring kanselahin na lamang ang order." @@ -1689,9 +1695,9 @@ fil_PH: few: "%{count}karagdagang mga item ang nakumpirma para sa order cycle na ito" many: "%{count}karagdagang mga item ang nakumpirma para sa order cycle na ito" other: "%{count}karagdagang mga item ang nakumpirma para sa order cycle na ito" - orders_bought_edit_button: ayusin ang kumpirmadong mga item + orders_bought_edit_button: "ayusin ang kumpirmadong mga item" orders_bought_already_confirmed: "* kumpirmado na" - orders_confirm_cancel: sigurado ka bang nais mo na kanselahin ang order na ito? + orders_confirm_cancel: "sigurado ka bang nais mo na kanselahin ang order na ito?" order_processed_successfully: "ang inyong order ay matagumpay na naproseso" products_cart_distributor_choice: "Distributor ng inyong order:" products_cart_distributor_change: "ang distributor para sa order na ito ay mapapalitan ng%{name} kung idadagdag ang produktong ito sa inyong cart." @@ -2714,6 +2720,9 @@ fil_PH: start_free_profile: "Magsimula sa libreng profile at palawakin kapag handa ka na!" order_management: reports: + bulk_coop: + filters: + generate_report: "Bumuo ng ulat" enterprise_fee_summaries: filters: date_range: "saklaw na petsa" @@ -2759,6 +2768,8 @@ fil_PH: tax_category_name: "kategorya ng tax" total_amount: "$$ KABUUAN" invalid_filter_parameters: "ang mga filter na pinili para sa ulat na ito ay hindi valid." + report: + none: "wala" order: "order" distribution: "pamamahagi" order_details: "mga detalye ng order" @@ -2789,7 +2800,13 @@ fil_PH: previous: "nauna" last: "huli" spree: + all: "Lahat" + category: "kategorya" + credit: "utang" more: "Karagdagang Impormasyon" + no_pending_payments: "walang nakabinbin na mga bayad" + none: "wala" + updating: "ina-update" your_order_is_empty_add_product: "ang iyong order ay walang laman, humanap at magdagdag ng produkto sa itaas." add_product: "magdagdag ng produkto" name_or_sku: "Pangalan o SKU (ipasok ang 4 na letra sa pangalan ng produkto)" @@ -2952,6 +2969,7 @@ fil_PH: successfully_updated: '%{resource}ay matagumpay na na-update' payment_method: "Paraan ng pagbayad" payment_processing_failed: "hindi maproseso ang bayad, maaaring suriin ang mga detalyeng inilagay" + sku: "SKU" actions: update: "i-update" cancel: "kanselahin" @@ -2969,6 +2987,8 @@ fil_PH: header: store: tindahan admin: + subscriptions: + number: "Bilang" tab: dashboard: "Dashboard" orders: "mga order" @@ -3115,6 +3135,7 @@ fil_PH: back_to_shipping_methods_list: "bumalik sa listahan ng mga paraan ng pagpapadala" form: categories: "mga kategorya" + tax_category: "kategorya ng tax" zones: "mga sona" payment_methods: index: @@ -3176,6 +3197,7 @@ fil_PH: value: "halaga" unit_name: "pangalan ng yunit" price: "presyo" + unit_price: "Presyo kada Yunit" on_hand: "on hand" on_demand: "on demand" product_description: "paglalarawan ng produkto" @@ -3244,7 +3266,6 @@ fil_PH: price: "presyo" options: "pagpipilian" no_results: "Walang resulta" - to_add_variants_you_must_first_define: "para makapagdagdag ng mga variant, tukuyin muna ang" option_types: "mga uri ng pagpipilian" option_values: "Mga halaga ng pagpipilian" and: "at" @@ -3256,6 +3277,7 @@ fil_PH: form: sku: "SKU" price: "presyo" + unit_price: "Presyo kada Yunit" display_as: "Ipakita Bilang" display_name: "Pangalan na nakikita" autocomplete: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index abea5e80c1..25384b59f9 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -85,6 +85,11 @@ fr: no_default_card: "Pas de carte de paiement par défaut pour cet acheteur" shipping_method: not_available_to_shop: "n'est pas disponible pour %{shop}" + card_details: "Détalis de la carte" + card_type: "Type de carte" + cardholder_name: "Titulaire de la carte" + community_forum_url: "Lien vers le forum" + customer_instructions: "Précisions pour l'acheteur" devise: confirmations: send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!" @@ -114,11 +119,39 @@ fr: updated_not_active: "Votre mot de passe a bien été réinitialisé, mais votre email n'a pas encore été confirmé." updated: "Votre mot de passer a été changé avec succès. Vous êtes maintenant connecté(e)." send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!" + home_page_alert_html: "Bannière d'alerte sur la page d'acceuil en HTML" + hub_signup_case_studies_html: "HTML page cas d'études hub" + hub_signup_detail_html: "HTML page inscription hub" + hub_signup_pricing_table_html: "HTML table de prix page inscription hub" + group_signup_case_studies_html: "HTML page inscription groupe" + group_signup_detail_html: "HTML page inscription groupe" + group_signup_pricing_table_html: "HTML table de prix page inscription groupe" + item_description: "Description de la pièce" + menu_1_icon_name: "Nom de l'icône du menu 1" + menu_2_icon_name: "Nom de l'icône du menu 2" + menu_3_icon_name: "Nom de l'icône du menu 3" + menu_4_icon_name: "Nom de l'icône du menu 4" + menu_5_icon_name: "Nom de l'icône du menu 5" + menu_6_icon_name: "Nom de l'icône du menu 6" + menu_7_icon_name: "Nom de l'icône du menu 7" models: order_cycle: cloned_order_cycle_name: "Copie de %{order_cycle}" tax_rate: included_in_price: "Inclus dans le prix" + open_street_map_enabled: "Open Street Map est activé" + open_street_map_default_latitude: "Latitude par défaut Open Street Map" + open_street_map_default_longitude: "Longitude par défaut Open Street Map" + open_street_map_provider_name: "Nom du fournisseur Open Street Map" + open_street_map_provider_options: "Options du fournisseur Open Street Map" + producer_signup_case_studies_html: "HTML études de cas producteur" + producer_signup_detail_html: "HTML page inscription producteur" + producer_signup_pricing_table_html: "HTML table de prix page inscription producteur" + producers_social: "Réseau social producteur" + resume_order: "Reprendre la commande" + sku: "Référence Produit" + subtotal: "Sous-total" + tax_rate: "TVA applicable" validators: date_time_string_validator: not_string_error: "doit être une série" @@ -144,6 +177,7 @@ fr: producer_mailer: order_cycle: subject: "Rapport de cycle de vente pour %{producer}" + provider_settings: "Paramètres fournisseur" shipment_mailer: shipped_email: dear_customer: "Cher Acheteur," @@ -264,7 +298,7 @@ fr: error: Erreur processing_payment: "Paiement en cours..." no_pending_payments: "Aucun paiement en attente." - invalid_payment_state: "Statut de paiement invalide" + invalid_payment_state: "Statut de paiement invalide : %{state}" filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -298,8 +332,12 @@ fr: destroy: "Détruire" rename: "Renommer" admin: + adjustments: + skipped_changing_canceled_order: "Vous ne pouvez pas modifier une commande annulée." begins_at: Commence begins_on: Commence le + bill_address: "Adresse de facturation" + ship_address: "Adresse de livraison" customer: Acheteur date: Date email: Email @@ -1066,6 +1104,7 @@ fr: index: title: "Abonnements" new: "Nouvel abonnement" + issue: "Editée" new: title: "Nouvel abonnement" edit: @@ -1147,6 +1186,7 @@ fr: yes_cancel_them: Les annuler no_keep_them: Les conserver yes_i_am_sure: Oui, je confirme + number: "N° commande" order_update_issues_msg: Certaines commandes n'ont pas pu être mises à jour automatiquement, probablement car elles ont été manuellement modifiées. Veuillez revoir les erreurs listées ci-dessous et effectuer si nécessaire les ajustements nécessaires sur les commandes individuelles. no_results: no_subscriptions: Pas encore d'abonnements... @@ -1179,8 +1219,10 @@ fr: message_html: "J'accepte les %{terms_and_conditions_link}." link_text: "CGU & CGV" platform_terms_of_service: + message_html: "J'accepte les %{tos_link}." terms_of_service: "Conditions Générales d'Utilisation" all_terms_and_conditions: + message_html: "J'accepte les %{terms_and_conditions_link} de la boutique et les %{tos_link} de CoopCircuits." terms_and_conditions: "CGU & CGV" terms_of_service: "Conditions Générales d'Utilisation" failed: "La validation du paiement a échoué. Contactez-nous afin de finaliser votre commande." @@ -1572,7 +1614,9 @@ fr: shopping_tabs_home: "Accueil" shopping_tabs_shop: "Boutique" shopping_tabs_about: "A propos" + shopping_tabs_producers: "Producteurs" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groupes" shopping_contact_address: "Adresse" shopping_contact_web: "Contact" shopping_contact_social: "Suivre" @@ -1724,39 +1768,40 @@ fr: shops_signup_help: Rejoindre le réseau shops_signup_help_text: Créez votre profil distributeur, et dès que vous êtes prêt, changez de formule pour ouvrir votre boutique en ligne. shops_signup_detail: Les avantages CoopCircuits - orders: Commandes - orders_fees: Frais... - orders_edit_title: Panier - orders_edit_headline: Votre panier - orders_edit_time: Commande prête pour - orders_edit_continue: Retour à la boutique - orders_edit_checkout: Etape suivante (coordonnées) + orders: "Commandes" + orders_fees: "Frais..." + orders_edit_title: "Panier" + orders_edit_headline: "Votre panier" + orders_edit_time: "Commande prête pour" + orders_edit_continue: "Retour à la boutique" + orders_edit_checkout: "Etape suivante (coordonnées)" orders_form_empty_cart: "Vider le panier" - orders_form_subtotal: Sous-total - orders_form_admin: Admin & traitements - orders_form_total: Total - orders_oc_expired_headline: Les commandes ne sont plus possibles pour ce cycle de vente. + orders_form_update_cart: "Mettre à jour" + orders_form_subtotal: "Sous-total" + orders_form_admin: "Admin & traitements" + orders_form_total: "Total" + orders_oc_expired_headline: "Les commandes ne sont plus possibles pour ce cycle de vente." orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}!" orders_oc_expired_text_others_html: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le gestionnaire de la boutique pour voir s'il accepte les commandes tardives %{link}." orders_oc_expired_text_link: "ou voir si d'autres cycles de vente sont ouverts pour cette boutique" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Téléphone:" - orders_show_title: Confirmation de commande - orders_show_time: Commande prête pour + orders_show_title: "Confirmation de commande" + orders_show_time: "Commande prête pour" orders_show_order_number: "Commande #%{number}" - orders_show_cancelled: Annulée - orders_show_confirmed: Confirmée + orders_show_cancelled: "Annulée" + orders_show_confirmed: "Confirmée" orders_your_order_has_been_cancelled: "Votre commande a été annulée" orders_could_not_cancel: "Désolé, la commande n'a pas pu être annulée" orders_cannot_remove_the_final_item: "Impossible de supprimer le dernier produit d'une commande, si vous souhaitez supprimer l'ensemble des produits, veuillez annuler la commande." orders_bought_items_notice: - one: Un produit additionnel est déjà confirmé pour ce cycle de vente. + one: "Un produit additionnel est déjà confirmé pour ce cycle de vente." few: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." many: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." other: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." - orders_bought_edit_button: Modifier les produits confirmés + orders_bought_edit_button: "Modifier les produits confirmés" orders_bought_already_confirmed: "* déjà confirmé" - orders_confirm_cancel: Voulez-vous vraiment annuler cette commande ? + orders_confirm_cancel: "Voulez-vous vraiment annuler cette commande ?" order_processed_successfully: "Votre commande a été traitée avec succès" products_cart_distributor_choice: "Distributeur pour votre commande:" products_cart_distributor_change: "Vore distributeur pour cette commande sera dorénavant %{name} si vous ajoutez ce produit à votre panier." @@ -2417,6 +2462,7 @@ fr: Il y a eu un problème lors de l'ajout de votre produit au panier. Peut-être qu'il n'est plus en stock ou que la boutique sur laquelle vous étiez a fermé. admin: + unit_price_tooltip: "Le prix unitaire permet aux acheteurs de comparer les prix entre les produits et/ou les conditionnements. Attention, le prix final observé par l'acheteur peut être différent si des marges et/ou commissions sont appliquées." enterprise_limit_reached: "Vous avez atteint le nombre limite d'entreprises autorisées par défaut. Ecrivez à %{contact_email}si vous avez besoin d'augmenter cette limite." modals: got_it: "J'ai compris" @@ -2835,6 +2881,15 @@ fr: start_free_profile: "Créez votre profil producteur, et dès que vous êtes prêt, changez de formule pour ouvrir votre boutique en ligne." order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Achats groupés Allocation" + bulk_coop_customer_payments: "Achats groupés - Paiement des acheteurs" + bulk_coop_packing_sheets: "Achats groupés - Feuilles de préparation des paniers" + bulk_coop_supplier_report: "Achats groupés - Totaux par Producteur" + date_range: "Plage de dates" + generate_report: "Générer le rapport" + report_format_csv: "Format de rapport CSV" enterprise_fee_summaries: filters: date_range: "Période" @@ -2880,6 +2935,8 @@ fr: tax_category_name: "TVA applicable" total_amount: "€ total" invalid_filter_parameters: "Les filtres sélectionnés pour ce rapport sont invalides." + report: + none: "Aucun" order: "Commande" distribution: "Distribution" order_details: "Détails de la commande" @@ -2912,7 +2969,54 @@ fr: previous: "Précédent" last: "Fin" spree: + add_country: "Ajouter un pays" + add_state: "Ajouter un département" + adjustment: "Ajustement" + all: "Tous" + associated_adjustment_closed: "L'ajustement associé est fermé" + authorization_failure: "Echec de l'autorisation" + back_to_adjustments_list: "Retour aux ajustements" + back_to_users_list: "Retour à la liste d'utilisateurs" + back_to_zones_list: "Retour à la liste de zones" + card_code: "Code de la carte" + card_number: "Numéro de la carte" + category: "Catégorie" + created_successfully: "Créé avec succès" + credit: "Créditer" + editing_tax_category: "Modifier une catégorie de taxe" + editing_tax_rate: "Modifier un taux" + editing_zone: "Modifier une zone" + expiration: "Expiration" + invalid_payment_provider: "Fournisseur de paiement invalide" + items_cannot_be_shipped: "Les produits ne peuvent pas être envoyés" + gateway_config_unavailable: "Configuration de la passerelle indisponible" + gateway_error: "Le paiement a échoué" more: "Plus" + new_adjustment: "Nouvel ajustement" + new_order_completed: "Nouvelle commande finalisée" + new_tax_category: "Nouvelle catégorie de taxe" + new_taxon: "Nouvelle taxonomie" + new_user: "Nouvel utilisateur" + no_pending_payments: "Aucun paiement en attente." + none: "Aucun" + not_found: "Non trouvé" + notice_messages: + variant_deleted: "Variante supprimée" + or: "Ou" + order_processed_successfully: "Commande traitée avec succès" + payment_method_not_supported: "Mode de paiement non pris en charge" + resend_authorization_email: "Renvoyer l'e-mail d'autorisation" + rma_credit: "Crédit RMA" + server_error: "Erreur serveur" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Date de début" + successfully_removed: "Supprimé avec succès" + taxonomy_edit: "Modifier la taxonomie" + taxonomy_tree_error: "Erreur de l'arbre de toxonomie" + taxonomy_tree_instruction: "Consignes pour l'arbre de taxonomie" + tree: "Arbre" + updating: "Mettre à jour" your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits" add_product: "Ajouter un produit" name_or_sku: "Nom ou Ref Produit (entrer au moins les 4 premiers caractères du nom du produit)" @@ -2940,6 +3044,7 @@ fr: tracking_number: "Numéro de suivi" order_total: "Total Commande" customer_details: "Informations acheteur" + customer_details_updated: "Détails de l'acheteur mis à jour" customer_search: "Recherche Acheteur" choose_a_customer: "Choisir un acheteur" account: "Compte" @@ -3090,6 +3195,8 @@ fr: payment_method: "Méthode de paiement" payment_processing_failed: "Le paiement n'a pas pu être traité, veuillez vérifier les informations saisies" not_available: "N/A" + sku: "Référence Produit" + there_are_no_items_for_this_order: "Il n'y a pas de produits pour cette commande." order_populator: out_of_stock: '%{item} est en rupture de stock.' actions: @@ -3117,7 +3224,17 @@ fr: login_nav: header: store: Vue acheteur + validation: + must_be_int: "doit être un entier" admin: + mail_methods: + send_testmail: "Envoyer un e-mail de test" + testmail: + delivery_success: "E-mail de test envoyé." + error: "Une erreur s'est produite lors de l'envoi de l'e-mail de test. " + unit_price_tooltip: "Le prix unitaire permet aux acheteurs de comparer les prix entre les produits et/ou les conditionnements. Attention, le prix final observé par l'acheteur peut être différent si des marges et/ou commissions sont appliquées." + subscriptions: + number: "N° commande" tab: dashboard: "Tableau de bord" orders: "Commandes" @@ -3186,6 +3303,8 @@ fr: received: "Reçu" canceled: "Annulé" orders: + add_product: + cannot_add_item_to_canceled_order: "Il n'est pas possible d'ajouter des produits sur une commande annulée" index: listing_orders: "Liste des commandes" new_order: "Nouvelle commande" @@ -3228,6 +3347,10 @@ fr: overview: enterprises_header: ofn_with_tip: Les Entreprises sont les entités qui organisent des circuits courts et utilisent pour cela CoopCircuits. + enterprise_row: + has_no_enterprise_fees: "n'a pas de marge ou commission" + has_no_payment_methods: "n'a pas de méthode de paiement" + has_no_shipping_methods: "n'a pas de méthode de livraison" products: active_products: zero: "Vous n'avez aucun produit actif." @@ -3266,6 +3389,7 @@ fr: back_to_shipping_methods_list: "Retour à la liste des méthodes de livraison" form: categories: "Conditions de transport" + tax_category: "TVA applicable" zones: "Zones" both: "Vu par l'acheteur sur la boutique" back_end: "Visible pour l'administration uniquement" @@ -3346,6 +3470,8 @@ fr: value: "Quantité" unit_name: "Unité" price: "Prix" + unit_price: "Prix unitaire" + unit_price_legend: "Calcul basé sur le prix à l'unité" on_hand: "En stock" on_demand: "A volonté" product_description: "Description du Produit" @@ -3416,7 +3542,6 @@ fr: price: "Prix" options: "Options" no_results: "Pas de résultats" - to_add_variants_you_must_first_define: "Pour ajouter une variante, vous devez d'abord définir" option_types: "Types d'options" option_values: "Valeurs" and: "et" @@ -3428,6 +3553,7 @@ fr: form: sku: "Référence Produit" price: "Prix" + unit_price: "Prix unitaire" display_as: "Unité affichée" display_name: "Nom affiché" display_as_placeholder: 'ex. 2 kg' @@ -3451,6 +3577,7 @@ fr: cookies_consent_banner_toggle: "Afficher la bannière de consentement à l'utilisation des cookies" privacy_policy_url: "URL de la politique de confidentialité" enterprises_require_tos: "Les entreprises doivent accepter les Conditions Générales d'Utilisation" + shoppers_require_tos: "Les acheteurs doivent accepter les CGU." cookies_policy_matomo_section: "Afficher la section Matomo sur la politique de cookies" footer_tos_url: "Conditions d'utilisation URL" checkout: @@ -3664,3 +3791,42 @@ fr: spree/payment: one: Paiement other: Paiements + datetime: + distance_in_words: + about_x_hours: + one: environ 1 heure + other: environ %{count}heures + about_x_months: + one: environ 1 mois + other: environ %{count} mois + about_x_years: + one: environ 1 année + other: environ %{count} années + almost_x_years: + one: presque 1 année + other: presque %{count} années + half_a_minute: moins d'une minute + less_than_x_seconds: + one: moins d' 1 seconde + other: moins de %{count} secondes + less_than_x_minutes: + one: moins d'une minute + other: moins de %{count} minutes + over_x_years: + one: plus d' 1 an + other: plus de %{count} années + x_seconds: + one: "1 seconde" + other: "%{count} secondes" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 jour" + other: "%{count} jours" + x_months: + one: "1 mois" + other: "%{count} mois" + x_years: + one: "1 an" + other: "%{count} ans" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index 63bc38600d..b5edc2e731 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -84,6 +84,7 @@ fr_BE: no_default_card: "Pas de carte de paiement par défaut pour cet acheteur" shipping_method: not_available_to_shop: "n'est pas disponible pour %{shop}" + customer_instructions: "Précisions pour la personne qui achète" devise: confirmations: send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!" @@ -116,6 +117,8 @@ fr_BE: models: order_cycle: cloned_order_cycle_name: "Copie de %{order_cycle}" + sku: "Référence produit" + tax_rate: "TVA applicable" validators: date_time_string_validator: not_string_error: "doit être une chaîne" @@ -261,7 +264,6 @@ fr_BE: error: Erreur processing_payment: "Paiement en cours..." no_pending_payments: "Aucun paiement en attente" - invalid_payment_state: "État de paiement invalide" filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -1129,6 +1131,7 @@ fr_BE: yes_cancel_them: Les annuler no_keep_them: Les conserver yes_i_am_sure: Oui, je confirme + number: "N° commande" order_update_issues_msg: Certaines commandes n'ont pas pu être mises à jour automatiquement, probablement car elles ont été manuellement modifiées. Veuillez revoir les erreurs listées ci-dessous et effectuer si nécessaire les ajustements nécessaires sur les commandes individuelles. no_results: no_subscriptions: Pas encore d'abonnements... @@ -1542,7 +1545,9 @@ fr_BE: shopping_tabs_home: "Accueil" shopping_tabs_shop: "Comptoir" shopping_tabs_about: "A propos" + shopping_tabs_producers: "Producteur·trice·s" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groupes" shopping_contact_address: "Adresse" shopping_contact_web: "Contact" shopping_contact_social: "Suivre" @@ -1692,28 +1697,29 @@ fr_BE: shops_signup_help: Nous sommes là pour vous aider. shops_signup_help_text: Vous avez besoin de pouvoir travailler de manière efficace. Vous avez besoin de nouveaux acheteurs et de partenaires logistiques. Vous souhaitez que votre histoire soit racontée tout au long du circuit, que l'acheteur final sache qui se trouve derrière les produits. shops_signup_detail: Comment ça marche. - orders: Commandes - orders_fees: Frais... - orders_edit_title: Panier - orders_edit_headline: Votre panier - orders_edit_time: Commande prête pour - orders_edit_continue: Retour au comptoir - orders_edit_checkout: Etape suivante (coordonnées) + orders: "Commandes" + orders_fees: "Frais..." + orders_edit_title: "Panier" + orders_edit_headline: "Votre panier" + orders_edit_time: "Commande prête pour" + orders_edit_continue: "Retour au comptoir" + orders_edit_checkout: "Etape suivante (coordonnées)" orders_form_empty_cart: "Vider le panier" - orders_form_subtotal: Sous-total - orders_form_admin: Admin & traitements - orders_form_total: Total - orders_oc_expired_headline: Les commandes ne sont plus possibles pour ce cycle de vente. + orders_form_update_cart: "Mettre à jour" + orders_form_subtotal: "Sous-total" + orders_form_admin: "Admin & traitements" + orders_form_total: "Total" + orders_oc_expired_headline: "Les commandes ne sont plus possibles pour ce cycle de vente." orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le comptoir pour voir s'il accepte les commandes tardives." orders_oc_expired_text_others_html: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le comptoir pour voir s'il accepte les commandes tardives %{link}." orders_oc_expired_text_link: "ou voir si d'autres cycles de vente sont ouverts pour ce comptoir" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Téléphone:" - orders_show_title: Confirmation de commande - orders_show_time: Commande prête pour + orders_show_title: "Confirmation de commande" + orders_show_time: "Commande prête pour" orders_show_order_number: "Commande #%{number}" - orders_show_cancelled: Annulée - orders_show_confirmed: Confirmée + orders_show_cancelled: "Annulée" + orders_show_confirmed: "Confirmée" orders_your_order_has_been_cancelled: "Votre commande a été annulée" orders_could_not_cancel: "Désolé, la commande n'a pas pu être annulée" orders_cannot_remove_the_final_item: "Impossible de supprimer le dernier produit d'une commande, si vous souhaitez supprimer l'ensemble des produits, veuillez annuler la commande." @@ -1721,9 +1727,9 @@ fr_BE: few: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." many: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." other: "%{count} produits ajoutés ont été confirmés pour ce cycle de vente." - orders_bought_edit_button: Modifier les produits confirmés + orders_bought_edit_button: "Modifier les produits confirmés" orders_bought_already_confirmed: "* déjà confirmé" - orders_confirm_cancel: Voulez-vous vraiment annuler cette commande ? + orders_confirm_cancel: "Voulez-vous vraiment annuler cette commande ?" order_processed_successfully: "Votre commande est passée avec succès" products_cart_distributor_choice: "Comptoir pour votre commande:" products_cart_distributor_change: "Votre comptoir, pour cette commande, sera dorénavant %{name} si vous ajoutez ce produit à votre panier." @@ -2686,6 +2692,9 @@ fr_BE: start_free_profile: "Commencez par créer votre profil entreprise, et présentez votre formule quand vous êtes prêt !" order_management: reports: + bulk_coop: + filters: + generate_report: "Générer un rapport" enterprise_fee_summaries: filters: date_range: "Plage de dates" @@ -2731,6 +2740,8 @@ fr_BE: tax_category_name: "TVA applicable" total_amount: "€€ SOMME" invalid_filter_parameters: "Les filtres sélectionnés pour ce rapport ne sont pas valides." + report: + none: "Aucun" order: "Commandes à venir" distribution: "Distribution" order_details: "Données de la commande " @@ -2763,7 +2774,13 @@ fr_BE: previous: "Précédent" last: "Fin" spree: + all: "Tous" + category: "Catégorie" + credit: "Crédit" more: "Plus" + no_pending_payments: "Aucun paiement en attente" + none: "Aucun" + updating: "Mettre à jour" your_order_is_empty_add_product: "Votre commande est vide, merci de chercher et d'ajouter un des produits ci-dessus" add_product: "Ajoutez un produit" name_or_sku: "Nom ou N° d'article (entrer au moins 4 lettres du nom du produit) " @@ -2932,6 +2949,7 @@ fr_BE: successfully_updated: '%{resource}a été enregistrée avec succès' payment_method: "Méthode de paiement" payment_processing_failed: "Le paiement n' a pu être effectué , merci de vérifier les données rentrées" + sku: "Référence produit" actions: update: "Mettre à jour" cancel: "Annuler" @@ -2952,6 +2970,8 @@ fr_BE: header: store: Aperçu admin: + subscriptions: + number: "N° commande" tab: dashboard: "Tableau de bord" orders: "Commandes" @@ -3100,6 +3120,7 @@ fr_BE: back_to_shipping_methods_list: "Retour à la liste des méthodes de livraison" form: categories: "Les catégories" + tax_category: "TVA applicable" zones: "Zones" both: "Aussi bien check-out ets parametre" back_end: "Seulement back office" @@ -3173,6 +3194,7 @@ fr_BE: value: "Nb unités" unit_name: "Nom de l'unité" price: "Prix" + unit_price: "Prix unitaire" on_hand: "En stock" on_demand: "A volonté" product_description: "Description du Produit" @@ -3243,7 +3265,6 @@ fr_BE: price: "Prix" options: "Options" no_results: "Aucun résultat" - to_add_variants_you_must_first_define: "Pour ajouter des variantes, vous devez d'abord définir" option_types: "Option Types " option_values: "Valeurs optionnelles" and: "et" @@ -3255,6 +3276,7 @@ fr_BE: form: sku: "Référence produit" price: "Prix" + unit_price: "Prix unitaire" display_as: "Unité affichéé" display_name: "Nom d'affichage" display_as_placeholder: 'Ex: 2 kilo' diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index a631cd765e..9b104ab7d1 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -85,6 +85,7 @@ fr_CA: no_default_card: "Pas de carte de paiement par défaut pour cet acheteur" shipping_method: not_available_to_shop: "n'est pas disponible pour %{shop}" + customer_instructions: "Précisions pour l'acheteur" devise: confirmations: send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!" @@ -120,6 +121,8 @@ fr_CA: cloned_order_cycle_name: "Copie de %{order_cycle}" tax_rate: included_in_price: "Inclus dans le prix" + sku: "Référence Produit" + tax_rate: "Taux de taxe" validators: date_time_string_validator: not_string_error: "doit être une série" @@ -265,7 +268,7 @@ fr_CA: error: Erreur processing_payment: "Paiement en cours..." no_pending_payments: "Aucun paiement en attente." - invalid_payment_state: "Statut de paiement invalide" + invalid_payment_state: "Statut de paiement invalide : %{state}" filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -1147,6 +1150,7 @@ fr_CA: yes_cancel_them: Les annuler no_keep_them: Les conserver yes_i_am_sure: Oui, je confirme + number: "N° commande" order_update_issues_msg: Certaines commandes n'ont pas pu être mises à jour automatiquement, probablement car elles ont été manuellement modifiées. Veuillez revoir les erreurs listées ci-dessous et effectuer si nécessaire les ajustements nécessaires sur les commandes individuelles. no_results: no_subscriptions: Pas encore d'abonnements... @@ -1179,8 +1183,10 @@ fr_CA: message_html: "J'accepte les %{terms_and_conditions_link}" link_text: "CGU & CGV" platform_terms_of_service: + message_html: "J'accepte les %{tos_link}" terms_of_service: "Conditions Générales d'Utilisation" all_terms_and_conditions: + message_html: "J'accepte les %{terms_and_conditions_link} de la boutique et les %{tos_link} de Open Food Network." terms_and_conditions: "CGU & CGV" terms_of_service: "Conditions Générales d'Utilisation" failed: "La validation du paiement a échoué. Contactez-nous afin de finaliser votre commande." @@ -1572,7 +1578,9 @@ fr_CA: shopping_tabs_home: "Accueil" shopping_tabs_shop: "Boutique" shopping_tabs_about: "A propos" + shopping_tabs_producers: "Producteurs" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groupes" shopping_contact_address: "Adresse" shopping_contact_web: "Contact" shopping_contact_social: "Suivre" @@ -1724,39 +1732,40 @@ fr_CA: shops_signup_help: Nous sommes là pour vous aider. shops_signup_help_text: Vous avez besoin de pouvoir travailler de manière efficace. Vous avez besoin de nouveaux acheteurs et de partenaires logistiques. Vous souhaitez que votre histoire soit racontée tout au long du circuit, que l'acheteur final sache qui se trouve derrière les produits. shops_signup_detail: Comment ça marche. - orders: Commandes - orders_fees: Frais... - orders_edit_title: Panier - orders_edit_headline: Votre panier - orders_edit_time: Commande prête pour - orders_edit_continue: Retour à la boutique - orders_edit_checkout: Finalisation commande + orders: "Commandes" + orders_fees: "Frais..." + orders_edit_title: "Panier" + orders_edit_headline: "Votre panier" + orders_edit_time: "Commande prête pour" + orders_edit_continue: "Retour à la boutique" + orders_edit_checkout: "Finalisation commande" orders_form_empty_cart: "Vider le panier" - orders_form_subtotal: Sous-total - orders_form_admin: Admin & gestion - orders_form_total: Total - orders_oc_expired_headline: Les commandes ne sont plus possibles pour ce cycle de vente. + orders_form_update_cart: "Mettre à jour" + orders_form_subtotal: "Sous-total" + orders_form_admin: "Admin & gestion" + orders_form_total: "Total" + orders_oc_expired_headline: "Les commandes ne sont plus possibles pour ce cycle de vente." orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le hub pour voir s'il accepte les commandes tardives." orders_oc_expired_text_others_html: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le hub pour voir s'il accepte les commandes tardives %{link}." orders_oc_expired_text_link: "ou voir si d'autres cycles de vente sont ouverts pour ce hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Téléphone:" - orders_show_title: Confirmation de commande - orders_show_time: Commande prête pour + orders_show_title: "Confirmation de commande" + orders_show_time: "Commande prête pour" orders_show_order_number: "Commande #%{number}" - orders_show_cancelled: Annulée - orders_show_confirmed: Confirmée + orders_show_cancelled: "Annulée" + orders_show_confirmed: "Confirmée" orders_your_order_has_been_cancelled: "VotrVotre commande a été annuléee commande a été annulée" orders_could_not_cancel: "Désolé, la commande n'a pas pu être annulée" orders_cannot_remove_the_final_item: "Impossible de supprimer le dernier produit d'une commande, si vous souhaitez supprimer l'ensemble des produits, veuillez annuler la commande." orders_bought_items_notice: - one: Un produit additionnel est déjà confirmé pour ce cycle de vente. + one: "Un produit additionnel est déjà confirmé pour ce cycle de vente." few: "%{count} produits ajoutés ont déjà été confirmés pour ce cycle de vente." many: "%{count} produits ajoutés ont déjà été confirmés pour ce cycle de vente." other: "%{count} produits ajoutés ont déjà été confirmés pour ce cycle de vente." - orders_bought_edit_button: Modifier les produits confirmés + orders_bought_edit_button: "Modifier les produits confirmés" orders_bought_already_confirmed: "* déjà confirmé" - orders_confirm_cancel: Voulez-vous vraiment annuler cette commande ? + orders_confirm_cancel: "Voulez-vous vraiment annuler cette commande ?" order_processed_successfully: "Votre commande a été traitée avec succès" products_cart_distributor_choice: "Distributeur pour votre commande:" products_cart_distributor_change: "Vore distributeur pour cette commande sera dorénavant %{name} si vous ajoutez ce produit à votre panier." @@ -2417,6 +2426,7 @@ fr_CA: Il y a eu un problème lors de l'ajout de votre produit au panier. Peut-être qu'il n'est plus en stock ou que la boutique sur laquelle vous étiez a fermé. admin: + unit_price_tooltip: "Le prix unitaire permet aux acheteurs de comparer les prix entre les produits et/ou les conditionnements. Attention, le prix final observé par l'acheteur peut être différent si des marges et/ou commissions sont appliquées." enterprise_limit_reached: "Vous avez atteint le nombre limite d'entreprises autorisées par défaut. Ecrivez à %{contact_email}si vous avez besoin d'augmenter cette limite." modals: got_it: "J'ai compris" @@ -2819,6 +2829,9 @@ fr_CA: start_free_profile: "Commencez par créer votre profil entreprise, c'est gratuit, et changez de formule quand vous êtes prêt !" order_management: reports: + bulk_coop: + filters: + generate_report: "Générer le rapport" enterprise_fee_summaries: filters: date_range: "Période" @@ -2864,6 +2877,8 @@ fr_CA: tax_category_name: "Type de taxe" total_amount: "$$ TOTAL" invalid_filter_parameters: "Les filtres sélectionnés pour ce rapport sont invalides." + report: + none: "Aucun" order: "Commander" distribution: "Distribution" order_details: "Détails de la commande" @@ -2896,7 +2911,13 @@ fr_CA: previous: "Précédent" last: "Fin" spree: + all: "Tous" + category: "Catégorie" + credit: "Crédit" more: "Plus" + no_pending_payments: "Aucun paiement en attente." + none: "Aucun" + updating: "Mettre à jour" your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits" add_product: "Ajouter un produit" name_or_sku: "Nom ou Ref Produit (entrer au moins les 4 premiers caractères du nom du produit)" @@ -3074,6 +3095,7 @@ fr_CA: payment_method: "Méthode de paiement" payment_processing_failed: "Le paiement n'a pas pu être traité, veuillez vérifier les informations saisies" not_available: "N/A" + sku: "Référence Produit" order_populator: out_of_stock: '%{item} est en rupture de stock.' actions: @@ -3102,6 +3124,9 @@ fr_CA: header: store: Vue acheteur admin: + unit_price_tooltip: "Le prix unitaire permet aux acheteurs de comparer les prix entre les produits et/ou les conditionnements. Attention, le prix final observé par l'acheteur peut être différent si des marges et/ou commissions sont appliquées." + subscriptions: + number: "N° commande" tab: dashboard: "Tableau de bord" orders: "Commandes" @@ -3170,6 +3195,8 @@ fr_CA: received: "Reçu" canceled: "Annulée" orders: + add_product: + cannot_add_item_to_canceled_order: "Il n'est pas possible d'ajouter des produits sur une commande annulée." index: listing_orders: "Liste des commandes" new_order: "Nouvelle commande" @@ -3250,6 +3277,7 @@ fr_CA: back_to_shipping_methods_list: "Retour à la liste des méthodes de livraison" form: categories: "Conditions de transport" + tax_category: "Type de taxe" zones: "Zones" both: "Visible par l'acheteur sur la boutique" back_end: "Visible pour l'administration uniquement" @@ -3330,6 +3358,8 @@ fr_CA: value: "Nb unités" unit_name: "Unité" price: "Prix" + unit_price: "Prix unitaire" + unit_price_legend: "Calcul basé sur le prix à l'unité" on_hand: "En stock" on_demand: "A volonté" product_description: "Description du Produit" @@ -3400,7 +3430,6 @@ fr_CA: price: "Prix" options: "Options" no_results: "Pas de résultats" - to_add_variants_you_must_first_define: "Pour ajouter une variante, vous devez d'abord définir" option_types: "Types d'options" option_values: "Valeurs" and: "et" @@ -3412,6 +3441,7 @@ fr_CA: form: sku: "Référence Produit" price: "Prix" + unit_price: "Prix unitaire" display_as: "Afficher comme" display_name: "Nom affiché" display_as_placeholder: 'ex. 2 kg' @@ -3435,6 +3465,7 @@ fr_CA: cookies_consent_banner_toggle: "Afficher la bannière de consentement à l'utilisation des cookies" privacy_policy_url: "URL de la politique de confidentialité" enterprises_require_tos: "Les entreprises doivent accepter les Conditions Générales d'Utilisation" + shoppers_require_tos: "Les acheteurs doivent accepter les CGU." cookies_policy_matomo_section: "Afficher la section Matomo sur la politique de cookies" footer_tos_url: "Conditions d'utilisation URL" checkout: @@ -3648,3 +3679,42 @@ fr_CA: spree/payment: one: Paiement other: Paiements + datetime: + distance_in_words: + about_x_hours: + one: environ 1 heure + other: environ %{count} heures + about_x_months: + one: environ 1 mois + other: environ %{count} mois + about_x_years: + one: environ 1 année + other: environ %{count} années + almost_x_years: + one: presque 1 année + other: presque%{count} années + half_a_minute: moins d'une minute + less_than_x_seconds: + one: moins d' 1 seconde + other: moins de %{count} secondes + less_than_x_minutes: + one: moins d'une minute + other: moins de %{count} minutes + over_x_years: + one: plus d' 1 an + other: plus de %{count} années + x_seconds: + one: "1 seconde" + other: "%{count} secondes" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + x_days: + one: "1 jour" + other: "%{count} jours" + x_months: + one: "1 mois" + other: "%{count} mois" + x_years: + one: "1 an" + other: "%{count} ans" diff --git a/config/locales/it.yml b/config/locales/it.yml index 3cd265487f..58d55d3055 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -9,11 +9,11 @@ it: shipment_state: Stato Spedizione completed_at: Completato Al number: Numero - state: Stato + state: Provincia email: E-Mail Cliente spree/payment: amount: Quantità - state: Stato + state: Provincia source: Fonte spree/product: primary_taxon: "Categoria Prodotto" @@ -85,6 +85,11 @@ it: no_default_card: "^Nessuna carta predefinita è disponibile per questo cliente" shipping_method: not_available_to_shop: "non è disponibile al %{shop}" + card_details: "Dettagli carta" + card_type: "Tipo carta" + cardholder_name: "Titolare carta" + community_forum_url: "URL Forum Community" + customer_instructions: "Istruzioni per i consumatori" devise: confirmations: send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." @@ -114,11 +119,39 @@ it: updated_not_active: "La tua password è stata resettata, ma la tua email non è ancora stata confermata." updated: "La tua password è stata modificata con successo.\nOra sei collegato." send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." + home_page_alert_html: "HTML alert Home page" + hub_signup_case_studies_html: "HTML iscrizione hub casi studio" + hub_signup_detail_html: "HTML dettagli iscrizione hub" + hub_signup_pricing_table_html: "HTML iscrizione tabella prezzi hub" + group_signup_case_studies_html: "HTML iscrizione reti casi studio" + group_signup_detail_html: "HTML dettagli iscrizione reti" + group_signup_pricing_table_html: "HTML iscrizione tabella prezzi Reti" + item_description: "Descrizione articolo" + menu_1_icon_name: "Menu nome icona 1" + menu_2_icon_name: "Menu nome icona 2" + menu_3_icon_name: "Menu nome icona 3" + menu_4_icon_name: "Menu nome icona 4" + menu_5_icon_name: "Menu nome icona 5" + menu_6_icon_name: "Menu nome icona 6" + menu_7_icon_name: "Menu nome icona 7" models: order_cycle: cloned_order_cycle_name: "COPIA DI %{order_cycle}" tax_rate: included_in_price: "Incluso nel prezzo" + open_street_map_enabled: "Open Street Map abilitato" + open_street_map_default_latitude: "Open Street Map latitudine di default" + open_street_map_default_longitude: "Open Street Map longitudine di default" + open_street_map_provider_name: "Open Street Map nome provider" + open_street_map_provider_options: "Open Street Map opzioni provider" + producer_signup_case_studies_html: "HTML iscrizione produttori casi studio" + producer_signup_detail_html: "HTML dettagli iscrizione produttori" + producer_signup_pricing_table_html: "HTML tabella prezzi iscrizione produttore" + producers_social: "Social dei produttori" + resume_order: "Riepilogo richieste" + sku: "SKU" + subtotal: "Subtotale" + tax_rate: "% tasse" validators: date_time_string_validator: not_string_error: "deve essere una stringa" @@ -144,6 +177,7 @@ it: producer_mailer: order_cycle: subject: "Resoconto degli ordini per %{producer}" + provider_settings: "Impostazioni provider" shipment_mailer: shipped_email: dear_customer: "Caro Cliente," @@ -264,7 +298,7 @@ it: error: Errore processing_payment: "Elaborazione pagamento..." no_pending_payments: "Nessun pagamento in sospeso" - invalid_payment_state: "Stato del pagamento non valido" + invalid_payment_state: "Stato pagamento non valido: %{state}" filter_results: Filtra i risultati quantity: Quantità pick_up: Ritiro @@ -300,6 +334,8 @@ it: admin: begins_at: Inizia a begins_on: Inizia da + bill_address: "Indirizzo di fatturazione" + ship_address: "Indirizzo di consegna" customer: Cliente date: Data email: Email @@ -323,7 +359,7 @@ it: shipping_method: Metodo di consegna shop: Negozio sku: articolo gestito a magazzino - status_state: Stato + status_state: Provincia tags: Tag variant: Variante weight: Peso @@ -966,7 +1002,7 @@ it: new_schedule: Nuovo programma name_and_timing_form: name: Nome - orders_open: Richieste aperte a + orders_open: Richieste aperte dal coordinator: Referente orders_close: Gentili richieste chiuse row: @@ -1065,6 +1101,7 @@ it: index: title: "Abbonamenti" new: "Nuovo Abbonamento" + issue: "Issue" new: title: "Nuovo Abbonamento" edit: @@ -1146,6 +1183,7 @@ it: yes_cancel_them: Cancella l'articolo no_keep_them: Tieni l'articolo yes_i_am_sure: Si', sono sicuro + number: "Numero" order_update_issues_msg: Alcuni ordini non possono essere aggiornati automaticamente, molto probabilmente perché sono stati modificati manualmente. Si prega di verificare gli estremi elencati di seguito e di apportare eventuali modifiche ai singoli ordini, se necessario. no_results: no_subscriptions: Ancora nessuna sottoscrizione @@ -1178,8 +1216,10 @@ it: message_html: "Accetto i %{terms_and_conditions_link} del venditore." link_text: "Termini e Condizioni" platform_terms_of_service: + message_html: "Acconsento ai %{tos_link} della piattaforma." terms_of_service: "Termini di Servizio" all_terms_and_conditions: + message_html: "Acconsento ai %{terms_and_conditions_link} del venditore ed ai %{tos_link} della piattaforma." terms_and_conditions: "Termini e Condizioni" terms_of_service: "Termini di Servizio" failed: "Checkout fallito. Contattaci per poter processare il tuo ordine." @@ -1197,7 +1237,7 @@ it: cart: cart: "Carrello" cart_sidebar: - checkout: "Paga" + checkout: "Conferma" edit_cart: "Modifica il carrello" items_in_cart_singular: "%{num} articolo nel tuo carrello" items_in_cart_plural: "%{num} articoli nel tuo carrello" @@ -1314,7 +1354,7 @@ it: postcode: CAP postcode_placeholder: es. 10040 suburb: Comune - state: Stato + state: Provincia country: Paese unauthorized: Non autorizzato terms_of_service: "Termini di servizio" @@ -1441,7 +1481,7 @@ it: stats_shops: "negozi" stats_shoppers: "clienti" stats_orders: "ordini" - checkout_title: Paga + checkout_title: Conferma checkout_now: Paga ora checkout_order_ready: Ordine pronto per checkout_hide: Nascondi @@ -1571,7 +1611,9 @@ it: shopping_tabs_home: "Home" shopping_tabs_shop: "Negozio" shopping_tabs_about: "Descrizione" + shopping_tabs_producers: "Produttori" shopping_tabs_contact: "Contatti" + shopping_tabs_groups: "Reti" shopping_contact_address: "Indirizzo" shopping_contact_web: "Contatti" shopping_contact_social: "Segui" @@ -1723,39 +1765,40 @@ it: shops_signup_help: Siamo pronti ad aiutare. shops_signup_help_text: Ti serve un ritorno migliore. Ti servono nuovi compratori e partner logistici. Ti serve che la tua storia sia raccontata attraverso l'ingrosso, il dettaglio e la tavola della cucina. shops_signup_detail: Ecco il dettaglio. - orders: Gentili richieste - orders_fees: Commissioni... - orders_edit_title: Carrello - orders_edit_headline: Il tuo carrello - orders_edit_time: Ordine pronto per - orders_edit_continue: Continua a comprare - orders_edit_checkout: Paga + orders: "Gentili richieste" + orders_fees: "Commissioni..." + orders_edit_title: "Carrello" + orders_edit_headline: "Il tuo carrello" + orders_edit_time: "Ordine pronto per" + orders_edit_continue: "Continua a comprare" + orders_edit_checkout: "Conferma" orders_form_empty_cart: "Carrello vuoto" - orders_form_subtotal: Calcola il subtotale - orders_form_admin: Admin - orders_form_total: Totale - orders_oc_expired_headline: Gli ordini sono chiusi per questo ciclo di ordini + orders_form_update_cart: "Aggiorna" + orders_form_subtotal: "Calcola il subtotale" + orders_form_admin: "Admin" + orders_form_total: "Totale" + orders_oc_expired_headline: "Gli ordini sono chiusi per questo ciclo di ordini" orders_oc_expired_text: "Spiacenti, gli ordini per questo ciclo son chiusi %{time} da! Per favore contatta direttamente il tuo hub per sapere se accettano ordini tardivi." orders_oc_expired_text_others_html: "Spiacenti, gli ordini per questo ciclo sono chiusi %{time} fa! Per favore contatta direttamente il tuo hub per sapere se accetta ordini tardivi %{link}." orders_oc_expired_text_link: "o vedi gli altri cicli d'ordine disponibili per questo hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Telefono:" - orders_show_title: Conferma Ordine - orders_show_time: Ordine pronto + orders_show_title: "Conferma Ordine" + orders_show_time: "Ordine pronto" orders_show_order_number: "Gentile richiesta #%{number}" - orders_show_cancelled: Annullato - orders_show_confirmed: Confermato + orders_show_cancelled: "Annullato" + orders_show_confirmed: "Confermato" orders_your_order_has_been_cancelled: "La tua gentile richiesta è stata annullata" orders_could_not_cancel: "Ci dispiace, la gentile richiesta non ha potuto essere annullata" orders_cannot_remove_the_final_item: "Non si può rimuovere l'articolo definitivo da una gentile richiesta, per favore annulla piuttosto la gentile richiesta." orders_bought_items_notice: - one: E' già stato confermato un articolo aggiuntivo per questo ciclo di richieste + one: "E' già stato confermato un articolo aggiuntivo per questo ciclo di richieste" few: "%{count} articoli aggiuntivi già confermati in questo ciclo di richieste" many: "%{count} articoli aggiuntivi già confermati in questo ciclo di richieste" other: "%{count} articoli aggiuntivi già confermati in questo ciclo di richieste" - orders_bought_edit_button: Modifica gli articoli confermati + orders_bought_edit_button: "Modifica gli articoli confermati" orders_bought_already_confirmed: "* già confermato" - orders_confirm_cancel: Sei sicura/o di voler annullare questa gentile richiesta? + orders_confirm_cancel: "Sei sicura/o di voler annullare questa gentile richiesta?" order_processed_successfully: "Il tuo ordine è stato elaborato correttamente" products_cart_distributor_choice: "Distributore per il tuo ordine:" products_cart_distributor_change: "Il tuo distributore per questo ordine sarà sostituito da %{name} se aggiungi questo prodotto al tuo carrello." @@ -2003,7 +2046,7 @@ it: admin_enterprise_groups_contact_city_placeholder: "p.es. Sesto" admin_enterprise_groups_contact_zipcode: "CAP" admin_enterprise_groups_contact_zipcode_placeholder: "p.es. 20100" - admin_enterprise_groups_contact_state_id: "Stato" + admin_enterprise_groups_contact_state_id: "Provincia" admin_enterprise_groups_contact_country_id: "Stato" admin_enterprise_groups_web: "Risorse web" admin_enterprise_groups_web_twitter: "p.es. @az_agr" @@ -2131,7 +2174,7 @@ it: admin_share_city: "Comune" admin_share_zipcode: "CAP" admin_share_country: "Stato" - admin_share_state: "Stato" + admin_share_state: "Provincia" hub_sidebar_hubs: "Hubs" hub_sidebar_none_available: "Nussuna disponibilità" hub_sidebar_manage: "Gestisci" @@ -2414,6 +2457,7 @@ it: C'è stato un problema nell'aggiungere questo prodotto al carrello. Forse non é più disponibile o il negozio sta chiudendo. admin: + unit_price_tooltip: "Il prezzo unitario migliora la trasparenza, permettendo ai consumatori di comparare i prezzi tra prodotti e confezioni differenti. Nota che il prezzo unitario finale visibile nella vetrina può differire in quanto include eventuali tariffe e maggiorazioni." enterprise_limit_reached: "Hai raggiunto il limite standard di aziende per account. Scrivi a %{contact_email} se hai bisogno di aumentarlo." modals: got_it: "Capito" @@ -2595,7 +2639,7 @@ it: payment_states: balance_due: "saldo" completed: "completato" - checkout: "paga" + checkout: "conferma" credit_owed: "credito dovuto" failed: "fallito" paid: "pagato" @@ -2810,6 +2854,15 @@ it: start_free_profile: "Inizia con un profilo gratuito e migliora quando sei pronto!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Allocazione in serie" + bulk_coop_customer_payments: "Pagamenti clienti in serie" + bulk_coop_packing_sheets: "Fogli Imballaggi in serie" + bulk_coop_supplier_report: "Report fornitori in serie" + date_range: "Range di date" + generate_report: "Genera report" + report_format_csv: "Report formato CSV" enterprise_fee_summaries: filters: date_range: "Intervallo di date" @@ -2855,6 +2908,8 @@ it: tax_category_name: "Categoria d'imposta" total_amount: "€€ SOMMA" invalid_filter_parameters: "I filtri che hai selezionato per questo report non sono validi" + report: + none: "Nessuno" order: "Gentile Richiesta" distribution: "Distribuzione" order_details: "Dettagli ordine" @@ -2887,7 +2942,54 @@ it: previous: "Precedente" last: "Ultimo" spree: + add_country: "Aggiungi Stato" + add_state: "Aggiungi provincia" + adjustment: "Aggiustamenti" + all: "Tutti" + associated_adjustment_closed: "Aggiustamenti associati chiusi" + authorization_failure: "Autorizzazione fallita" + back_to_adjustments_list: "Indietro ad Aggiustamenti" + back_to_users_list: "Indietro a Utenti" + back_to_zones_list: "Indietro a Zone" + card_code: "Codice carta" + card_number: "Numero carta" + category: "Categoria" + created_successfully: "Creato con successo" + credit: "Credito" + editing_tax_category: "Modifica categoria imposta" + editing_tax_rate: "Modifica imposta" + editing_zone: "Modifica zona" + expiration: "Scadenza" + invalid_payment_provider: "Provider pagamento non valido" + items_cannot_be_shipped: "Gli articoli non possono essere consegnati" + gateway_config_unavailable: "Configurazione Gateway non disponibile" + gateway_error: "Pagamento fallito" more: "Di più" + new_adjustment: "Nuovo aggiustamento" + new_order_completed: "Nuova richiesta completata" + new_tax_category: "Nuova Categoria imposta" + new_taxon: "Nuova tassonomia" + new_user: "Nuovo utente" + no_pending_payments: "Nessun pagamento in sospeso" + none: "Nessuno" + not_found: "Non trovato" + notice_messages: + variant_deleted: "Variante eliminata" + or: "O" + order_processed_successfully: "Richiesta processata con successo" + payment_method_not_supported: "Metodo di pagamento non supportato" + resend_authorization_email: "Invia di nuovo mail di autorizzazione" + rma_credit: "Credito RMA" + server_error: "Errore Server" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Data inizio" + successfully_removed: "Rimosso con successo" + taxonomy_edit: "Modifica tassonomia" + taxonomy_tree_error: "Errore schema tassonomia" + taxonomy_tree_instruction: "Istruzioni schema tassonomia" + tree: "Schema" + updating: "In aggiornamento" your_order_is_empty_add_product: "Il tuo ordine è vuoto, cerca e aggiungi un prodotto qui sopra" add_product: "Aggiungi prodotto" name_or_sku: "Nome o SKU (inserisci almeno i primi 4 caratteri del nome del prodotto)" @@ -2915,6 +3017,7 @@ it: tracking_number: "Numero Tracciamento" order_total: "Ordine totale" customer_details: "Dettagli Cliente" + customer_details_updated: "Dettagli Consumatore aggiornati" customer_search: "Ricerca Clienti" choose_a_customer: "Scegli un cliente" account: "Account" @@ -2927,7 +3030,7 @@ it: city: "Comune" zip: "CAP" country: "Stato" - state: "Stato" + state: "Provincia" phone: "Telefono" update: "Aggiorna" use_billing_address: "Utilizzare l'indirizzo di fatturazione" @@ -3065,6 +3168,8 @@ it: payment_method: "Metodo di pagamento" payment_processing_failed: "Non è stato possibile elaborare il pagamento, per favore controlla i dettagli che hai inserito" not_available: "N/A" + sku: "SKU" + there_are_no_items_for_this_order: "Non ci sono articoli per questa richiesta" order_populator: out_of_stock: '%{item} non è al momento disponibile.' actions: @@ -3092,7 +3197,17 @@ it: login_nav: header: store: Memorizzare + validation: + must_be_int: "deve essere un numero intero" admin: + mail_methods: + send_testmail: "Invia mail prova" + testmail: + delivery_success: "Email prova inviata" + error: "Errore nell'invio della mail prova." + unit_price_tooltip: "Il prezzo unitario migliora la trasparenza, permettendo ai consumatori di comparare i prezzi tra prodotti e confezioni differenti. Nota che il prezzo unitario finale visibile nella vetrina può differire in quanto include eventuali tariffe e maggiorazioni." + subscriptions: + number: "Numero" tab: dashboard: "Pannello di controllo" orders: "Gentili richieste" @@ -3161,6 +3276,8 @@ it: received: "ricevuto" canceled: "Annullato" orders: + add_product: + cannot_add_item_to_canceled_order: "Non è possibile aggiungere articoli a richieste cancellate" index: listing_orders: "Listino Ordini" new_order: "Nuovo ordine" @@ -3183,7 +3300,7 @@ it: shipment_state: "Stato della spedizione" completed_at: "Completo al" number: "Numero" - state: "Stato" + state: "Provincia" email: "E-mail Cliente" invoice: issued_on: "Emesso il" @@ -3203,6 +3320,10 @@ it: overview: enterprises_header: ofn_with_tip: Le aziende sono produttori e/o isole logistiche e sono le unità base dell'organizzazione di OFN + enterprise_row: + has_no_enterprise_fees: "non ha tariffe aziendali" + has_no_payment_methods: "non ha metodi di pagamento" + has_no_shipping_methods: "non ha metodi di consegna" products: active_products: zero: "Non hai prodotti attivi." @@ -3241,6 +3362,7 @@ it: back_to_shipping_methods_list: "Torna alla lista dei metodi di spedizione" form: categories: "categorie" + tax_category: "Categoria d'imposta" zones: "Zone" both: "Entrambi Checkout e Back Office" back_end: "Solo Back office" @@ -3321,6 +3443,8 @@ it: value: "Valore" unit_name: "Nome Unità" price: "Prezzo" + unit_price: "Prezzo unitario" + unit_price_legend: "Calcolato in base al prezzo articolo" on_hand: "Disponibile" on_demand: "A richiesta" product_description: "Descrizione prodotto" @@ -3391,7 +3515,6 @@ it: price: "Prezzo" options: "Opzioni" no_results: "Nessun risultato" - to_add_variants_you_must_first_define: "Per aggiungere varianti, devi prima definire" option_types: "Tipi di opzioni" option_values: "Valori opzione" and: "e" @@ -3403,6 +3526,7 @@ it: form: sku: "SKU" price: "Prezzo" + unit_price: "Prezzo unitario" display_as: "Visualizza come" display_name: "Nome da visualizzare" display_as_placeholder: 'es. 2 kg' @@ -3415,7 +3539,7 @@ it: sortable_header: name: "Nome" number: "Numero" - state: "Stato" + state: "Provincia" payment_state: "Stato Pagamento" shipment_state: "Stato della spedizione" email: "Email" @@ -3426,6 +3550,7 @@ it: cookies_consent_banner_toggle: "Mostra banner di consenso per i cookie" privacy_policy_url: "Privacy Policy URL" enterprises_require_tos: "Le aziende devono accettare i Termini di Servizio" + shoppers_require_tos: "Gli acquirenti devono accettare i Termini di Servizio" cookies_policy_matomo_section: "Visualizza la sezione di Matomo nella pagina della cookie policy" footer_tos_url: "URL Termini di Servizio" checkout: @@ -3443,8 +3568,8 @@ it: or_enter_new_card: "Oppure, inserire dettagli di una nuova carta" remember_this_card: Ricordare questa Carta? date_picker: - flatpickr_date_format: "G-m-a" - flatpickr_datetime_format: "G-m-a H:m" + flatpickr_date_format: "Y-m-d" + flatpickr_datetime_format: "Y-m-d H:i" today: "Oggi" now: "Adesso" orders: @@ -3467,7 +3592,7 @@ it: payment_states: balance_due: saldo completed: completato - checkout: paga + checkout: conferma credit_owed: credito dovuto failed: fallito paid: pagato @@ -3638,3 +3763,42 @@ it: spree/payment: one: Pagamento other: Pagamenti + datetime: + distance_in_words: + about_x_hours: + one: circa 1 ora + other: circa %{count} ore + about_x_months: + one: circa 1 mese + other: circa %{count} mesi + about_x_years: + one: cica 1 anno + other: circa %{count} anni + almost_x_years: + one: almeno 1 anno + other: almeno %{count} anni + half_a_minute: mezzo minuto + less_than_x_seconds: + one: meno di 1 secondo + other: meno di %{count} secondi + less_than_x_minutes: + one: meno di un minuto + other: meno di %{count} minuti + over_x_years: + one: oltre 1 anno + other: oltre %{count} anni + x_seconds: + one: "1 secondo" + other: "%{count} secondi" + x_minutes: + one: "1 minuto" + other: "%{count} minuti" + x_days: + one: "1 giorno" + other: "%{count} giorni" + x_months: + one: "1 mese" + other: "%{count} mesi" + x_years: + one: "1 anno" + other: "%{count} anni" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index dc9912f6e2..83ca1ff00a 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -85,6 +85,11 @@ nb: no_default_card: "^Ingen standardkort tilgjengelig for denne kunden" shipping_method: not_available_to_shop: "er ikke tilgjengelig for %{shop}" + card_details: "Kortdetaljer" + card_type: "Korttype" + cardholder_name: "Kortholders navn" + community_forum_url: "URL for diskusjonsforum" + customer_instructions: "Kundeinstruksjoner" devise: confirmations: send_instructions: "Du vil motta en epost med instruksjoner om hvordan du bekrefter kontoen din om noen få minutter." @@ -114,9 +119,39 @@ nb: updated_not_active: "Ditt passord har blitt tilbakestilt, men epostadressen din er ikke bekreftet enda." updated: "Passordendringen var vellykket. Du er nå pålogget." send_instructions: "Du vil motta en epost med instruksjoner om hvordan du bekrefter kontoen din om noen få minutter." + home_page_alert_html: "HTML for varsler på hjemmeside " + hub_signup_case_studies_html: "Hub-registrering studier HTML" + hub_signup_detail_html: "Hub registrering detaljer HTML" + hub_signup_pricing_table_html: "Hub-registrering pristabell HTML" + group_signup_case_studies_html: "Gruppe registrering casestudier HTML" + group_signup_detail_html: "Gruppe registrering detaljer HTML" + group_signup_pricing_table_html: "Gruppe registrering pristabell HTML" + item_description: "Varebeskrivelse" + menu_1_icon_name: "Meny 1 ikonnavn" + menu_2_icon_name: "Meny 2 ikonnavn" + menu_3_icon_name: "Meny 3 ikonnavn" + menu_4_icon_name: "Meny 4 ikonnavn" + menu_5_icon_name: "Meny 5 ikonnavn" + menu_6_icon_name: "Meny 6 ikonnavn" + menu_7_icon_name: "Meny 7 ikonnavn" models: order_cycle: cloned_order_cycle_name: "KOPI AV %{order_cycle}" + tax_rate: + included_in_price: "Inkludert i prisen" + open_street_map_enabled: "Open Street Map aktivert" + open_street_map_default_latitude: "Open Street Map standard breddegrad" + open_street_map_default_longitude: "Open Street Map standard lengdegrad" + open_street_map_provider_name: "Open Street Map leverandørnavn" + open_street_map_provider_options: "Open Street Map leverandørvalg" + producer_signup_case_studies_html: "Produsentregistrering casestudier HTML" + producer_signup_detail_html: "Produsentregistrering detaljer HTML" + producer_signup_pricing_table_html: "Produsent registrering pristabell HTML" + producers_social: "Produsenter sosiale" + resume_order: "Gjenoppta bestillingen" + sku: "SKU" + subtotal: "Subtotal" + tax_rate: "Avgiftsrate" validators: date_time_string_validator: not_string_error: "må være en streng" @@ -142,6 +177,7 @@ nb: producer_mailer: order_cycle: subject: "Bestillingsrunderapport for %{producer}" + provider_settings: "Leverandørinnstillinger" shipment_mailer: shipped_email: dear_customer: "Kjære Kunde," @@ -262,7 +298,7 @@ nb: error: Feil processing_payment: "Behandler betaling ..." no_pending_payments: "Ingen ventende betalinger" - invalid_payment_state: "Ugyldig betalingstilstand" + invalid_payment_state: "Ugyldig betalingsstatus: %{state}" filter_results: Filtrer Resultater quantity: Mengde pick_up: Hent @@ -296,8 +332,12 @@ nb: destroy: "Fjern" rename: "Gi nytt navn" admin: + adjustments: + skipped_changing_canceled_order: "Du kan ikke endre en avbrutt bestilling." begins_at: Begynner på begins_on: Begynner på + bill_address: "Fakturaadresse" + ship_address: "Leveringsadresse" customer: Kunde date: Dato email: Epost @@ -1062,6 +1102,7 @@ nb: index: title: "Abonnement" new: "Nytt abonnement" + issue: "Problem" new: title: "Nytt abonnement" edit: @@ -1143,6 +1184,7 @@ nb: yes_cancel_them: Avbryt dem no_keep_them: Behold dem yes_i_am_sure: Ja jeg er sikker + number: "Antall" order_update_issues_msg: Noen bestillinger kan ikke oppdateres automatisk, dette er mest sannsynlig fordi de har blitt redigert manuelt. Vennligst gå gjennom problemene som er oppført nedenfor, og gjør eventuelle tilpasninger til individuelle bestillinger om nødvendig. no_results: no_subscriptions: Ingen abonnement ennå... @@ -1175,8 +1217,10 @@ nb: message_html: "Jeg godtar selgers %{terms_and_conditions_link}." link_text: "Vilkår og Betingelser" platform_terms_of_service: + message_html: "Jeg godtar plattformens %{tos_link}." terms_of_service: "Vilkår for bruk" all_terms_and_conditions: + message_html: "Jeg godtar selgerens %{terms_and_conditions_link} og plattformens %{tos_link}." terms_and_conditions: "Vilkår og Betingelser" terms_of_service: "Vilkår for bruk" failed: "Utsjekk fra kassen mislyktes. Gi oss beskjed slik at vi kan behandle bestillingen din." @@ -1189,6 +1233,7 @@ nb: mailers: powered_by: open_food_network: "Open Food Network" + powered_html: "Din handleopplevelse er drevet av %{open_food_network}." menu: cart: cart: "Handlekurv" @@ -1555,6 +1600,7 @@ nb: set_a_password: "Du blir da bedt om å angi et passord før du kan administrere bedriften." mistakenly_sent: "Ikke sikker på hvorfor du har mottatt denne e-posten? Kontakt %{owner_email} for mer informasjon." producer_mail_greeting: "Kjære" + producer_mail_text_before: "Nedenfor finner du en oppdatering om bestillingssyklusen klar for:" producer_mail_order_text: "Her er en oppsummering av bestillingene:" producer_mail_delivery_instructions: "Henting / leveringsdetaljer :" producer_mail_signoff: "Med vennlig hilsen" @@ -1566,7 +1612,9 @@ nb: shopping_tabs_home: "Hjem" shopping_tabs_shop: "Butikk" shopping_tabs_about: "Om" + shopping_tabs_producers: "Produsenter" shopping_tabs_contact: "Kontakt" + shopping_tabs_groups: "Grupper" shopping_contact_address: "Adresse" shopping_contact_web: "Kontakt" shopping_contact_social: "Følg" @@ -1718,39 +1766,40 @@ nb: shops_signup_help: Vi er klar til å hjelpe. shops_signup_help_text: Du trenger bedre resultater. Du trenger nye kunder og logistikkpartnere. Du trenger å få din historie fortalt hos grossister, i dagligvaren og rundt kjøkkenbordet. shops_signup_detail: Detaljene. - orders: Bestillinger - orders_fees: Gebyrer... - orders_edit_title: Handlekurv - orders_edit_headline: Din handlekurv - orders_edit_time: Bestilling klar for - orders_edit_continue: Fortsett å handle - orders_edit_checkout: Kassen + orders: "Bestillinger" + orders_fees: "Gebyrer..." + orders_edit_title: "Handlekurv" + orders_edit_headline: "Din handlekurv" + orders_edit_time: "Bestilling klar for" + orders_edit_continue: "Fortsett å handle" + orders_edit_checkout: "Kassen" orders_form_empty_cart: "Tøm handlekurv" - orders_form_subtotal: Delsum varer - orders_form_admin: Admin & Håndtering - orders_form_total: Total - orders_oc_expired_headline: Bestillinger stengt for denne runden + orders_form_update_cart: "Oppdater" + orders_form_subtotal: "Delsum varer" + orders_form_admin: "Admin & Håndtering" + orders_form_total: "Total" + orders_oc_expired_headline: "Bestillinger stengt for denne runden" orders_oc_expired_text: "Beklager, bestillinger for denne runden stengte for %{time} siden! Kontakt din hub direkte for å høre om de tar i mot sene bestillinger." orders_oc_expired_text_others_html: "Beklager, bestillinger for denne runden stengte for %{time} siden! Kontakt din hub direkte for å høre om de tar i mot sene bestillinger %{link}." orders_oc_expired_text_link: "eller se på de andre bestillinsrundene tilgjengelig fra denne huben" orders_oc_expired_email: "Epost:" orders_oc_expired_phone: "Telefon:" - orders_show_title: Ordrebekreftelse - orders_show_time: Bestilling klar for + orders_show_title: "Ordrebekreftelse" + orders_show_time: "Bestilling klar for" orders_show_order_number: "Bestilling # %{number}" - orders_show_cancelled: Avbrutt - orders_show_confirmed: Bekreftet + orders_show_cancelled: "Avbrutt" + orders_show_confirmed: "Bekreftet" orders_your_order_has_been_cancelled: "Din bestilling er avbrutt" orders_could_not_cancel: "Beklager, bestillingen kunne ikke avbrytes" orders_cannot_remove_the_final_item: "Kan ikke fjerne den siste varen fra en bestilling, vennligst avbryt bestillingen i stedet." orders_bought_items_notice: - one: En ekstra vare er allerede bekreftet for denne bestillingsrunden + one: "En ekstra vare er allerede bekreftet for denne bestillingsrunden" few: "Ytterligere%{count} varer er allerede bekreftet for denne bestillingsrunden" many: "Ytterligere%{count} varer er allerede bekreftet for denne bestillingsrunden" other: "Ytterligere%{count} varer er allerede bekreftet for denne bestillingsrunden" - orders_bought_edit_button: Rediger bekreftede varer + orders_bought_edit_button: "Rediger bekreftede varer" orders_bought_already_confirmed: "* allerede bekreftet" - orders_confirm_cancel: Er du sikker på at du vil avbryte denne bestillingen? + orders_confirm_cancel: "Er du sikker på at du vil avbryte denne bestillingen?" order_processed_successfully: "Behandlingen av din bestilling var vellykket" products_cart_distributor_choice: "Distributør for bestillingen:" products_cart_distributor_change: "Din distributør for denne ordren vil bli endret til %{name} hvis du legger til dette produktet i handlekurven din." @@ -2324,6 +2373,8 @@ nb: payment_processing_failed: "Betalingen kunne ikke behandles, vennligst sjekk detaljene du skrev inn" payment_method_not_supported: "Den betalingsmåten støttes ikke. Velg en annen." payment_updated: "Betaling Oppdatert" + cannot_perform_operation: "Kunne ikke oppdatere betalingen" + action_required: "Handling kreves" inventory_settings: "Beholdningsinnstillinger" tag_rules: "Regler merkelapper" shop_preferences: "Butikkvalg" @@ -2385,6 +2436,7 @@ nb: js: saving: 'Lagrer...' changes_saved: 'Endringene er lagret.' + authorising: "Autoriserer..." save_changes_first: Lagre endringer først. all_changes_saved: Alle endringer lagret unsaved_changes: Du har ulagrede endringer @@ -2406,6 +2458,7 @@ nb: Det oppsto et problem med å legge dette produktet til handlekurven. Kanskje den har blitt utilgjengelig eller butikken stenger. admin: + unit_price_tooltip: "Enhetsprisen øker gjennomsiktigheten ved at kundene dine enkelt kan sammenligne priser mellom forskjellige produkter og emballasjestørrelser. Merk at den endelige enhetsprisen som vises i butikken, kan variere ettersom den inkluderer skatter og avgifter." enterprise_limit_reached: "Du har nådd standardgrensen for bedrifter per konto. Skriv til %{contact_email} hvis du trenger å øke den." modals: got_it: "Jeg forstår" @@ -2592,6 +2645,8 @@ nb: processing: "behandler" void: "ugyldig" invalid: "ugyldig" + quantity_adjusted: "Utilstrekkelig lager tilgjengelig. Ordrelinje oppdatert til maksimalt tilgjengelig antall." + quantity_unchanged: "Antall uendret fra forrige mengde." resend_user_email_confirmation: resend: "Send på nytt" sending: "Send på nytt ..." @@ -2648,6 +2703,7 @@ nb: min_quantity: "Min. mengde" max_quantity: "Max mengde" price_breakdown: "Prisfordeling" + unit_price_tooltip: "Dette er enhetsprisen på dette produktet. Det lar deg sammenligne prisen på produkter uavhengig av størrelser og vekt." variants: on_demand: 'yes': "Ved forespørsel" @@ -2793,6 +2849,15 @@ nb: start_free_profile: "Start med en gratis profil, og utvid når du er klar!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Bulk Co-op Tildeling" + bulk_coop_customer_payments: "Bulk Co-op kundebetalinger" + bulk_coop_packing_sheets: "Bulk Co-op pakkeliste" + bulk_coop_supplier_report: "Bulk Co-op Leverandørrapport" + date_range: "Datointervall" + generate_report: "Generer rapport" + report_format_csv: "Rapportformat CSV" enterprise_fee_summaries: filters: date_range: "Datointervall" @@ -2838,6 +2903,8 @@ nb: tax_category_name: "Avgiftskategori" total_amount: "$$ SUM" invalid_filter_parameters: "Filtrene du valgte for denne rapporten er ugyldige." + report: + none: "Ingen" order: "Bestilling" distribution: "Distribusjon" order_details: "Ordredetaljer" @@ -2870,12 +2937,60 @@ nb: previous: "Tidligere" last: "Siste" spree: + add_country: "Legg til land" + add_state: "Legg til fylke" + adjustment: "Justering" + all: "Alle" + associated_adjustment_closed: "Tilknyttet justering lukket" + authorization_failure: "Autorisasjonsfeil" + back_to_adjustments_list: "Tilbake til justeringer" + back_to_users_list: "Tilbake til brukere" + back_to_zones_list: "Tilbake til soner" + card_code: "Kortkode" + card_number: "Kortnummer" + category: "Kategori" + created_successfully: "Opprettet vellykket" + credit: "Kreditt" + editing_tax_category: "Redigering av avgiftskategori" + editing_tax_rate: "Redigering av avgiftssats" + editing_zone: "Redigeringssone" + expiration: "Utløp" + invalid_payment_provider: "Ugyldig betalingsleverandør" + items_cannot_be_shipped: "Varer kan ikke sendes" + gateway_config_unavailable: "Gateway-konfigurasjon utilgjengelig" + gateway_error: "Betalingen feilet" more: "Mer" + new_adjustment: "Ny justering" + new_order_completed: "Ny bestilling fullført" + new_tax_category: "Ny avgiftskategori" + new_taxon: "Ny kategori" + new_user: "Ny bruker" + no_pending_payments: "Ingen ventende betalinger" + none: "Ingen" + not_found: "Ikke funnet" + notice_messages: + variant_deleted: "Variant slettet" + or: "Eller" + order_processed_successfully: "Bestillingen ble behandlet" + payment_method_not_supported: "Betalingsmåte støttes ikke" + resend_authorization_email: "Send autorisasjons-epost på nytt" + rma_credit: "RMA-kreditt" + server_error: "Serverfeil" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Startdato" + successfully_removed: "Fjernet OK" + taxonomy_edit: "Rediger kategori" + taxonomy_tree_error: "Feil i kategoritre" + taxonomy_tree_instruction: "Instruksjon for kategoritre" + tree: "Tre" + updating: "Oppdaterer" your_order_is_empty_add_product: "Bestillingen din er tom, vennligst søk etter og legg til et produkt over" add_product: "Legg til produkt" name_or_sku: "Navn eller SKU (skriv inn minst 4 tegn av produktnavn)" resend: "Send på nytt" back_to_orders_list: "Tilbake til Bestillingsliste" + back_to_payments_list: "Tilbake til betalingsliste" return_authorizations: "Returautorisasjoner" cannot_create_returns: "Kan ikke opprette retur da denne bestillingen ikke har noen sendte elementer." select_stock: "Velg lager" @@ -2897,6 +3012,7 @@ nb: tracking_number: "Sporingsnummer" order_total: "Bestilling Totalt" customer_details: "Kundedetaljer" + customer_details_updated: "Kundedetaljer oppdatert" customer_search: "Kundesøk" choose_a_customer: "Velg en kunde" account: "Konto" @@ -2949,6 +3065,7 @@ nb: display_currency: "Vis valuta" choose_currency: "Velg Valuta" mail_method_settings: "Innstillinger for epost-metode" + mail_settings_notice_html: "Noen av følgende innstillinger kan ikke redigeres og er oppført her bare for feilsøking. Endringer kan gjøres ved å oppdatere plattformens secrets og klargjøre dem ved hjelp av ofn-install . Kontakt OFNs globale team for mer informasjon." general: "Generelt" enable_mail_delivery: "Aktiver epost-levering" send_mails_as: "Send Eposter Som" @@ -3046,6 +3163,8 @@ nb: payment_method: "Betalingsmetode" payment_processing_failed: "Betalingen kunne ikke behandles, vennligst sjekk detaljene du skrev inn" not_available: "Ikke relevant" + sku: "SKU" + there_are_no_items_for_this_order: "Det er ingen varer for denne bestillingen." order_populator: out_of_stock: '%{item} er utsolgt.' actions: @@ -3066,13 +3185,24 @@ nb: payment_state: "Betalingsstatus" errors: messages: + included_price_validation: "kan ikke velges med mindre du har angitt en standard Avgiftssone" blank: "kan ikke være tomt" layouts: admin: login_nav: header: store: Butikk + validation: + must_be_int: "må være et heltall" admin: + mail_methods: + send_testmail: "Send test-epost" + testmail: + delivery_success: "Test-epost sendt." + error: "Det oppsto en feil under forsøk på å sende test-eposten." + unit_price_tooltip: "Enhetsprisen øker gjennomsiktigheten ved at kundene dine enkelt kan sammenligne priser mellom forskjellige produkter og emballasjestørrelser. Merk at den endelige enhetsprisen som vises i butikken, kan variere ettersom den inkluderer skatter og avgifter." + subscriptions: + number: "Antall" tab: dashboard: "Dashboard" orders: "Bestillinger" @@ -3141,6 +3271,8 @@ nb: received: "Mottatt" canceled: "Avbrutt" orders: + add_product: + cannot_add_item_to_canceled_order: "Kan ikke legge varen til den avbrutte bestillingen" index: listing_orders: "Lister opp bestillinger" new_order: "Ny bestilling" @@ -3183,6 +3315,10 @@ nb: overview: enterprises_header: ofn_with_tip: Bedrifter er Produsenter og / eller Hubs og er den grunnleggende organisasjonsenheten innen Open Food Network. + enterprise_row: + has_no_enterprise_fees: "har ingen bedriftsavgifter" + has_no_payment_methods: "har ingen betalingsmåter" + has_no_shipping_methods: "har ingen leveringmetoder" products: active_products: zero: "Du har ingen aktive produkter." @@ -3221,6 +3357,7 @@ nb: back_to_shipping_methods_list: "Tilbake til liste over leveringsmetoder" form: categories: "Kategorier" + tax_category: "Avgiftskategori" zones: "Soner" both: "Både Utsjekk og Backoffice" back_end: "Kun backoffice" @@ -3276,6 +3413,13 @@ nb: deactivation_warning: "Ved å deaktivere en betalingsmetode kan den forsvinne fra listen din. Alternativt kan du skjule en betalingsmetode fra kassen ved å sette alternativet "Vis" til "Kun Backoffice"." providers: provider: "Tilbyder" + check: "Kontanter/ EFT/osv. (betalinger som det ikke kreves automatisk validering av)" + pin: "Pin Payments" + paypalexpress: "PayPal Express" + stripeconnect: "Stripe" + stripesca: "Stripe SCA" + bogus: "Bogus" + bogussimple: "BogusSimple" payments: source_forms: stripe: @@ -3294,6 +3438,8 @@ nb: value: "Verdi" unit_name: "Enhetsnavn" price: "Pris" + unit_price: "Enhetspris" + unit_price_legend: "Beregnet basert på vareprisen" on_hand: "Tilgjengelig" on_demand: "Ved forespørsel" product_description: "Produktbeskrivelse" @@ -3364,7 +3510,6 @@ nb: price: "Pris" options: "Valg" no_results: "Ingen resultater" - to_add_variants_you_must_first_define: "For å legge til varianter, må du først definere" option_types: "Valgtyper" option_values: "Valgverdier" and: "og" @@ -3376,6 +3521,7 @@ nb: form: sku: "SKU" price: "Pris" + unit_price: "Enhetspris" display_as: "Vis som" display_name: "Visningsnavn" display_as_placeholder: 'f.eks. 2 kg' @@ -3399,6 +3545,7 @@ nb: cookies_consent_banner_toggle: "Vis informasjonskapsler samtykkebanner" privacy_policy_url: "Personvernspolicy URL" enterprises_require_tos: "Bedrifter må godta Tjenestevilkår" + shoppers_require_tos: "Kundene må godta vilkårene for bruk" cookies_policy_matomo_section: "Vis Matomo-delen på informasjonskapsler-siden" footer_tos_url: "Vilkår URL" checkout: @@ -3416,6 +3563,9 @@ nb: or_enter_new_card: "Eller skriv inn detaljer for et nytt kort:" remember_this_card: Husk dette kortet? date_picker: + flatpickr_date_format: "Y-m-d" + flatpickr_datetime_format: "Y-m-d H:i" + today: "I dag" now: "Nå" orders: error_flash_for_unavailable_items: "En vare i handlekurven din er blitt utilgjengelig. Oppdater valgte mengder." @@ -3433,6 +3583,7 @@ nb: pending: ventende ready: klar shipped: sendt + canceled: avbrutt payment_states: balance_due: balanse forfaller completed: fullført @@ -3444,6 +3595,7 @@ nb: processing: behandler void: ugyldig invalid: ugyldig + authorise: autorisere order_mailer: cancel_email: customer_greeting: "Kjære %{name}," @@ -3458,6 +3610,8 @@ nb: cancel_email_for_shop: greeting: "Kjære %{name}," subject: "Kansellering av bestilling" + intro: "En kunde har avbrutt bestillingen sin # %{number}." + view_cancelled_order: "Vis avbrutt bestilling" confirm_email: subject: "Ordrebekreftelse" invoice_email: @@ -3476,6 +3630,13 @@ nb: subject: "Tilbakestill passordinstruksjonene" confirmation_instructions: subject: "Vennligst bekreft OFN-kontoen din" + payment_mailer: + authorize_payment: + subject: "Vennligst autoriser betalingen din til %{distributor} på OFN" + instructions: "Din betaling av %{amount} til %{distributor} krever ytterligere godkjenning. Gå til følgende URL for å godkjenne betalingen din:" + authorization_required: + subject: "En betaling krever autorisasjon fra kunden" + message: "En betaling for bestilling %{order_number} krever ytterligere autorisasjon fra kunden. Kunden har fått beskjed via epost og betalingen vil fremstå som ventende til den er autorisert." shipment_mailer: shipped_email: dear_customer: "Kjære Kunde," @@ -3512,7 +3673,23 @@ nb: paused: pauset canceled: avbrutt paypal: + already_refunded: "Denne betalingen er tilbakebetalt og det kan ikke gjøres noe mer med den." + no_payment_via_admin_backend: "Du kan ikke belaste PayPal-kontoer via administrator-backend på dette tidspunktet." + transaction: "PayPal-transaksjon" + payer_id: "Betaler-ID" + transaction_id: "Transaksjons-ID" + token: "Token" + refund: "Refusjon" refund_amount: "Antall" + original_amount: "Opprinnelig beløp: %{amount}" + refund_successful: "PayPal-tilbakebetaling vellykket" + refund_unsuccessful: "PayPal tilbakebetaling mislyktes" + actions: + refund: "Refusjon" + flash: + cancel: "Vil du ikke bruke PayPal? Ingen problemer." + connection_failed: "Kunne ikke koble til PayPal." + generic_error: "PayPal mislyktes. %{reasons}" users: form: account_settings: Kontoinnstillinger @@ -3528,6 +3705,8 @@ nb: past_orders: Tidligere Bestillinger transactions: transaction_history: Transaksjonshistorie + authorisation_required: Autorisasjon kreves + authorise: Autorisere open_orders: order: Bestilling shop: Butikk @@ -3579,3 +3758,42 @@ nb: spree/payment: one: innbetaling other: Betalinger + datetime: + distance_in_words: + about_x_hours: + one: omtrent 1 time + other: omtrent %{count} timer + about_x_months: + one: ca 1 måned + other: ca %{count} måneder + about_x_years: + one: ca 1 år + other: ca %{count} år + almost_x_years: + one: nesten 1 år + other: nesten %{count} år + half_a_minute: et halvt minutt + less_than_x_seconds: + one: mindre enn 1 sekund + other: mindre enn %{count} sekunder + less_than_x_minutes: + one: mindre enn ett minutt + other: mindre enn %{count} minutter + over_x_years: + one: over 1 år + other: over %{count} år + x_seconds: + one: "1 sekund" + other: "%{count} sekunder" + x_minutes: + one: "1 minutt" + other: "%{count} minutter" + x_days: + one: "1 dag" + other: "%{count} dager" + x_months: + one: "1 måned" + other: "%{count} måneder" + x_years: + one: "1 år" + other: "%{count} år" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index 927f72b893..c8073ebf00 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -84,6 +84,7 @@ nl_BE: no_default_card: "^Er is geen standaardkaart beschikbaar voor deze klant" shipping_method: not_available_to_shop: "is niet beschikbaar voor %{shop}" + customer_instructions: "Klantenaanwijzingen" devise: confirmations: send_instructions: "U ontvangt een e-mail met instructies over hoe u uw account binnen enkele minuten kunt bevestigen." @@ -116,6 +117,8 @@ nl_BE: models: order_cycle: cloned_order_cycle_name: "KOPIE VAN %{order_cycle}" + sku: "SKU" + tax_rate: "BTW-tarief" validators: date_time_string_validator: not_string_error: "moet een snaar zijn" @@ -261,7 +264,6 @@ nl_BE: error: Fout processing_payment: "Verwerking van de betaling....." no_pending_payments: "Geen betaling in afhandeling" - invalid_payment_state: "Onjuiste betaling status" filter_results: Filter resultaten quantity: Kwantiteit pick_up: Afhalen @@ -1131,6 +1133,7 @@ nl_BE: yes_cancel_them: 'Annuleer ze ' no_keep_them: Behoud ze yes_i_am_sure: Ja, ik ben zeker + number: "Nummer" order_update_issues_msg: Sommige bestellingen konden niet automatisch geüpdatet worden, dit is de meest waarschijnlijke omdat ze handmatig werden aangepast. Kijk alsjeblieft eens naar de hieronder opgelijste aspecten en maak aanpassingen aan specifieke bestellingen indien nodig. no_results: no_subscriptions: Er zijn nog geen abonnementen... @@ -1544,7 +1547,9 @@ nl_BE: shopping_tabs_home: "Start" shopping_tabs_shop: "winkel" shopping_tabs_about: "Over" + shopping_tabs_producers: "Producenten" shopping_tabs_contact: "Contact" + shopping_tabs_groups: "Groepen" shopping_contact_address: "Adres" shopping_contact_web: "Contact" shopping_contact_social: "Volg" @@ -1694,28 +1699,29 @@ nl_BE: shops_signup_help: We zijn klaar om te helpen. shops_signup_help_text: Je hebt een betere winst nodig. Je hebt nood aan kopers en logistieke partners. Je moet een verhaal verkocht krijgen aan groothandelaren, retail en aan de keukentafel. shops_signup_detail: Hier is het plaatje gedetailleerder. - orders: Bestellingen - orders_fees: Kosten... - orders_edit_title: Winkelwagentje - orders_edit_headline: Je winkelwagentje - orders_edit_time: Bestellingen klaar tegen - orders_edit_continue: Ga verder met winkelen - orders_edit_checkout: Kassa + orders: "Bestellingen" + orders_fees: "Kosten..." + orders_edit_title: "Winkelwagentje" + orders_edit_headline: "Je winkelwagentje" + orders_edit_time: "Bestellingen klaar tegen" + orders_edit_continue: "Ga verder met winkelen" + orders_edit_checkout: "Kassa" orders_form_empty_cart: "Maak je winkelwagentje leeg" - orders_form_subtotal: subtotaal Producten - orders_form_admin: Beheer & Behandeling - orders_form_total: Totaal - orders_oc_expired_headline: Bestellingen zijn gesloten voor deze bestellingscyclus + orders_form_update_cart: "Update" + orders_form_subtotal: "subtotaal Producten" + orders_form_admin: "Beheer & Behandeling" + orders_form_total: "Totaal" + orders_oc_expired_headline: "Bestellingen zijn gesloten voor deze bestellingscyclus" orders_oc_expired_text: "Sorry, bestellingen voor deze bestellingscyclus zijn %{time} geleden gesloten! Contacteer alsjeblief rechtstreeks een hub om te zien indien ze of ze laattijdige bestellingen kunnen accepteren." orders_oc_expired_text_others_html: "Sorry, bestellingen voor deze cyclus zijn %{time} geleden gesloten! Contacteer alsjeblief een hub rechtstreeks om te kijken of ze laattijdige bestellingen kunnen accepteren %{link}." orders_oc_expired_text_link: "of kijk eens naar de andere bestellingscycli beschikbaar in deze hub" orders_oc_expired_email: "E-Mail:" orders_oc_expired_phone: "Telefoon:" - orders_show_title: Bestellingsinformatie - orders_show_time: Bestelling klaar op + orders_show_title: "Bestellingsinformatie" + orders_show_time: "Bestelling klaar op" orders_show_order_number: "Bestelling #%{number}" - orders_show_cancelled: Geannuleerd - orders_show_confirmed: Bevestigd + orders_show_cancelled: "Geannuleerd" + orders_show_confirmed: "Bevestigd" orders_your_order_has_been_cancelled: "Je bestelling werd geannuleerd" orders_could_not_cancel: "Sorry, de bestelling kon niet worden geannuleerd" orders_cannot_remove_the_final_item: "Het is niet mogelijk om het laatste artikel van de bestelling te verwijderen, verwijder in plaats daarvan alsjeblieft de bestelling." @@ -1723,9 +1729,9 @@ nl_BE: few: "%{count}bijkomende artikels zijn reeds bevestigd voor deze bestellingscyclus" many: "%{count}bijkomende artikels zijn reeds bevestigd voor deze bestellingscyclus" other: "%{count}bijkomende artikels zijn reeds bevestigd voor deze bestellingscyclus" - orders_bought_edit_button: Pas de bevestigde artikels aan + orders_bought_edit_button: "Pas de bevestigde artikels aan" orders_bought_already_confirmed: "* reeds bevestigd" - orders_confirm_cancel: Ben je zeker dat je deze bestelling wil annuleren? + orders_confirm_cancel: "Ben je zeker dat je deze bestelling wil annuleren?" order_processed_successfully: "Je bestelling is met succes geplaatst" products_cart_distributor_choice: "Verdeler voor jouw bestelling:" products_cart_distributor_change: "Je verdeler voor deze bestelling zal vervangen worden door %{name} indien je dit product toevoegt aan je winkelwagentje." @@ -2681,6 +2687,9 @@ nl_BE: start_free_profile: "Eerst uw bedrijfsprofiel maken en wijzig de formule als U klaar bent !" order_management: reports: + bulk_coop: + filters: + generate_report: "Ontwikkel verslag" enterprise_fee_summaries: filters: date_range: "Datumbereik" @@ -2726,6 +2735,8 @@ nl_BE: tax_category_name: "Belastingcategorie" total_amount: "€€ SUM" invalid_filter_parameters: "De filters voor dit verslag zijn ongeldig." + report: + none: "Geen enkele" order: "Bestelling" distribution: "Distributie" order_details: "Bestellingsgegevens" @@ -2758,7 +2769,13 @@ nl_BE: previous: "Voorgaande" last: "Laatst" spree: + all: "Universum" + category: "Categorie" + credit: "Krediet" more: "Meer" + no_pending_payments: "Geen betaling in afhandeling" + none: "Geen enkele" + updating: "Updatend" your_order_is_empty_add_product: "Je bestelling is leeg, gelieve hierboven een product te zoeken en toe te voegen " add_product: "Voeg een product toe" name_or_sku: "Beschrijving of artikelnummer ( tenminste 4 letters van de productnaam invoeren )" @@ -2927,6 +2944,7 @@ nl_BE: successfully_updated: '%{resource}is succesvol bijgewerkt!' payment_method: "Betaalmethode" payment_processing_failed: "De betaling is niet succesvol, gelieve de ingevoerde gegevens na te kijken" + sku: "SKU" actions: update: "Update" cancel: "Annuleren" @@ -2947,6 +2965,8 @@ nl_BE: header: store: Zicht koper admin: + subscriptions: + number: "Nummer" tab: dashboard: "Dashboard" orders: "Bestellingen" @@ -3095,6 +3115,7 @@ nl_BE: back_to_shipping_methods_list: "Terug naar Verzendmethodenlijst" form: categories: "Categorieën" + tax_category: "Belastingcategorie" zones: "Zones " both: "Bijden uitchecken en Back office" back_end: "Aleen Back Office" @@ -3168,6 +3189,7 @@ nl_BE: value: "Waarde" unit_name: "Unit naam" price: "Prijs" + unit_price: "Stukprijs" on_hand: "Bij de Hand" on_demand: "Op Aanvraag" product_description: "Beschrijving product" @@ -3238,7 +3260,6 @@ nl_BE: price: "Prijs" options: "Opties" no_results: "Geen resultaten " - to_add_variants_you_must_first_define: "Om varianten toetevoegen moet u eerst bepalen" option_types: "Optietypen" option_values: "Waarden opties" and: "En" @@ -3250,6 +3271,7 @@ nl_BE: form: sku: "SKU" price: "Prijs" + unit_price: "Stukprijs" display_as: "Weergeven als" display_name: "Weergave naam" display_as_placeholder: 'bv. 2.kg' diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 466a006cb5..2e85f80f18 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -114,6 +114,7 @@ pl: models: order_cycle: cloned_order_cycle_name: "Kopia %{order_cycle}" + sku: "SKU" validators: date_time_string_validator: not_string_error: "musi być ciągiem znaków" @@ -259,7 +260,6 @@ pl: error: Błąd processing_payment: "Przetwarzanie płatności ..." no_pending_payments: "Brak oczekujących płatności" - invalid_payment_state: "Nieprawidłowy stan płatności" filter_results: Filtruj wyniki quantity: Ilość pick_up: Odbiór @@ -1126,6 +1126,7 @@ pl: yes_cancel_them: Anuluj je no_keep_them: Zachować je yes_i_am_sure: Tak, jestem pewny + number: "Numer zamówienia" order_update_issues_msg: Niektórych zamówień nie udało się zaktualizować automatycznie, najprawdopodobniej dlatego, że zostały edytowane ręcznie. Zapoznaj się z poniższymi problemami i w razie potrzeby wprowadź ewentualne poprawki do poszczególnych zamówień. no_results: no_subscriptions: Brak subskrypcji ... @@ -1538,7 +1539,9 @@ pl: shopping_tabs_home: "Dom" shopping_tabs_shop: "Sklep" shopping_tabs_about: "O nas" + shopping_tabs_producers: "Producenci" shopping_tabs_contact: "Kontakt" + shopping_tabs_groups: "Grupy" shopping_contact_address: "Adres" shopping_contact_web: "Kontakt" shopping_contact_social: "Obserwuj" @@ -1684,28 +1687,29 @@ pl: shops_signup_help: Jesteśmy gotowi do pomocy. shops_signup_help_text: Potrzebujesz lepszego zwrotu. Potrzebujesz nowych kupujących i partnerów logistycznych. Potrzebujesz swojej historii opowiedzianej w sprzedaży hurtowej, detalicznej i na stole kuchennym. shops_signup_detail: Oto szczegóły. - orders: Zamówienia - orders_fees: Opłaty ... - orders_edit_title: Koszyk - orders_edit_headline: Twój Koszyk - orders_edit_time: Termin odbioru - orders_edit_continue: Kontynuuj zakupy - orders_edit_checkout: Zamów + orders: "Zamówienia" + orders_fees: "Opłaty ..." + orders_edit_title: "Koszyk" + orders_edit_headline: "Twój Koszyk" + orders_edit_time: "Termin odbioru" + orders_edit_continue: "Kontynuuj zakupy" + orders_edit_checkout: "Zamów" orders_form_empty_cart: "Pusty koszyk" - orders_form_subtotal: Podaj sumę częściową - orders_form_admin: Administracja i obsługa - orders_form_total: Razem - orders_oc_expired_headline: Ten cykl zamówień został zamknięty + orders_form_update_cart: "Aktualizuj" + orders_form_subtotal: "Podaj sumę częściową" + orders_form_admin: "Administracja i obsługa" + orders_form_total: "Razem" + orders_oc_expired_headline: "Ten cykl zamówień został zamknięty" orders_oc_expired_text: "Przepraszamy, zamówienia dla tego cyklu zamówień zostały zakończone %{time} temu! Skontaktuj się bezpośrednio z hubem, aby sprawdzić, czy może przyjmować spóźnione zamówienia." orders_oc_expired_text_others_html: "Przepraszamy, zamówienia dla tego cyklu zamówień zostały zakończone %{time} temu! Skontaktuj się bezpośrednio z hubem, aby sprawdzić, czy może przyjąć spóźnione zamówienia %{link} ." orders_oc_expired_text_link: "lub zobacz inne cykle zamówień dostępne w tym hubie" orders_oc_expired_email: "E-mail:" orders_oc_expired_phone: "Telefon:" - orders_show_title: Potwierdzenie zamówienia - orders_show_time: Zamówienie gotowe w dniu + orders_show_title: "Potwierdzenie zamówienia" + orders_show_time: "Zamówienie gotowe w dniu" orders_show_order_number: "Zamówienie nr %{number}" - orders_show_cancelled: Anulowane - orders_show_confirmed: Potwierdzone + orders_show_cancelled: "Anulowane" + orders_show_confirmed: "Potwierdzone" orders_your_order_has_been_cancelled: "Twoje zamówienie zostało anulowane" orders_could_not_cancel: "Przepraszamy, nie można anulować zamówienia" orders_cannot_remove_the_final_item: "Nie można usunąć ostatniej pozycji z zamówienia. Zamiast tego anuluj zamówienie." @@ -1713,9 +1717,9 @@ pl: few: "%{count} dodatkowe pozycje już potwierdzone dla tego cyklu zamówień" many: "%{count} dodatkowe pozycje już potwierdzone dla tego cyklu zamówień" other: "%{count} dodatkowe pozycje już potwierdzone dla tego cyklu zamówień" - orders_bought_edit_button: Edytuj potwierdzone pozycje + orders_bought_edit_button: "Edytuj potwierdzone pozycje" orders_bought_already_confirmed: "* już potwierdzony" - orders_confirm_cancel: Czy na pewno chcesz anulować to zamówienie? + orders_confirm_cancel: "Czy na pewno chcesz anulować to zamówienie?" order_processed_successfully: "Twoje zamówienie zostało pomyślnie przetworzone" products_cart_distributor_choice: "Dystrybutor na Twoje zamówienie:" products_cart_distributor_change: "Twój dystrybutor dla tego zamówienia zostanie zmieniony na %{name}, jeśli dodasz ten produkt do koszyka." @@ -2834,6 +2838,8 @@ pl: tax_category_name: "Kategoria podatku" total_amount: "$$ SUMA" invalid_filter_parameters: "Filtry wybrane dla tego raportu są nieprawidłowe." + report: + none: "Nic" order: "Zamówienie" distribution: "Dystrybucja" order_details: "Szczegóły zamówienia" @@ -2866,7 +2872,11 @@ pl: previous: "Poprzedni" last: "Ostatni" spree: + all: "Wszystko" + category: "Kategoria" more: "Więcej" + no_pending_payments: "Brak oczekujących płatności" + none: "Nic" your_order_is_empty_add_product: "Twoje zamówienie jest puste, wyszukaj i dodaj produkt powyżej" add_product: "Dodaj produkt" name_or_sku: "Nazwa lub SKU (wprowadź co najmniej 4 pierwsze znaki nazwy produktu)" @@ -3031,6 +3041,7 @@ pl: please_define_payment_methods: "Najpierw określ niektóre metody płatności." options: "Opcje" payment_method: "Metoda płatności" + sku: "SKU" actions: update: "Aktualizuj" cancel: "Anuluj" @@ -3051,6 +3062,8 @@ pl: header: store: Sklep admin: + subscriptions: + number: "Numer zamówienia" tab: dashboard: "Kokpit" orders: "Zamówienia" @@ -3195,6 +3208,7 @@ pl: back_to_shipping_methods_list: "Powrót do listy metod dostaw" form: categories: "Kategorie" + tax_category: "Kategoria podatku" zones: "Strefy" both: "Zarówno Checkout, jak i Back office" back_end: "Tylko na zapleczu" @@ -3338,7 +3352,6 @@ pl: price: "Cena" options: "Opcje" no_results: "Brak wyników" - to_add_variants_you_must_first_define: "Aby dodać warianty, musisz najpierw zdefiniować" option_types: "Typy opcji" option_values: "Wartości opcji" and: "i" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 113b70804f..f104683dc3 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -85,6 +85,7 @@ pt: no_default_card: "^Nenhum cartão por defeito para este/a consumidor/a" shipping_method: not_available_to_shop: "não está disponível para %{shop}" + customer_instructions: "Instruções para o consumidor" devise: confirmations: send_instructions: "Daqui a uns minutos irá receber um email com instruções sobre como confirmar a sua conta." @@ -117,6 +118,8 @@ pt: models: order_cycle: cloned_order_cycle_name: "CÓPIA DE%{order_cycle}" + sku: "SKU" + tax_rate: "Taxa de imposto" validators: date_time_string_validator: not_string_error: "deve ser texto" @@ -262,7 +265,6 @@ pt: error: Erro processing_payment: "Pagamento em processamento..." no_pending_payments: "Sem pagamentos pendentes" - invalid_payment_state: "Estado do pagamento inválido" filter_results: Filtrar resultados quantity: Quantidade pick_up: Levantamento @@ -1122,6 +1124,7 @@ pt: yes_cancel_them: Cancelá-las no_keep_them: Mantê-las yes_i_am_sure: Sim, tenho a certeza + number: "Número" order_update_issues_msg: Não foi possível actualizar automaticamente algumas das encomendas, provavelmente porque foram editadas manualmente. Por favor reveja os problemas listados abaixo e faça os ajustes necessários às encomendas individuais. no_results: no_subscriptions: Ainda não existem subscrições.... @@ -1518,7 +1521,9 @@ pt: shopping_tabs_home: "Início" shopping_tabs_shop: "Loja" shopping_tabs_about: "Sobre" + shopping_tabs_producers: "Produtores" shopping_tabs_contact: "Contacto" + shopping_tabs_groups: "Grupos" shopping_contact_address: "Morada" shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" @@ -1547,6 +1552,7 @@ pt: hubs_distance: Mais próximo a hubs_distance_filter: "Mostrar lojas próximas a %{location}" shop_changeable_orders_alert_html: + one: 'A sua encomenda %{shop}/%{order} está actualmente aberta para revisão. Pode fazer alterações até %{oc_close}. ' few: 'Tem %{count}encomendas com %{shop} actualmente abertas para revisão. Pode fazer alterações até %{oc_close}. ' many: 'Tem %{count}encomendas com %{shop} actualmente abertas para revisão. Pode fazer alterações até %{oc_close}. ' other: 'Tem %{count}encomendas com %{shop} actualmente abertas para revisão. Pode fazer alterações até %{oc_close}. ' @@ -1662,28 +1668,29 @@ pt: shops_signup_help: Estamos prontos para ajudar. shops_signup_help_text: Você está a precisar de melhor retorno, de novos clientes e parceiros de logística. Está a precisar que a sua história seja contada em grupos de consumo, em retalho e à mesa de jantar. shops_signup_detail: Aqui está o detalhe. - orders: Encomendas - orders_fees: Taxas... - orders_edit_title: Carrinho de Compras - orders_edit_headline: O seu carrinho de compras - orders_edit_time: Encomenda pronta para - orders_edit_continue: Continuar a comprar - orders_edit_checkout: Finalizar compra + orders: "Encomendas" + orders_fees: "Taxas..." + orders_edit_title: "Carrinho de Compras" + orders_edit_headline: "O seu carrinho de compras" + orders_edit_time: "Encomenda pronta para" + orders_edit_continue: "Continuar a comprar" + orders_edit_checkout: "Finalizar compra" orders_form_empty_cart: "Carrinho vazio" - orders_form_subtotal: Subtotal dos produtos - orders_form_admin: Administração & Logística - orders_form_total: Total - orders_oc_expired_headline: Este ciclo de encomendas está fechado + orders_form_update_cart: "Atualizar" + orders_form_subtotal: "Subtotal dos produtos" + orders_form_admin: "Administração & Logística" + orders_form_total: "Total" + orders_oc_expired_headline: "Este ciclo de encomendas está fechado" orders_oc_expired_text: "Desculpe, este ciclo de encomendas fechou há %{time} atrás. Por favor entre em contacto directamente com a sua central para saber se podem aceitar encomendas tardias." orders_oc_expired_text_others_html: "Desculpe, este ciclo de encomendas fechou há %{time} atrás. Por favor entre em contacto directamente com a sua central para saber se podem aceitar encomendas tardias %{link}." orders_oc_expired_text_link: "ou veja os outros ciclos de encomendas que estão disponíveis nesta central" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Telefone:" - orders_show_title: Confimação de Encomenda - orders_show_time: Encomenda pronta em + orders_show_title: "Confimação de Encomenda" + orders_show_time: "Encomenda pronta em" orders_show_order_number: "Encomenda #%{number}" - orders_show_cancelled: Cancelada - orders_show_confirmed: Confirmada + orders_show_cancelled: "Cancelada" + orders_show_confirmed: "Confirmada" orders_your_order_has_been_cancelled: "A sua encomenda foi cancelada" orders_could_not_cancel: "Pedimos desculpa, a sua encomenda não pode ser cancelada" orders_cannot_remove_the_final_item: "Não é possível remover o item final de uma encomenda, em vez disso, por favor cancele a encomenda." @@ -1691,9 +1698,9 @@ pt: few: "%{count}itens adicionais já confirmados para este ciclo de encomendas " many: "%{count}itens adicionais já confirmados para este ciclo de encomendas " other: "%{count}itens adicionais já confirmados para este ciclo de encomendas " - orders_bought_edit_button: Editar itens confirmados + orders_bought_edit_button: "Editar itens confirmados" orders_bought_already_confirmed: "* já confirmado" - orders_confirm_cancel: Tem a certeza que quer cancelar esta encomenda? + orders_confirm_cancel: "Tem a certeza que quer cancelar esta encomenda?" order_processed_successfully: "A sua encomenda foi processada com sucesso" products_cart_distributor_choice: "Distribuidor para a sua encomenda:" products_cart_distributor_change: "O distribuidor para esta encomenda será alterado para %{name} se adicionar este produto ao carrinho." @@ -2649,6 +2656,9 @@ pt: start_free_profile: "Comece com um perfil gratuito e expanda quando estivere pronto/a!" order_management: reports: + bulk_coop: + filters: + generate_report: "Gerar Relatório" enterprise_fee_summaries: filters: date_range: "Intervalo de Datas" @@ -2694,6 +2704,8 @@ pt: tax_category_name: "Categoria de Imposto" total_amount: "Soma Total" invalid_filter_parameters: "Os filtros que selecionou para este relatório são inválidos." + report: + none: "Nenhum" order: "Encomenda" distribution: "Distribuição" order_details: "Detalhes da Encomenda" @@ -2724,7 +2736,13 @@ pt: previous: "Anterior" last: "Último" spree: + all: "Tudo" + category: "Categoria" + credit: "Crédito" more: "Mais" + no_pending_payments: "Sem pagamentos pendentes" + none: "Nenhum" + updating: "Atualizando" your_order_is_empty_add_product: "A sua encomenda está vazia, por favor procure e adicione um produto em cima" add_product: "Adicionar Produto" name_or_sku: "Nome ou Código (insira pelo menos 4 caracteres)" @@ -2865,6 +2883,7 @@ pt: successfully_updated: '%{resource} foi actualizado/a com sucesso!' payment_method: "Método de Pagamento" payment_processing_failed: "O pagamento não pode ser processado, por favor verifique os detalhes que introduziu" + sku: "SKU" actions: update: "Atualizar" cancel: "Cancelar" @@ -2882,6 +2901,8 @@ pt: header: store: Loja admin: + subscriptions: + number: "Número" tab: dashboard: "Painel de controlo" orders: "Encomendas" @@ -3009,6 +3030,7 @@ pt: back_to_shipping_methods_list: "Voltar à Lista de Categorias de Envio" form: categories: "Categorias" + tax_category: "Categoria de Imposto" zones: "Zonas" both: "Ambos Checkout e Administração" back_end: "Só Administração" @@ -3078,6 +3100,7 @@ pt: value: "Valor" unit_name: "Nome da Unidade" price: "Preço" + unit_price: "Preço Unitário" on_hand: "Disponível" on_demand: "Sob Encomenda" product_description: "Descrição do Produto" @@ -3146,7 +3169,6 @@ pt: price: "Preço" options: "Opções" no_results: "Nenhum resultado" - to_add_variants_you_must_first_define: "Para adicionar variants, primeiro tem de" option_types: "Tipos de Opções" option_values: "Opções de Valor" and: "e" @@ -3158,6 +3180,7 @@ pt: form: sku: "SKU" price: "Preço" + unit_price: "Preço Unitário" display_as: "Mostrar como" display_name: "Nome a apresentar" display_as_placeholder: 'por ex. 2 kg' diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 27c9fb2fed..9dc1243189 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -85,6 +85,7 @@ pt_BR: no_default_card: "^Nenhum cartão padrão disponível para este cliente" shipping_method: not_available_to_shop: "não está disponível para %{shop}" + customer_instructions: "Instruções para o consumidor" devise: confirmations: send_instructions: "Você receberá um e-mail com instruções sobre como confirmar sua conta em alguns minutos." @@ -119,6 +120,8 @@ pt_BR: cloned_order_cycle_name: "COPIA DO %{order_cycle}" tax_rate: included_in_price: "Incluso no preço" + sku: "SKU" + tax_rate: "Alíquota da taxa" validators: date_time_string_validator: not_string_error: "deve ser uma linha" @@ -264,7 +267,6 @@ pt_BR: error: Erro processing_payment: "Processando pagamento..." no_pending_payments: "Nenhum pagamento pendente" - invalid_payment_state: "Situação de pagamento inválido" filter_results: Filtrar resultados quantity: Quantidade pick_up: Retirar @@ -1143,6 +1145,7 @@ pt_BR: yes_cancel_them: Cancele-os no_keep_them: Mantenha-os yes_i_am_sure: Sim eu tenho certeza + number: "Número" order_update_issues_msg: Alguns pedidos não puderam ser atualizados automaticamente; é mais provável que tenham sido editados manualmente. Revise os problemas listados abaixo e faça ajustes nos pedidos individuais, se necessário. no_results: no_subscriptions: Ainda não há assinaturas ... @@ -1175,8 +1178,10 @@ pt_BR: message_html: "Eu concordo com os%{terms_and_conditions_link}do vendedor" link_text: "Termos e Condições" platform_terms_of_service: + message_html: "Eu concordo com os %{tos_link}da plataforma" terms_of_service: "Termos de serviço" all_terms_and_conditions: + message_html: "Eu concordo com os%{terms_and_conditions_link}do vendedor e os%{tos_link}da plataforma" terms_and_conditions: "Termos e Condições" terms_of_service: "Termos de serviço" failed: "O checkout falhou. Informe-nos para que possamos processar seu pedido." @@ -1189,6 +1194,7 @@ pt_BR: mailers: powered_by: open_food_network: "Open Food Brasil" + powered_html: "Esta compra é possibilitada pela %{open_food_network}." menu: cart: cart: "Carrinho" @@ -1555,6 +1561,7 @@ pt_BR: set_a_password: "Você será solicitado a definir uma senha antes de poder administrar a empresa." mistakenly_sent: "Não sabe ao certo por que você recebeu este e-mail? Entre em contato com %{owner_email} para obter mais informações." producer_mail_greeting: "Querido" + producer_mail_text_before: "Veja abaixo uma atualização para o ciclo de pedidos com entregas em:" producer_mail_order_text: "Aqui está um resumo de pedidos para seus produtos:" producer_mail_delivery_instructions: "Instruções para retirada/entrega do estoque:" producer_mail_signoff: "Obrigado e até breve" @@ -1566,7 +1573,9 @@ pt_BR: shopping_tabs_home: "Início" shopping_tabs_shop: "Comprar" shopping_tabs_about: "Sobre" + shopping_tabs_producers: "Produtores" shopping_tabs_contact: "Contato" + shopping_tabs_groups: "Grupos" shopping_contact_address: "Endereço" shopping_contact_web: "Contato" shopping_contact_social: "Seguir" @@ -1718,39 +1727,40 @@ pt_BR: shops_signup_help: Estamos prontos para ajudar shops_signup_help_text: Você precisa de mais retorno, novos compradores e parceiros de logística. Você precisa contar a sua história. shops_signup_detail: Aqui está o detalhe. - orders: Encomendas - orders_fees: Taxas... - orders_edit_title: Carrinho de compras - orders_edit_headline: seu carrinho de compras - orders_edit_time: Pedido pronto para - orders_edit_continue: Continuar comprando - orders_edit_checkout: Fechar pedido + orders: "Encomendas" + orders_fees: "Taxas..." + orders_edit_title: "Carrinho de compras" + orders_edit_headline: "seu carrinho de compras" + orders_edit_time: "Pedido pronto para" + orders_edit_continue: "Continuar comprando" + orders_edit_checkout: "Fechar pedido" orders_form_empty_cart: "Carrinho vazio" - orders_form_subtotal: Subtotal dos produtos - orders_form_admin: Administração e manejo - orders_form_total: Total - orders_oc_expired_headline: Este ciclo de pedidos está fechado para pedidos + orders_form_update_cart: "Atualizar" + orders_form_subtotal: "Subtotal dos produtos" + orders_form_admin: "Administração e manejo" + orders_form_total: "Total" + orders_oc_expired_headline: "Este ciclo de pedidos está fechado para pedidos" orders_oc_expired_text: "Desculpe, este ciclo de pedidos fechou há %{time} atrás. Por favor entre em contato diretamente com sua central para saber se podem aceitar pedidos atrasados." orders_oc_expired_text_others_html: "Desculpe, este ciclo de pedidos fechou há %{time} atrás. Por favor entre em contato diretamente com sua central para saber se podem aceitar pedidos atrasados %{link}." orders_oc_expired_text_link: "ou veja os outros ciclos de pedidos disponíveis nessa central" orders_oc_expired_email: "E-mail:" orders_oc_expired_phone: "Telefone:" - orders_show_title: Confimação de Pedido - orders_show_time: Pedido pronto em + orders_show_title: "Confimação de Pedido" + orders_show_time: "Pedido pronto em" orders_show_order_number: "Pedido #" - orders_show_cancelled: Cancelado - orders_show_confirmed: Confirmado + orders_show_cancelled: "Cancelado" + orders_show_confirmed: "Confirmado" orders_your_order_has_been_cancelled: "Seu pedido foi cancelado" orders_could_not_cancel: "Desculpa, seu pedido não pode ser cancelado" orders_cannot_remove_the_final_item: "Não é possível remover o item final de um pedido, ao invés disso, por favor cancele o pedido" orders_bought_items_notice: - one: 'Um item adicional já está confirmado para este ciclo de pedidos. ' + one: "Um item adicional já está confirmado para este ciclo de pedidos. " few: "%{count} itens adicionais já confirmados para este ciclo de pedidos" many: "%{count} itens adicionais já confirmados para este ciclo de pedidos" other: "%{count} itens adicionais já confirmados para este ciclo de pedidos" - orders_bought_edit_button: Editar itens confirmados + orders_bought_edit_button: "Editar itens confirmados" orders_bought_already_confirmed: "* já confirmado" - orders_confirm_cancel: Tem certeza de que deseja cancelar este pedido? + orders_confirm_cancel: "Tem certeza de que deseja cancelar este pedido?" order_processed_successfully: "Seu pedido foi processado com sucesso" products_cart_distributor_choice: "Distribuidor para seu pedido:" products_cart_distributor_change: "O distribuidor para este pedido será trocado para %{name} se você adicionar este produto no carrinho." @@ -2377,6 +2387,7 @@ pt_BR: back_to_orders_list: "Voltar à lista de pedidos" no_orders_found: "Nenhum pedido encontrado" order_information: "Informações sobre pedidos" + new_payment: "Novo Pagamento" date_completed: "Data de conclusão" amount: "Montante" state_names: @@ -2805,6 +2816,9 @@ pt_BR: start_free_profile: "Comece com um perfil gratuito e expanda quando estiver pronto!" order_management: reports: + bulk_coop: + filters: + generate_report: "Gerar Relatório" enterprise_fee_summaries: filters: date_range: "Período" @@ -2850,6 +2864,8 @@ pt_BR: tax_category_name: "Categoria de taxa" total_amount: "$$ SUM" invalid_filter_parameters: "Os filtros que você selecionou para este relatório são inválidos." + report: + none: "Nenhum" order: "Pedido" distribution: "Distribuição" order_details: "detalhes do pedido" @@ -2882,12 +2898,19 @@ pt_BR: previous: "Anterior" last: "Último" spree: + all: "Todos" + category: "Categoria" + credit: "Crédito" more: "Mais" + no_pending_payments: "Nenhum pagamento pendente" + none: "Nenhum" + updating: "Atualizando" your_order_is_empty_add_product: "Seu pedido está vazio, pesquise e adicione um produto acima" add_product: "Adicionar produto" name_or_sku: "Nome ou SKU (digite pelo menos os 4 primeiros caracteres do nome do produto)" resend: "Re-enviar" back_to_orders_list: "Voltar à lista de pedidos" + back_to_payments_list: "Voltar pra Lista de Pagamentos" return_authorizations: "Autorizações de Devolução" cannot_create_returns: "Não é possível criar devoluções, pois esse pedido não possui unidades enviadas." select_stock: "Selecionar estoque" @@ -3059,6 +3082,7 @@ pt_BR: payment_method: "Método de Pagamento" payment_processing_failed: "O pagamento não pôde ser processado, favor verificar os dados informados. " not_available: "N/A" + sku: "SKU" order_populator: out_of_stock: '%{item}fora de estoque. ' actions: @@ -3087,6 +3111,8 @@ pt_BR: header: store: Loja admin: + subscriptions: + number: "Número" tab: dashboard: "Painel" orders: "Encomendas" @@ -3235,6 +3261,7 @@ pt_BR: back_to_shipping_methods_list: "Voltar à lista de métodos de envio" form: categories: "Categorias" + tax_category: "Categoria de taxa" zones: "Zonas" both: "Tanto Checkout quanto Área Administrativa" back_end: "Somente Área Administrativa" @@ -3315,6 +3342,7 @@ pt_BR: value: "Quantidade" unit_name: "Nome da Unidade" price: "Preço" + unit_price: "Preço Unitário" on_hand: "Disponível" on_demand: "Sob Encomenda" product_description: "Descrição do Produto" @@ -3385,7 +3413,6 @@ pt_BR: price: "Preço" options: "Opções" no_results: "Nenhum Resultado" - to_add_variants_you_must_first_define: "Para adicionar variantes, primeiro você precisa definir" option_types: "Tipos de Opções" option_values: "Valores das Opções" and: "e" @@ -3397,6 +3424,7 @@ pt_BR: form: sku: "SKU" price: "Preço" + unit_price: "Preço Unitário" display_as: "Mostrar Como" display_name: "Mostrar Nome" display_as_placeholder: 'ex. 2 kg' @@ -3420,6 +3448,7 @@ pt_BR: cookies_consent_banner_toggle: "Mostrar banner sobre permissão para cookies" privacy_policy_url: " Política de Privacidade URL" enterprises_require_tos: "As iniciativas devem aceitar os Termos de Serviço" + shoppers_require_tos: "Compradores precisam aceitar Termos de Serviço" cookies_policy_matomo_section: "Exibir a seção Matomo nos cookies da página de política" footer_tos_url: "URL Termos de Serviço" checkout: @@ -3457,6 +3486,7 @@ pt_BR: pending: pendente ready: pronto shipped: enviado + canceled: cancelado payment_states: balance_due: saldo devedor completed: completado @@ -3578,6 +3608,8 @@ pt_BR: past_orders: Pedidos passados transactions: transaction_history: Histórico de transações + authorisation_required: Requer Autorização + authorise: Autorizar open_orders: order: Pedido shop: Loja diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 3e40f0f7b2..2019a6f96b 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -85,6 +85,11 @@ ru: no_default_card: "^У этого клиента нет карты по умолчанию" shipping_method: not_available_to_shop: "недоступно для %{shop}" + card_details: "Реквизиты карты" + card_type: "Тип карты" + cardholder_name: "Имя владельца карты" + community_forum_url: "URL форума сообщества" + customer_instructions: "Инструкции для Клиента" devise: confirmations: send_instructions: "В течение нескольких минут Вы получите электронное письмо с инструкциями о том, как подтвердить свой аккаунт." @@ -115,11 +120,39 @@ ru: updated_not_active: "Ваш пароль был сброшен, но ваш адрес электронной почты еще не подтвержден." updated: "Ваш пароль был успешно изменен. Вы вошли в систему." send_instructions: "Вы получите электронное письмо с инструкциями о том, как подтвердить свою учетную запись в течение нескольких минут." + home_page_alert_html: "HTML оповещения на главной странице" + hub_signup_case_studies_html: "Примеры использования подписки на хаб HTML" + hub_signup_detail_html: "Подробности о регистрации в хабе HTML" + hub_signup_pricing_table_html: "Таблица цен на подписку в хабе HTML" + group_signup_case_studies_html: "Примеры использования групповой регистрации HTML" + group_signup_detail_html: "Подробности о регистрации в группе HTML" + group_signup_pricing_table_html: "Таблица расценок для групповой подписки HTML" + item_description: "Описание товара" + menu_1_icon_name: "Имя значка меню 1" + menu_2_icon_name: "Имя значка меню 2" + menu_3_icon_name: "Имя значка меню 3" + menu_4_icon_name: "Имя значка меню 4" + menu_5_icon_name: "Имя значка меню 5" + menu_6_icon_name: "Имя значка меню 6" + menu_7_icon_name: "Имя значка меню 7" models: order_cycle: cloned_order_cycle_name: "КОПИЯ %{order_cycle}" tax_rate: included_in_price: "Включено в цену" + open_street_map_enabled: "Open Street Map включена" + open_street_map_default_latitude: "Широта по умолчанию в Open Street Map" + open_street_map_default_longitude: "Долгота по умолчанию в Open Street Map" + open_street_map_provider_name: "Имя провайдера Open Street Map" + open_street_map_provider_options: "Параметры провайдера Open Street Map" + producer_signup_case_studies_html: "Примеры использования регистрации производителя HTML" + producer_signup_detail_html: "Подробности о регистрации производителя HTML" + producer_signup_pricing_table_html: "Таблица цен на подписку производителя HTML" + producers_social: "Соцсети производителей" + resume_order: "Возобновить заказ" + sku: "SKU" + subtotal: "Промежуточный итог" + tax_rate: "Налоговая ставка" validators: date_time_string_validator: not_string_error: "должно быть строкой" @@ -145,6 +178,7 @@ ru: producer_mailer: order_cycle: subject: "Отчет по Циклу Заказа для %{producer}" + provider_settings: "Настройки провайдера" shipment_mailer: shipped_email: dear_customer: "Уважаемый Клиент," @@ -265,7 +299,7 @@ ru: error: Ошибка processing_payment: "Обработка платежа..." no_pending_payments: "Нет ожидающих платежей" - invalid_payment_state: "Неверный статус платежа" + invalid_payment_state: "Неверное состояние платежа: %{state}" filter_results: Результаты фильтрации quantity: Количество pick_up: Самовывоз @@ -299,8 +333,12 @@ ru: destroy: "Уничтожить" rename: "Переименовать" admin: + adjustments: + skipped_changing_canceled_order: "Вы не можете изменить отмененный заказ." begins_at: Начинается С begins_on: Начинается На + bill_address: "Адрес счета" + ship_address: "Адрес доставки" customer: Клиент date: Дата email: Электронная почта @@ -1066,6 +1104,7 @@ ru: index: title: "Подписки" new: "Новая Подписка" + issue: "Проблема" new: title: "Новая Подписка" edit: @@ -1148,6 +1187,7 @@ ru: yes_cancel_them: Отменить их no_keep_them: Оставить их yes_i_am_sure: Да, уверен + number: "Номер" order_update_issues_msg: Некоторые заказы не могут быть автоматически обновлены, скорее всего, потому что они были отредактированы вручную. Пожалуйста, просмотрите перечисленные ниже проблемы и при необходимости внесите коррективы в индивидуальные заказы. no_results: no_subscriptions: Еще нет подписок... @@ -1180,8 +1220,10 @@ ru: message_html: "Согласен на %{terms_and_conditions_link} продавца." link_text: "Условия и Положения" platform_terms_of_service: + message_html: "Я согласен c условиями платформы %{tos_link}." terms_of_service: "Условия Сервиса" all_terms_and_conditions: + message_html: "Я согласен с условиями %{terms_and_conditions_link} продавца и платформы %{tos_link}." terms_and_conditions: "Условия и Положения" terms_of_service: "Условия Сервиса" failed: "Оформить заказ не удалось. Сообщите нам, чтобы мы могли обработать ваш заказ." @@ -1573,7 +1615,9 @@ ru: shopping_tabs_home: "Главная" shopping_tabs_shop: "Магазин" shopping_tabs_about: "О Нас" + shopping_tabs_producers: "Производители" shopping_tabs_contact: "Контакты" + shopping_tabs_groups: "Группы" shopping_contact_address: "Адрес" shopping_contact_web: "Контакты" shopping_contact_social: "Следовать" @@ -1725,39 +1769,40 @@ ru: shops_signup_help: Мы готовы помочь. shops_signup_help_text: Вам необходима лучшая отдача. Вам нужны новые покупатели и логистические партнеры. Вы должны рассказать свою историю через оптовые и розничные продажи, а также за столом. shops_signup_detail: Подробности. - orders: Заказы - orders_fees: Сборы... - orders_edit_title: Корзина - orders_edit_headline: Ваша корзина - orders_edit_time: Заказ доступен с - orders_edit_continue: Продолжить покупки - orders_edit_checkout: Оформить + orders: "Заказы" + orders_fees: "Сборы..." + orders_edit_title: "Корзина" + orders_edit_headline: "Ваша корзина" + orders_edit_time: "Заказ доступен с" + orders_edit_continue: "Продолжить покупки" + orders_edit_checkout: "Оформить" orders_form_empty_cart: "Очистить корзину" - orders_form_subtotal: Итого - orders_form_admin: Администрирование и Управление - orders_form_total: Всего - orders_oc_expired_headline: Оформление Заказов для этого Цикла Заказа закрыто + orders_form_update_cart: "Обновить" + orders_form_subtotal: "Итого" + orders_form_admin: "Администрирование и Управление" + orders_form_total: "Всего" + orders_oc_expired_headline: "Оформление Заказов для этого Цикла Заказа закрыто" orders_oc_expired_text: "Извините, оформление заказов для этого цикла заказов закрыты %{time} назад! Пожалуйста, свяжитесь с вашим центром напрямую, чтобы узнать, могут ли они принимать поздние заказы." orders_oc_expired_text_others_html: "Извините, оформление заказов для этого цикла заказов закрыты %{time} назад! Пожалуйста, свяжитесь с вашим центром напрямую, чтобы узнать, могут ли они принимать поздние заказы %{link}." orders_oc_expired_text_link: "или посмотрите другие циклы заказа, доступные в этом Центре" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Телефон:" - orders_show_title: Подтверждение заказа - orders_show_time: Заказ готов с + orders_show_title: "Подтверждение заказа" + orders_show_time: "Заказ готов с" orders_show_order_number: "Заказ #%{number}" - orders_show_cancelled: Отменён - orders_show_confirmed: Подтверждён + orders_show_cancelled: "Отменён" + orders_show_confirmed: "Подтверждён" orders_your_order_has_been_cancelled: "Ваш заказ был отменен" orders_could_not_cancel: "Извините, заказ не может быть отменен" orders_cannot_remove_the_final_item: "Не удается удалить последний элемент из заказа, вместо этого отмените заказ." orders_bought_items_notice: - one: Дополнительная позиция уже подтверждена для этого цикла заказа + one: "Дополнительная позиция уже подтверждена для этого цикла заказа" few: "%{count} дополнительных позиций уже подтверждено для этого цикла заказа" many: "%{count} дополнительных позиций уже подтверждено для этого цикла заказа" other: "%{count} дополнительных позиций уже подтверждено для этого цикла заказа" - orders_bought_edit_button: Редактировать подтвержденные позиции + orders_bought_edit_button: "Редактировать подтвержденные позиции" orders_bought_already_confirmed: "* уже подтверждено" - orders_confirm_cancel: Вы уверены, что хотите отменить этот заказ? + orders_confirm_cancel: "Вы уверены, что хотите отменить этот заказ?" order_processed_successfully: "Ваш заказ был успешно обработан" products_cart_distributor_choice: "Дистрибьютор для Вашего заказа:" products_cart_distributor_change: "Ваш дистрибьютор для этого заказа изменится на %{name}, если Вы добавите этот продукт в Вашу корзину." @@ -2416,6 +2461,7 @@ ru: При добавлении этого товара в корзину возникла проблема. Возможно, он стал недоступен или магазин закрывается. admin: + unit_price_tooltip: "Цена за единицу увеличивает прозрачность, позволяя вашим клиентам легко сравнивать цены на разные продукты и размеры упаковки. Обратите внимание, что окончательная цена за единицу, отображаемая на витрине, может отличаться, поскольку она включает налоги и сборы." enterprise_limit_reached: "Вы достигли стандартного лимита количества предприятий на один аккаунт. Напишите на %{contact_email}, если Вам нужно увеличить его." modals: got_it: "Понятно" @@ -2862,6 +2908,15 @@ ru: start_free_profile: "Начните с бесплатного профиля и расширяйтесь, когда будете готовы!" order_management: reports: + bulk_coop: + filters: + bulk_coop_allocation: "Массовое распределение кооперативов" + bulk_coop_customer_payments: "Массовые Платежи Клиентов Кооперативов" + bulk_coop_packing_sheets: "Упаковочные листы для массовых кооперативов" + bulk_coop_supplier_report: "Отчет о массовых кооперативных поставках" + date_range: "Диапазон дат" + generate_report: "Создать отчет" + report_format_csv: "Формат отчета CSV" enterprise_fee_summaries: filters: date_range: "Диапозон даты" @@ -2907,6 +2962,8 @@ ru: tax_category_name: "Налоговая Категория" total_amount: "$$ СУММА" invalid_filter_parameters: "Фильтры, выбранные для этого отчета, недействительны." + report: + none: "Нет" order: "Заказ" distribution: "Дистрибьюция" order_details: "Информация по Заказу" @@ -2939,7 +2996,54 @@ ru: previous: "Предыдущий" last: "Последний" spree: + add_country: "Добавить страну" + add_state: "Добавить область" + adjustment: "Корректирование" + all: "Все" + associated_adjustment_closed: "Связанная корректировка закрыта" + authorization_failure: "Ошибка авторизации" + back_to_adjustments_list: "Вернуться к корректировкам" + back_to_users_list: "Вернуться к пользователям" + back_to_zones_list: "Вернуться в зоны" + card_code: "Код карты" + card_number: "Номер карты" + category: "Категория" + created_successfully: "Создано успешно" + credit: "Кредит" + editing_tax_category: "Редактирование налоговой категории" + editing_tax_rate: "Редактирование налоговой ставки" + editing_zone: "Редактирование зоны" + expiration: "Срок действия" + invalid_payment_provider: "Неверный провайдер платежа" + items_cannot_be_shipped: "Товары не могут быть отправлены" + gateway_config_unavailable: "Конфигурация шлюза недоступна" + gateway_error: "Платеж не прошел" more: "Ещё" + new_adjustment: "Новая корректировка" + new_order_completed: "Новый заказ выполнен" + new_tax_category: "Новая Налоговая Категория" + new_taxon: "Новая таксономия" + new_user: "Новый пользователь" + no_pending_payments: "Нет ожидающих платежей" + none: "Нет" + not_found: "Не найден" + notice_messages: + variant_deleted: "Вариант удален" + or: "Или" + order_processed_successfully: "Заказ успешно обработан" + payment_method_not_supported: "Способ оплаты не поддерживается" + resend_authorization_email: "Повторно отправить письмо для авторизации" + rma_credit: "Кредит RMA" + server_error: "Ошибка сервера" + shipping_method_names: + UPS Ground: "UPS Ground" + start_date: "Дата начала" + successfully_removed: "Успешно удалено" + taxonomy_edit: "Изменить таксономию" + taxonomy_tree_error: "Ошибка дерева таксономии" + taxonomy_tree_instruction: "Инструкция по дереву таксономии" + tree: "Дерево" + updating: "Обновление" your_order_is_empty_add_product: "Ваша корзина пуста, пожалуйста, найдите и добавьте товар выше" add_product: "Добавить Товар" name_or_sku: "Название или SKU (введите как минимум первые 4 символа названия товара)" @@ -2967,6 +3071,7 @@ ru: tracking_number: "Номер Отслеживания" order_total: "Итоговый Заказ" customer_details: "Информация о Клиенте" + customer_details_updated: "Информация о Клиенте обновлена" customer_search: "Поиск Клиента" choose_a_customer: "Выбрать клиента" account: "Профиль" @@ -3117,6 +3222,8 @@ ru: payment_method: "Способ Оплаты" payment_processing_failed: "Платеж не может быть обработан, пожалуйста, проверьте введенные данные" not_available: "Нет данных" + sku: "SKU" + there_are_no_items_for_this_order: "В этом заказе нет товаров." order_populator: out_of_stock: '%{item} отсутствует в наличии.' actions: @@ -3144,7 +3251,17 @@ ru: login_nav: header: store: Магазин + validation: + must_be_int: "должно быть целым числом" admin: + mail_methods: + send_testmail: "Отправить тестовое письмо" + testmail: + delivery_success: "Тестовое письмо отправлено." + error: "Произошла ошибка при отправке тестового письма." + unit_price_tooltip: "Цена за единицу увеличивает прозрачность, позволяя вашим клиентам легко сравнивать цены на разные продукты и размеры упаковки. Обратите внимание, что окончательная цена за единицу, отображаемая на витрине, может отличаться, поскольку она включает налоги и сборы." + subscriptions: + number: "Номер" tab: dashboard: "Панель" orders: "Заказы" @@ -3213,6 +3330,8 @@ ru: received: "Получен" canceled: "Отменен" orders: + add_product: + cannot_add_item_to_canceled_order: "Невозможно добавить товар в отмененный заказ" index: listing_orders: "Список Заказов" new_order: "Новый Заказ" @@ -3255,6 +3374,10 @@ ru: overview: enterprises_header: ofn_with_tip: Предприятия являются Производителями и/или Центрами и являются основной единицей организации в рамках Открытой Сети Продуктов. + enterprise_row: + has_no_enterprise_fees: "нет корпоративных сборов" + has_no_payment_methods: "нет способов оплаты" + has_no_shipping_methods: "нет способов доставки" products: active_products: zero: "У Вас нет активных товаров." @@ -3293,6 +3416,7 @@ ru: back_to_shipping_methods_list: "Назад К Списку Способов Доставки" form: categories: "Категории" + tax_category: "Налоговая Категория" zones: "Зоны" both: "Оба" back_end: "Интерфейс Администратора" @@ -3373,6 +3497,8 @@ ru: value: "Значение" unit_name: "Название единицы" price: "Цена" + unit_price: "Цена за единицу" + unit_price_legend: "Рассчитывается исходя из стоимости товара" on_hand: "В наличии" on_demand: "По Запросу" product_description: "Описание Товара" @@ -3443,7 +3569,6 @@ ru: price: "Цена" options: "Опции" no_results: "Нет результатов" - to_add_variants_you_must_first_define: "Чтобы добавить варианты, вы должны сначала определить" option_types: "Типы опций" option_values: "Значения опций" and: "и" @@ -3455,6 +3580,7 @@ ru: form: sku: "SKU" price: "Цена" + unit_price: "Цена за единицу" display_as: "Показать как" display_name: "Показать имя" display_as_placeholder: 'напр. 2 кг' @@ -3478,6 +3604,7 @@ ru: cookies_consent_banner_toggle: "Показывать баннер на согласие использования файлов cookie" privacy_policy_url: "URL политики конфиденциальности" enterprises_require_tos: "Предприятия должны принять Условия сервиса" + shoppers_require_tos: "Покупатели должны принять Условия Сервиса." cookies_policy_matomo_section: "Показать раздел Matomo на странице политики использования файлов cookie" footer_tos_url: "URL Условий сервиса" checkout: @@ -3693,3 +3820,66 @@ ru: few: Платежи many: Платежи other: Платежи + datetime: + distance_in_words: + about_x_hours: + one: около 1 часа + few: около %{count} часов + many: около %{count} часов + other: около %{count} часов + about_x_months: + one: около 1 месяца + few: около %{count} месяцев + many: около %{count} месяцев + other: около %{count} месяцев + about_x_years: + one: около 1 года + few: около %{count} лет + many: около %{count} лет + other: около %{count} лет + almost_x_years: + one: почти 1 год + few: почти %{count} лет + many: почти %{count} лет + other: почти %{count} лет + half_a_minute: полминуты + less_than_x_seconds: + one: менее 1 секунды + few: менее %{count} секунд + many: менее %{count} секунд + other: менее %{count} секунд + less_than_x_minutes: + one: меньше минуты + few: менее %{count} минут + many: менее %{count} минут + other: менее %{count} минут + over_x_years: + one: более 1 года + few: более %{count} лет + many: более %{count} лет + other: более %{count} лет + x_seconds: + one: "1 секунда" + few: "%{count} секунд" + many: "%{count} секунд" + other: "%{count} секунд" + x_minutes: + one: "1 минута" + few: "%{count} минут" + many: "%{count} минут" + other: "%{count} минут" + x_days: + one: "1 день" + few: "%{count} дней" + many: "%{count} дней" + other: "%{count} дней" + x_months: + one: "1 месяц" + few: "%{count} месяцев" + many: "%{count} месяцев" + other: "%{count} месяцев" + x_years: + one: "1 год" + few: "%{count} лет" + many: "%{count} лет" + other: "%{count} лет" diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 3f51bb341e..9ca0c49994 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -29,11 +29,14 @@ sv: order_cycle_ids: "Beställningsomgångar" shipping_method_ids: "Transportsätt" payment_method_ids: "Betalningssätt" + customer_instructions: "Kundinstruktioner" devise: failure: invalid: | Ogiltig e-post eller lösenord. Var du gäst senast? Du behöver kanske skapa ett konto eller återställa ditt lösenord. + sku: "SKU" + tax_rate: "Skattesats" enterprise_mailer: confirmation_instructions: subject: "Vänligen bekräfta e-postadressen för %{enterprise}" @@ -897,7 +900,9 @@ sv: shopping_tabs_home: "Hem" shopping_tabs_shop: "Butik " shopping_tabs_about: "Om oss" + shopping_tabs_producers: "Producenter " shopping_tabs_contact: "Kontakt" + shopping_tabs_groups: "Grupper" shopping_contact_address: "Adress" shopping_contact_web: "Kontakt" shopping_contact_social: "Följ" @@ -1036,27 +1041,28 @@ sv: shops_signup_help: Vi är redo att hjälpa. shops_signup_help_text: Du behöver bättre vinst. Du behöver nya kunder och logistikpartner. Din historia behöver bli känd bland grossister, detaljhandlare och vid köksbordet. shops_signup_detail: Här är haken. - orders_fees: Avgifter... - orders_edit_title: Varukorg - orders_edit_headline: Din varukorg - orders_edit_time: Beställning redo för - orders_edit_continue: Fortsätt handla - orders_edit_checkout: Utcheckning + orders_fees: "Avgifter..." + orders_edit_title: "Varukorg" + orders_edit_headline: "Din varukorg" + orders_edit_time: "Beställning redo för" + orders_edit_continue: "Fortsätt handla" + orders_edit_checkout: "Utcheckning" orders_form_empty_cart: "Tom varukorg" - orders_form_subtotal: Framställ delsumma - orders_form_admin: Administration och hantering - orders_form_total: 'Summa ' - orders_oc_expired_headline: Denna orderomgång är stängd för nya order + orders_form_update_cart: "Uppdatera" + orders_form_subtotal: "Framställ delsumma" + orders_form_admin: "Administration och hantering" + orders_form_total: "Summa " + orders_oc_expired_headline: "Denna orderomgång är stängd för nya order" orders_oc_expired_text: "Tyvärr, order för denna orderomgång stängde för %{time} sedan! Var vänlig kontakta ditt matcenter för att se om de kan ta emot en sen order. " orders_oc_expired_text_others_html: "Tyvärr, order för denna orderomgång stängde för %{time} sedan! Var vänlig kontakta ditt matcenter för att se om de kan ta emot en sen order %{link}." orders_oc_expired_text_link: "eller se de andra beställningstiderna för detta matställe" orders_oc_expired_email: "E-post:" orders_oc_expired_phone: "Telefon:" - orders_show_title: Orderbekräftelse - orders_show_time: Order redo den + orders_show_title: "Orderbekräftelse" + orders_show_time: "Order redo den" orders_show_order_number: "Beställning # %{number}" - orders_show_cancelled: Avbokad - orders_show_confirmed: Bekräftad + orders_show_cancelled: "Avbokad" + orders_show_confirmed: "Bekräftad" orders_your_order_has_been_cancelled: "Din beställning har avbrutits" orders_could_not_cancel: "Tyvärr kan denna beställning inte avbrytas" orders_cannot_remove_the_final_item: "Det går inte att ta bort det sista varan från en beställning, var god och avbryt beställningen istället." @@ -1064,9 +1070,9 @@ sv: few: "%{count} ytterligare artiklar är redan bekräftade för denna beställningsomgång" many: "%{count} ytterligare artiklar är redan bekräftade för denna beställningsomgång" other: "%{count} ytterligare artiklar är redan bekräftade för denna beställningsomgång" - orders_bought_edit_button: Redigera bekräftade varor + orders_bought_edit_button: "Redigera bekräftade varor" orders_bought_already_confirmed: "* redan bekräftad" - orders_confirm_cancel: Är du säker på att du vill avbryta denna beställning? + orders_confirm_cancel: "Är du säker på att du vill avbryta denna beställning?" products_cart_distributor_choice: "Distributör för din order:" products_cart_distributor_change: "Din distributör för denna order kommer att ändras till %{name} om du lägger denna produkt i din kundkorg." products_cart_distributor_is: "Din distributör för denna order är %{name}." @@ -1899,6 +1905,8 @@ sv: fee_type: "Avgiftstyp" customer_name: "Kund" tax_category_name: "Skattekategori" + report: + none: "Ingen" order: "Beställningar" distribution: "Distribution" payment: "Betalning " @@ -1909,6 +1917,11 @@ sv: account: "Konto" logout: "Logga ut" spree: + all: "Alla" + category: "Kategori" + credit: "Kredit" + none: "Ingen" + updating: "Uppdaterar" resend: "Återsänd" quantity: "Antal" on_demand: "På begäran" @@ -1946,6 +1959,7 @@ sv: inventory: Lager zipcode: Postkod payment_method: "Betalningsmetod" + sku: "SKU" actions: update: "Uppdatera" cancel: "Avbryt" @@ -2031,6 +2045,8 @@ sv: name: "Namn" products_distributor: "Distributör" calculator: "Beräkning" + form: + tax_category: "Skattekategori" payment_methods: index: payment_methods: "Betalningssätt" @@ -2050,6 +2066,7 @@ sv: units: "Enhetsstorlek" value: "Värde" price: "Pris" + unit_price: "Styckpris" on_hand: "På lager" on_demand: "På begäran" or: "eller" @@ -2093,6 +2110,7 @@ sv: form: sku: "SKU" price: "Pris" + unit_price: "Styckpris" display_as: "Visa som" autocomplete: producer_name: "Producent" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 92505030a2..0357a8bbf8 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -85,6 +85,7 @@ tr: no_default_card: "^ Bu müşteri için kayıtlı kart bulunmuyor" shipping_method: not_available_to_shop: "%{shop} için müsait değil" + customer_instructions: "Müşteri talimatları" devise: confirmations: send_instructions: "Birkaç dakika içinde, hesabınızı nasıl doğrulayacağınız ile ilgili talimatları içeren bir e-posta alacaksınız." @@ -117,6 +118,8 @@ tr: models: order_cycle: cloned_order_cycle_name: "%{order_cycle} KOPYALA" + sku: "Stok Kodu" + tax_rate: "Vergi oranı" validators: date_time_string_validator: not_string_error: "Dizili olmalı" @@ -262,7 +265,6 @@ tr: error: Hata processing_payment: "Ödeme İşlemi Gerçekleştiriliyor.." no_pending_payments: "Bekleyen ödeme yok" - invalid_payment_state: "Geçersiz ödeme durumu" filter_results: SONUÇLARI FİLTRELE quantity: Miktar pick_up: Teslim Alma @@ -1143,6 +1145,7 @@ tr: yes_cancel_them: Bunları iptal et no_keep_them: Bunları sakla yes_i_am_sure: Evet eminim + number: "Numara" order_update_issues_msg: Bazı siparişler otomatik olarak güncellenemedi, bunun nedeni büyük olasılıkla manuel olarak düzenlenmiş olmasıdır. Lütfen aşağıda listelenen sorunları gözden geçirin ve gerekirse siparişler özelinde ayarlamalarını yapın. no_results: no_subscriptions: Henüz üyelik yok ... @@ -1566,7 +1569,9 @@ tr: shopping_tabs_home: "Ana sayfa" shopping_tabs_shop: "ALIŞVERİŞ YAP" shopping_tabs_about: "Hakkında" + shopping_tabs_producers: "ÜRETİCİLER" shopping_tabs_contact: "İLETİŞİM" + shopping_tabs_groups: "AĞLAR" shopping_contact_address: "Adres" shopping_contact_web: "İLETİŞİM" shopping_contact_social: "TAKİP ET" @@ -1718,39 +1723,40 @@ tr: shops_signup_help: Yardım etmeye hazırız. shops_signup_help_text: Daha yüksek bir iş potansiyeliniz var. Yeni alıcılarla ve ortak hareket edebileceğiniz diğer üretici ve gruplarla iletişime geçin. Birlikte daha güçlüyüz. Hikayeniz, bir ailenin sofrasında anlatılmayı bekliyor. shops_signup_detail: İşte detay. - orders: Siparişler - orders_fees: Ücretler ... - orders_edit_title: Alışveriş Sepeti - orders_edit_headline: Alışveriş sepetiniz - orders_edit_time: Sipariş Teslimat - orders_edit_continue: Alışverişe devam - orders_edit_checkout: Ödeme Yap + orders: "Siparişler" + orders_fees: "Ücretler ..." + orders_edit_title: "Alışveriş Sepeti" + orders_edit_headline: "Alışveriş sepetiniz" + orders_edit_time: "Sipariş Teslimat" + orders_edit_continue: "Alışverişe devam" + orders_edit_checkout: "Ödeme Yap" orders_form_empty_cart: "Sepeti Boşalt" - orders_form_subtotal: Ürün Ara Toplamı - orders_form_admin: Yönetim & Operasyon - orders_form_total: Toplam - orders_oc_expired_headline: Bu sipariş dönemi için siparişler kapatıldı + orders_form_update_cart: "Güncelle" + orders_form_subtotal: "Ürün Ara Toplamı" + orders_form_admin: "Yönetim & Operasyon" + orders_form_total: "Toplam" + orders_oc_expired_headline: "Bu sipariş dönemi için siparişler kapatıldı" orders_oc_expired_text: "Üzgünüz, bu sipariş dönemi siparişleri %{time} önce kapandı! Geç siparişleri kabul edip edemeyeceklerini görmek için lütfen doğrudan pazarınızla iletişime geçin." orders_oc_expired_text_others_html: "Üzgünüz, bu sipariş dönemi siparişleri %{time} önce kapandı! Geç siparişleri kabul edip edemeyeceklerini görmek için lütfen doğrudan pazarınızla iletişime geçin%{link} ." orders_oc_expired_text_link: "veya bu pazarın diğer sipariş dönemlerine bakın" orders_oc_expired_email: "E-posta:" orders_oc_expired_phone: "Telefon:" - orders_show_title: Sipariş Onayı - orders_show_time: Sipariş hazır + orders_show_title: "Sipariş Onayı" + orders_show_time: "Sipariş hazır" orders_show_order_number: "Sipariş # %{number}" - orders_show_cancelled: İptal edildi - orders_show_confirmed: Onaylandı + orders_show_cancelled: "İptal edildi" + orders_show_confirmed: "Onaylandı" orders_your_order_has_been_cancelled: "Siparişiniz iptal edildi" orders_could_not_cancel: "Maalesef sipariş iptal edilemedi" orders_cannot_remove_the_final_item: "Son ürün siparişten kaldırılamaz, lütfen bunun yerine siparişi iptal edin." orders_bought_items_notice: - one: Bu sipariş döngüsü için ek bir ürün zaten onaylandı. + one: "Bu sipariş döngüsü için ek bir ürün zaten onaylandı." few: "%{count} ürün bu sipariş dönemi için onaylandı bile" many: "%{count} ürün bu sipariş dönemi için onaylandı bile" other: "%{count} ürün bu sipariş dönemi için onaylandı bile" - orders_bought_edit_button: Onaylanan ürünleri düzenle + orders_bought_edit_button: "Onaylanan ürünleri düzenle" orders_bought_already_confirmed: "* zaten onaylandı" - orders_confirm_cancel: Bu siparişi iptal etmek istediğinize emin misiniz? + orders_confirm_cancel: "Bu siparişi iptal etmek istediğinize emin misiniz?" order_processed_successfully: "Siparişiniz başarıyla işlendi" products_cart_distributor_choice: "Siparişinizin dağıtımcısı:" products_cart_distributor_change: "Bu ürünü sepetinize eklerseniz, bu sipariş için dağıtımcınız %{name} olarak değiştirilecektir." @@ -2797,6 +2803,9 @@ tr: start_free_profile: "Ücretsiz bir profille başlayın ve hazır olduğunuzda devam edin!" order_management: reports: + bulk_coop: + filters: + generate_report: "Rapor Oluştur" enterprise_fee_summaries: filters: date_range: "Tarih Aralığı" @@ -2842,6 +2851,8 @@ tr: tax_category_name: "Vergi Kategorisi" total_amount: "₺₺ TOPLAM" invalid_filter_parameters: "Bu rapor için seçtiğiniz filtreler geçersiz." + report: + none: "SATIŞ YAPMIYOR" order: "Sipariş" distribution: "dağıtım" order_details: "sipariş detayları" @@ -2874,7 +2885,13 @@ tr: previous: "Önceki" last: "Son" spree: + all: "Hepsi" + category: "Kategori" + credit: "Bakiye" more: "Daha Fazla" + no_pending_payments: "Bekleyen ödeme yok" + none: "SATIŞ YAPMIYOR" + updating: "Güncelleniyor" your_order_is_empty_add_product: "Sepetiniz boş, lütfen bir ürün arayın ve ekleyin" add_product: "ürün ekle" name_or_sku: "Ad veya STOK KODU (ürün adının en az ilk 4 karakterini girin)" @@ -3050,6 +3067,7 @@ tr: payment_method: "ÖDEME YÖNTEMİ" payment_processing_failed: "Ödeme işlenemedi, lütfen girdiğiniz bilgileri kontrol edin" not_available: "Yok" + sku: "Stok Kodu" order_populator: out_of_stock: '%{item} stokta yok' actions: @@ -3077,6 +3095,8 @@ tr: header: store: Ana Site admin: + subscriptions: + number: "Numara" tab: dashboard: "KONTROL PANELİ" orders: "SİPARİŞLER" @@ -3225,6 +3245,7 @@ tr: back_to_shipping_methods_list: "Teslimat Yöntemlerine Gerİ Dön" form: categories: "Kategoriler" + tax_category: "Vergi Kategorisi" zones: "bölgeler" both: "Ödeme Sayfası ve Panel" back_end: "Sadece panel" @@ -3298,6 +3319,7 @@ tr: value: "değer" unit_name: "BİRİM ADI" price: "Fiyat" + unit_price: "Birim fiyat" on_hand: "Mevcut" on_demand: "Talep üzerine" product_description: "Ürün Açıklaması" @@ -3368,7 +3390,6 @@ tr: price: "Fiyat" options: "Seçenekler" no_results: "Sonuç yok" - to_add_variants_you_must_first_define: "Varyant eklemeden önce tanımlamanız gerekir" option_types: "Seçenek Türleri" option_values: "Seçenek Değerleri" and: "ve" @@ -3380,6 +3401,7 @@ tr: form: sku: "Stok Kodu" price: "Fiyat" + unit_price: "Birim fiyat" display_as: "Gösterme Şekli" display_name: "Ekran adı" display_as_placeholder: 'Örn. 2 kg' diff --git a/config/ng-test.conf.js b/config/ng-test.conf.js index 8c4d5e971b..618b533b58 100644 --- a/config/ng-test.conf.js +++ b/config/ng-test.conf.js @@ -16,6 +16,7 @@ module.exports = function(config) { 'app/assets/javascripts/admin/**/*.js*', 'app/assets/javascripts/darkswarm/*.js*', 'app/assets/javascripts/darkswarm/**/*.js*', + 'app/assets/javascripts/shared/shared.js.coffee', 'spec/javascripts/unit/**/*.js*' ], diff --git a/config/routes.rb b/config/routes.rb index 5236a42c62..22e0db432a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,8 +68,9 @@ Openfoodnetwork::Application.routes.draw do resources :webhooks, only: [:create] end - get '/checkout', :to => 'checkout#edit' , :as => :checkout - put '/checkout', :to => 'checkout#update' , :as => :update_checkout + get '/checkout', to: 'checkout#edit' , as: :checkout + put '/checkout', to: 'checkout#update' , as: :update_checkout + get '/checkout/:state', to: 'checkout#edit', as: :checkout_state get '/checkout/paypal_payment/:order_id', to: 'checkout#paypal_payment', as: :paypal_payment get 'embedded_shopfront/shopfront_session', to: 'application#shopfront_session' diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 5b4a5b3479..88a577df18 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -3,6 +3,7 @@ Openfoodnetwork::Application.routes.draw do authenticated :spree_user, -> user { user.admin? } do mount DelayedJobWeb, at: '/delayed_job' + mount Flipper::UI.app(Flipper) => '/feature-toggle' end resources :bulk_line_items diff --git a/config/routes/api.rb b/config/routes/api.rb index 6bdfd5dcb3..69f41549f2 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -1,80 +1,84 @@ Openfoodnetwork::Application.routes.draw do namespace :api do - resources :products do - collection do - get :bulk_products - get :overridable - end - post :clone + namespace :v0 do + resources :products do + collection do + get :bulk_products + get :overridable + end + post :clone - resources :variants - end - - resources :variants, :only => [:index] - - resources :orders, only: [:index, :show] do - member do - put :capture - put :ship + resources :variants end - resources :shipments, :only => [:create, :update] do + resources :variants, :only => [:index] + + resources :orders, only: [:index, :show] do member do - put :ready + put :capture put :ship - put :add - put :remove + end + + resources :shipments, :only => [:create, :update] do + member do + put :ready + put :ship + put :add + put :remove + end end end - end - resources :enterprises do - post :update_image, on: :member + resources :enterprises do + post :update_image, on: :member - resource :logo, only: [:destroy] - resource :promo_image, only: [:destroy] - resource :terms_and_conditions, only: [:destroy] - end - - resources :shops, only: [:show] do - collection do - get :closed_shops + resource :logo, only: [:destroy] + resource :promo_image, only: [:destroy] + resource :terms_and_conditions, only: [:destroy] end - end - resources :order_cycles do - get :products, on: :member - get :taxons, on: :member - get :properties, on: :member - end - - resources :exchanges, only: [:show], to: 'exchange_products#index' do - get :products, to: 'exchange_products#index' - end - - resource :status do - get :job_queue - end - - resources :customers, only: [:index, :update] - - resources :enterprise_fees, only: [:destroy] - - post '/product_images/:product_id', to: 'product_images#update_product_image' - - resources :states, :only => [:index, :show] - - resources :taxons, :only => [:index] - - resources :taxonomies do - member do - get :jstree + resources :shops, only: [:show] do + collection do + get :closed_shops + end end - resources :taxons do + + resources :order_cycles do + get :products, on: :member + get :taxons, on: :member + get :properties, on: :member + end + + resources :exchanges, only: [:show], to: 'exchange_products#index' do + get :products, to: 'exchange_products#index' + end + + resource :status do + get :job_queue + end + + resources :customers, only: [:index, :update] + + resources :enterprise_fees, only: [:destroy] + + post '/product_images/:product_id', to: 'product_images#update_product_image' + + resources :states, :only => [:index, :show] + + resources :taxons, :only => [:index] + + resources :taxonomies do member do get :jstree end + resources :taxons do + member do + get :jstree + end + end end end + + match '*path', to: redirect(path: "/api/v0/%{path}"), via: :all, constraints: { path: /(?!v[0-9]).+/ } end end diff --git a/config/routes/spree.rb b/config/routes/spree.rb index a16ccaf107..f93a869170 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -170,7 +170,6 @@ Spree::Core::Engine.routes.draw do resources :products # Used by spree_paypal_express - get '/checkout/:state', :to => 'checkout#edit', :as => :checkout_state get '/content/cvv', :to => 'content#cvv', :as => :cvv get '/content/*path', :to => 'content#show', :as => :content get '/paypal', :to => "paypal#express", :as => :paypal_express diff --git a/db/migrate/20181128054803_old_migrations_removed.rb b/db/migrate/20181128054803_old_migrations_removed.rb index 47d233f0aa..a8dc8b0454 100644 --- a/db/migrate/20181128054803_old_migrations_removed.rb +++ b/db/migrate/20181128054803_old_migrations_removed.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class OldMigrationsRemoved < ActiveRecord::Migration +class OldMigrationsRemoved < ActiveRecord::Migration[4.2] def up raise StandardError, <<-MESSAGE diff --git a/db/migrate/20190221131622_delete_account_invoices_preferences.rb b/db/migrate/20190221131622_delete_account_invoices_preferences.rb index e55a61f721..217078b52c 100644 --- a/db/migrate/20190221131622_delete_account_invoices_preferences.rb +++ b/db/migrate/20190221131622_delete_account_invoices_preferences.rb @@ -1,4 +1,4 @@ -class DeleteAccountInvoicesPreferences < ActiveRecord::Migration +class DeleteAccountInvoicesPreferences < ActiveRecord::Migration[4.2] def up Spree::Preference .where( key: ['spree/app_configuration/accounts_distributor_id', diff --git a/db/migrate/20190221131741_delete_account_invoices_adjustments.rb b/db/migrate/20190221131741_delete_account_invoices_adjustments.rb index 1f1af59594..dcd965cdae 100644 --- a/db/migrate/20190221131741_delete_account_invoices_adjustments.rb +++ b/db/migrate/20190221131741_delete_account_invoices_adjustments.rb @@ -1,4 +1,4 @@ -class DeleteAccountInvoicesAdjustments < ActiveRecord::Migration +class DeleteAccountInvoicesAdjustments < ActiveRecord::Migration[4.2] def up Spree::Adjustment .where(source_type: 'BillablePeriod') diff --git a/db/migrate/20190221214542_drop_enterprise_shop_trial_start_date.rb b/db/migrate/20190221214542_drop_enterprise_shop_trial_start_date.rb index 69dd360e2c..0c77f1a6db 100644 --- a/db/migrate/20190221214542_drop_enterprise_shop_trial_start_date.rb +++ b/db/migrate/20190221214542_drop_enterprise_shop_trial_start_date.rb @@ -1,4 +1,4 @@ -class DropEnterpriseShopTrialStartDate < ActiveRecord::Migration +class DropEnterpriseShopTrialStartDate < ActiveRecord::Migration[4.2] def up remove_column :enterprises, :shop_trial_start_date end diff --git a/db/migrate/20190303143409_drop_product_distributions.rb b/db/migrate/20190303143409_drop_product_distributions.rb index 73318a359d..9de25c9164 100644 --- a/db/migrate/20190303143409_drop_product_distributions.rb +++ b/db/migrate/20190303143409_drop_product_distributions.rb @@ -1,4 +1,4 @@ -class DropProductDistributions < ActiveRecord::Migration +class DropProductDistributions < ActiveRecord::Migration[4.2] def up drop_table :product_distributions end diff --git a/db/migrate/20190313142051_set_default_stock_location_on_shipments.rb b/db/migrate/20190313142051_set_default_stock_location_on_shipments.rb index 45add57fe3..66d5f6cbde 100644 --- a/db/migrate/20190313142051_set_default_stock_location_on_shipments.rb +++ b/db/migrate/20190313142051_set_default_stock_location_on_shipments.rb @@ -1,4 +1,4 @@ -class SetDefaultStockLocationOnShipments < ActiveRecord::Migration +class SetDefaultStockLocationOnShipments < ActiveRecord::Migration[4.2] def up if Spree::Shipment.where('stock_location_id IS NULL').count > 0 location = DefaultStockLocation.find_or_create diff --git a/db/migrate/20190313142540_add_shipping_category_to_shipping_methods_and_products.rb b/db/migrate/20190313142540_add_shipping_category_to_shipping_methods_and_products.rb index b51c9a67b0..f2e0eacf7b 100644 --- a/db/migrate/20190313142540_add_shipping_category_to_shipping_methods_and_products.rb +++ b/db/migrate/20190313142540_add_shipping_category_to_shipping_methods_and_products.rb @@ -1,4 +1,4 @@ -class AddShippingCategoryToShippingMethodsAndProducts < ActiveRecord::Migration +class AddShippingCategoryToShippingMethodsAndProducts < ActiveRecord::Migration[4.2] def up # This is different from the equivalent Spree migration # Here we are creating the default shipping category even if there are already shipping categories diff --git a/db/migrate/20190315224423_drop_account_invoices_and_billable_periods.rb b/db/migrate/20190315224423_drop_account_invoices_and_billable_periods.rb index 4aaa282221..a754dfc0e7 100644 --- a/db/migrate/20190315224423_drop_account_invoices_and_billable_periods.rb +++ b/db/migrate/20190315224423_drop_account_invoices_and_billable_periods.rb @@ -1,4 +1,4 @@ -class DropAccountInvoicesAndBillablePeriods < ActiveRecord::Migration +class DropAccountInvoicesAndBillablePeriods < ActiveRecord::Migration[4.2] def up drop_table :billable_periods drop_table :account_invoices diff --git a/db/migrate/20190320111312_delete_obsolete_pending_jobs.rb b/db/migrate/20190320111312_delete_obsolete_pending_jobs.rb index 043612971c..d753c9ba6b 100644 --- a/db/migrate/20190320111312_delete_obsolete_pending_jobs.rb +++ b/db/migrate/20190320111312_delete_obsolete_pending_jobs.rb @@ -1,4 +1,4 @@ -class DeleteObsoletePendingJobs < ActiveRecord::Migration +class DeleteObsoletePendingJobs < ActiveRecord::Migration[4.2] def up Delayed::Job.all.each do |job| job.delete if job.name == "FinalizeAccountInvoices" || diff --git a/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb b/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb index 3170545118..eade2ba9a6 100644 --- a/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb +++ b/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToSpreeStockItems < ActiveRecord::Migration +class AddDeletedAtToSpreeStockItems < ActiveRecord::Migration[4.2] def up add_column :spree_stock_items, :deleted_at, :datetime end diff --git a/db/migrate/20190501143327_migrate_variants_on_demand_to_stock_items_backorderable.rb b/db/migrate/20190501143327_migrate_variants_on_demand_to_stock_items_backorderable.rb index 86d7a9d3ff..a507603120 100644 --- a/db/migrate/20190501143327_migrate_variants_on_demand_to_stock_items_backorderable.rb +++ b/db/migrate/20190501143327_migrate_variants_on_demand_to_stock_items_backorderable.rb @@ -1,4 +1,4 @@ -class MigrateVariantsOnDemandToStockItemsBackorderable < ActiveRecord::Migration +class MigrateVariantsOnDemandToStockItemsBackorderable < ActiveRecord::Migration[4.2] def up # We use SQL directly here to avoid going through VariantStock.on_demand and VariantStock.on_demand= sql = "update spree_stock_items set backorderable = (select on_demand from spree_variants where spree_variants.id = spree_stock_items.variant_id)" diff --git a/db/migrate/20190504151144_remove_field_name_from_exchange.rb b/db/migrate/20190504151144_remove_field_name_from_exchange.rb index 459c5f0444..5bd06e121e 100644 --- a/db/migrate/20190504151144_remove_field_name_from_exchange.rb +++ b/db/migrate/20190504151144_remove_field_name_from_exchange.rb @@ -1,4 +1,4 @@ -class RemoveFieldNameFromExchange < ActiveRecord::Migration +class RemoveFieldNameFromExchange < ActiveRecord::Migration[4.2] def up remove_column :exchanges, :payment_enterprise_id end diff --git a/db/migrate/20190506194625_update_stock_locations_backorderable_default.rb b/db/migrate/20190506194625_update_stock_locations_backorderable_default.rb index a95aae6eea..456f2b7fa4 100644 --- a/db/migrate/20190506194625_update_stock_locations_backorderable_default.rb +++ b/db/migrate/20190506194625_update_stock_locations_backorderable_default.rb @@ -1,4 +1,4 @@ -class UpdateStockLocationsBackorderableDefault < ActiveRecord::Migration +class UpdateStockLocationsBackorderableDefault < ActiveRecord::Migration[4.2] def change Spree::StockLocation.update_all(backorderable_default: false) end diff --git a/db/migrate/20190701002454_convert_string_fields_to_text.rb b/db/migrate/20190701002454_convert_string_fields_to_text.rb index 9d461c6070..b6c723747c 100644 --- a/db/migrate/20190701002454_convert_string_fields_to_text.rb +++ b/db/migrate/20190701002454_convert_string_fields_to_text.rb @@ -1,4 +1,4 @@ -class ConvertStringFieldsToText < ActiveRecord::Migration +class ConvertStringFieldsToText < ActiveRecord::Migration[4.2] def up change_column :enterprises, :description, :text change_column :enterprises, :pickup_times, :text diff --git a/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb b/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb index 949b7c11d9..c1159f8e5a 100644 --- a/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb +++ b/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToSpreePrices < ActiveRecord::Migration +class AddDeletedAtToSpreePrices < ActiveRecord::Migration[4.2] def change add_column :spree_prices, :deleted_at, :datetime end diff --git a/db/migrate/20190906151259_reset_negative_stock_levels.rb b/db/migrate/20190906151259_reset_negative_stock_levels.rb index ec0be5a4be..0a060f9ebd 100644 --- a/db/migrate/20190906151259_reset_negative_stock_levels.rb +++ b/db/migrate/20190906151259_reset_negative_stock_levels.rb @@ -1,4 +1,4 @@ -class ResetNegativeStockLevels < ActiveRecord::Migration +class ResetNegativeStockLevels < ActiveRecord::Migration[4.2] def up # Reset stock to zero for all on_demand variants that have negative stock execute "UPDATE spree_stock_items SET count_on_hand = '0' WHERE count_on_hand < 0 AND backorderable IS TRUE" diff --git a/db/migrate/20190906165501_remove_broken_variants_from_carts.rb b/db/migrate/20190906165501_remove_broken_variants_from_carts.rb index 3e6cfaed10..1c1452b42d 100644 --- a/db/migrate/20190906165501_remove_broken_variants_from_carts.rb +++ b/db/migrate/20190906165501_remove_broken_variants_from_carts.rb @@ -1,4 +1,4 @@ -class RemoveBrokenVariantsFromCarts < ActiveRecord::Migration +class RemoveBrokenVariantsFromCarts < ActiveRecord::Migration[4.2] def up # Removes line_items from open carts where the variant has a hard-deleted price diff --git a/db/migrate/20190908183511_set_backordered_inventory_to_on_hand.rb b/db/migrate/20190908183511_set_backordered_inventory_to_on_hand.rb index c743a381ed..3295bb4da6 100644 --- a/db/migrate/20190908183511_set_backordered_inventory_to_on_hand.rb +++ b/db/migrate/20190908183511_set_backordered_inventory_to_on_hand.rb @@ -1,4 +1,4 @@ -class SetBackorderedInventoryToOnHand < ActiveRecord::Migration +class SetBackorderedInventoryToOnHand < ActiveRecord::Migration[4.2] def up execute("UPDATE spree_inventory_units SET state = 'on_hand' WHERE state = 'backordered'") end diff --git a/db/migrate/20190913023137_replace_hard_deleted_prices.rb b/db/migrate/20190913023137_replace_hard_deleted_prices.rb index 15b34c12a7..8f658f50c6 100644 --- a/db/migrate/20190913023137_replace_hard_deleted_prices.rb +++ b/db/migrate/20190913023137_replace_hard_deleted_prices.rb @@ -1,4 +1,4 @@ -class ReplaceHardDeletedPrices < ActiveRecord::Migration +class ReplaceHardDeletedPrices < ActiveRecord::Migration[4.2] def up ActiveRecord::Base.connection.execute( "INSERT into spree_prices (variant_id, amount, currency, deleted_at) diff --git a/db/migrate/20190916105416_add_long_compound_index_on_spree_orders.rb b/db/migrate/20190916105416_add_long_compound_index_on_spree_orders.rb index 5ff04483ec..2564a66488 100644 --- a/db/migrate/20190916105416_add_long_compound_index_on_spree_orders.rb +++ b/db/migrate/20190916105416_add_long_compound_index_on_spree_orders.rb @@ -1,4 +1,4 @@ -class AddLongCompoundIndexOnSpreeOrders < ActiveRecord::Migration +class AddLongCompoundIndexOnSpreeOrders < ActiveRecord::Migration[4.2] def change add_index( :spree_orders, diff --git a/db/migrate/20190916110029_drop_completed_at_index_on_spree_orders.rb b/db/migrate/20190916110029_drop_completed_at_index_on_spree_orders.rb index 47b5517295..2a65208ee3 100644 --- a/db/migrate/20190916110029_drop_completed_at_index_on_spree_orders.rb +++ b/db/migrate/20190916110029_drop_completed_at_index_on_spree_orders.rb @@ -1,4 +1,4 @@ -class DropCompletedAtIndexOnSpreeOrders < ActiveRecord::Migration +class DropCompletedAtIndexOnSpreeOrders < ActiveRecord::Migration[4.2] def change remove_index :spree_orders, :completed_at end diff --git a/db/migrate/20190918105234_remove_all_master_variants_from_exchanges.rb b/db/migrate/20190918105234_remove_all_master_variants_from_exchanges.rb index 1b6de20c30..c6ce2fbce7 100644 --- a/db/migrate/20190918105234_remove_all_master_variants_from_exchanges.rb +++ b/db/migrate/20190918105234_remove_all_master_variants_from_exchanges.rb @@ -1,4 +1,4 @@ -class RemoveAllMasterVariantsFromExchanges < ActiveRecord::Migration +class RemoveAllMasterVariantsFromExchanges < ActiveRecord::Migration[4.2] def up # 1. We add standard variants of the products of "lonely masters" into the Exchanges where the master variants are lonely match_master_variants diff --git a/db/migrate/20190922201034_drop_orders_shipping_method_id.rb b/db/migrate/20190922201034_drop_orders_shipping_method_id.rb index 4f35ec7e99..b5292837e0 100644 --- a/db/migrate/20190922201034_drop_orders_shipping_method_id.rb +++ b/db/migrate/20190922201034_drop_orders_shipping_method_id.rb @@ -1,4 +1,4 @@ -class DropOrdersShippingMethodId < ActiveRecord::Migration +class DropOrdersShippingMethodId < ActiveRecord::Migration[4.2] def up remove_column :spree_orders, :shipping_method_id end diff --git a/db/migrate/20191023105006_drop_prototypes_tables.rb b/db/migrate/20191023105006_drop_prototypes_tables.rb index 974cec87ea..be22c757b4 100644 --- a/db/migrate/20191023105006_drop_prototypes_tables.rb +++ b/db/migrate/20191023105006_drop_prototypes_tables.rb @@ -1,4 +1,4 @@ -class DropPrototypesTables < ActiveRecord::Migration +class DropPrototypesTables < ActiveRecord::Migration[4.2] def up drop_table :spree_option_types_prototypes drop_table :spree_properties_prototypes diff --git a/db/migrate/20191023172424_add_indexes_to_spree_orders.rb b/db/migrate/20191023172424_add_indexes_to_spree_orders.rb index d121049fb4..bf92cc844d 100644 --- a/db/migrate/20191023172424_add_indexes_to_spree_orders.rb +++ b/db/migrate/20191023172424_add_indexes_to_spree_orders.rb @@ -1,4 +1,4 @@ -class AddIndexesToSpreeOrders < ActiveRecord::Migration +class AddIndexesToSpreeOrders < ActiveRecord::Migration[4.2] def change add_index :spree_orders, :order_cycle_id add_index :spree_orders, :distributor_id diff --git a/db/migrate/20191202165700_add_custom_data_to_versions.rb b/db/migrate/20191202165700_add_custom_data_to_versions.rb index 45a10ed67e..ddc2c2f26a 100644 --- a/db/migrate/20191202165700_add_custom_data_to_versions.rb +++ b/db/migrate/20191202165700_add_custom_data_to_versions.rb @@ -1,4 +1,4 @@ -class AddCustomDataToVersions < ActiveRecord::Migration +class AddCustomDataToVersions < ActiveRecord::Migration[4.2] def change add_column :versions, :custom_data, :string end diff --git a/db/migrate/20200209163549_change_cvv_response_message_to_text_in_spree_payments.rb b/db/migrate/20200209163549_change_cvv_response_message_to_text_in_spree_payments.rb index 5e2e8d88ad..0e2fb44b72 100644 --- a/db/migrate/20200209163549_change_cvv_response_message_to_text_in_spree_payments.rb +++ b/db/migrate/20200209163549_change_cvv_response_message_to_text_in_spree_payments.rb @@ -1,4 +1,4 @@ -class ChangeCvvResponseMessageToTextInSpreePayments < ActiveRecord::Migration +class ChangeCvvResponseMessageToTextInSpreePayments < ActiveRecord::Migration[4.2] def up change_column :spree_payments, :cvv_response_message, :text end diff --git a/db/migrate/20200327105910_change_versions_custom_data_to_text.rb b/db/migrate/20200327105910_change_versions_custom_data_to_text.rb index 0a995a85f4..f5b43f9a81 100644 --- a/db/migrate/20200327105910_change_versions_custom_data_to_text.rb +++ b/db/migrate/20200327105910_change_versions_custom_data_to_text.rb @@ -1,4 +1,4 @@ -class ChangeVersionsCustomDataToText < ActiveRecord::Migration +class ChangeVersionsCustomDataToText < ActiveRecord::Migration[4.2] def up change_column :versions, :custom_data, :text end diff --git a/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb b/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb index cb8ef67b0e..46e760f04d 100644 --- a/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb +++ b/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb @@ -1,4 +1,4 @@ -class AddUserIdIndexToSpreeOrders < ActiveRecord::Migration +class AddUserIdIndexToSpreeOrders < ActiveRecord::Migration[4.2] def change add_index :spree_orders, :user_id end diff --git a/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb b/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb index eadc5a7c50..dd157c573d 100644 --- a/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb +++ b/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb @@ -1,4 +1,4 @@ -class AddSupplierIdIndexToSpreeProducts < ActiveRecord::Migration +class AddSupplierIdIndexToSpreeProducts < ActiveRecord::Migration[4.2] def change add_index :spree_products, :supplier_id end diff --git a/db/migrate/20200404083008_drop_trackers_table.rb b/db/migrate/20200404083008_drop_trackers_table.rb index 4dca8c7cfc..7f29258953 100644 --- a/db/migrate/20200404083008_drop_trackers_table.rb +++ b/db/migrate/20200404083008_drop_trackers_table.rb @@ -1,4 +1,4 @@ -class DropTrackersTable < ActiveRecord::Migration +class DropTrackersTable < ActiveRecord::Migration[4.2] def up drop_table :spree_trackers end diff --git a/db/migrate/20200404090436_remove_ga_cookies_preference.rb b/db/migrate/20200404090436_remove_ga_cookies_preference.rb index c509b11e5e..156d308dbe 100644 --- a/db/migrate/20200404090436_remove_ga_cookies_preference.rb +++ b/db/migrate/20200404090436_remove_ga_cookies_preference.rb @@ -1,4 +1,4 @@ -class RemoveGaCookiesPreference < ActiveRecord::Migration +class RemoveGaCookiesPreference < ActiveRecord::Migration[4.2] class Spree::Preference < ActiveRecord::Base; end def up diff --git a/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb b/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb index 5cac7dab5b..e1070cba7f 100644 --- a/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb +++ b/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb @@ -1,4 +1,4 @@ -class IncreaseCharactersOfLocaleInSpreeUsers < ActiveRecord::Migration +class IncreaseCharactersOfLocaleInSpreeUsers < ActiveRecord::Migration[4.2] def up change_column :spree_users, :locale, :string, limit: 6 end diff --git a/db/migrate/20200429122446_drop_mail_methods.rb b/db/migrate/20200429122446_drop_mail_methods.rb index 12dba55bbe..3efdabce91 100644 --- a/db/migrate/20200429122446_drop_mail_methods.rb +++ b/db/migrate/20200429122446_drop_mail_methods.rb @@ -1,4 +1,4 @@ -class DropMailMethods < ActiveRecord::Migration +class DropMailMethods < ActiveRecord::Migration[4.2] def up drop_table :spree_mail_methods diff --git a/db/migrate/20200430105459_add_timestamps_to_order_cycle_schedules.rb b/db/migrate/20200430105459_add_timestamps_to_order_cycle_schedules.rb index 5f57cd13a2..270977ad60 100644 --- a/db/migrate/20200430105459_add_timestamps_to_order_cycle_schedules.rb +++ b/db/migrate/20200430105459_add_timestamps_to_order_cycle_schedules.rb @@ -1,4 +1,4 @@ -class AddTimestampsToOrderCycleSchedules < ActiveRecord::Migration +class AddTimestampsToOrderCycleSchedules < ActiveRecord::Migration[4.2] def change change_table :order_cycle_schedules do |t| t.timestamps diff --git a/db/migrate/20200508101630_convert_frontend_shipping_method_to_both.rb b/db/migrate/20200508101630_convert_frontend_shipping_method_to_both.rb index 5e2418c3b8..c44dd18a1c 100644 --- a/db/migrate/20200508101630_convert_frontend_shipping_method_to_both.rb +++ b/db/migrate/20200508101630_convert_frontend_shipping_method_to_both.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ConvertFrontendShippingMethodToBoth < ActiveRecord::Migration +class ConvertFrontendShippingMethodToBoth < ActiveRecord::Migration[4.2] def up # The display_on value front_end is not working # (it's not being used in the back office to ignore shipping methods marked as front_end) diff --git a/db/migrate/20200512070717_add_lock_version_to_stock_items.rb b/db/migrate/20200512070717_add_lock_version_to_stock_items.rb index 416a43f62e..24fc2eb9a9 100644 --- a/db/migrate/20200512070717_add_lock_version_to_stock_items.rb +++ b/db/migrate/20200512070717_add_lock_version_to_stock_items.rb @@ -1,4 +1,4 @@ -class AddLockVersionToStockItems < ActiveRecord::Migration +class AddLockVersionToStockItems < ActiveRecord::Migration[4.2] def change add_column :spree_stock_items, :lock_version, :integer, default: 0 end diff --git a/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb b/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb index c57730c99a..cc46f82d12 100644 --- a/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb +++ b/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ResetNegativeNonbackorderableCountOnHandInStockItems < ActiveRecord::Migration +class ResetNegativeNonbackorderableCountOnHandInStockItems < ActiveRecord::Migration[4.2] module Spree class StockItem < ActiveRecord::Base self.table_name = "spree_stock_items" diff --git a/db/migrate/20200616162646_move_all_calculators_outside_the_spree_namespace.rb b/db/migrate/20200616162646_move_all_calculators_outside_the_spree_namespace.rb index b357242db2..8514b5e4ee 100644 --- a/db/migrate/20200616162646_move_all_calculators_outside_the_spree_namespace.rb +++ b/db/migrate/20200616162646_move_all_calculators_outside_the_spree_namespace.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class MoveAllCalculatorsOutsideTheSpreeNamespace < ActiveRecord::Migration +class MoveAllCalculatorsOutsideTheSpreeNamespace < ActiveRecord::Migration[4.2] def up convert_calculator("DefaultTax") convert_calculator("FlatPercentItemTotal") diff --git a/db/migrate/20200623140437_fix_preferences_keys.rb b/db/migrate/20200623140437_fix_preferences_keys.rb index 3f024ee278..08819689ff 100644 --- a/db/migrate/20200623140437_fix_preferences_keys.rb +++ b/db/migrate/20200623140437_fix_preferences_keys.rb @@ -1,4 +1,4 @@ -class FixPreferencesKeys < ActiveRecord::Migration +class FixPreferencesKeys < ActiveRecord::Migration[4.2] def up unmigrated_preferences = Spree::Preference.exists?(['key NOT LIKE ?', '/%']) return unless unmigrated_preferences diff --git a/db/migrate/20200624091611_make_timestamps_nullable.rb b/db/migrate/20200624091611_make_timestamps_nullable.rb index 32ea61ac43..545a84eb62 100644 --- a/db/migrate/20200624091611_make_timestamps_nullable.rb +++ b/db/migrate/20200624091611_make_timestamps_nullable.rb @@ -1,4 +1,4 @@ -class MakeTimestampsNullable < ActiveRecord::Migration +class MakeTimestampsNullable < ActiveRecord::Migration[4.2] def up change_column_null :customers, :created_at, true change_column_null :customers, :updated_at, true diff --git a/db/migrate/20200630070422_require_timestamps.rb b/db/migrate/20200630070422_require_timestamps.rb index 2075876bca..8d510288d3 100644 --- a/db/migrate/20200630070422_require_timestamps.rb +++ b/db/migrate/20200630070422_require_timestamps.rb @@ -1,4 +1,4 @@ -class RequireTimestamps < ActiveRecord::Migration +class RequireTimestamps < ActiveRecord::Migration[4.2] def up current_time = Time.zone.now diff --git a/db/migrate/20200702112157_add_stateful_id_index_to_state_changes.rb b/db/migrate/20200702112157_add_stateful_id_index_to_state_changes.rb index 8a52643cff..4cfff94491 100644 --- a/db/migrate/20200702112157_add_stateful_id_index_to_state_changes.rb +++ b/db/migrate/20200702112157_add_stateful_id_index_to_state_changes.rb @@ -1,4 +1,4 @@ -class AddStatefulIdIndexToStateChanges < ActiveRecord::Migration +class AddStatefulIdIndexToStateChanges < ActiveRecord::Migration[4.2] def change add_index :spree_state_changes, :stateful_id end diff --git a/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb b/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb index 2591550dd1..553288dfe8 100644 --- a/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb +++ b/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb @@ -1,6 +1,6 @@ # As we moved the calculators outside the Spree namespace in migration MoveAllCalculatorsOutsideTheSpreeNamespace # We need to move their preferences too (currency, value, etc), otherwise they are not used -class MoveCalculatorsPreferencesOutsideSpreeNamespace < ActiveRecord::Migration +class MoveCalculatorsPreferencesOutsideSpreeNamespace < ActiveRecord::Migration[4.2] def up replace_preferences_key("/spree/calculator", "/calculator") end diff --git a/db/migrate/20200817150002_add_terms_and_conditions_to_enterprises.rb b/db/migrate/20200817150002_add_terms_and_conditions_to_enterprises.rb index 57b646abd6..7f08cc2a53 100644 --- a/db/migrate/20200817150002_add_terms_and_conditions_to_enterprises.rb +++ b/db/migrate/20200817150002_add_terms_and_conditions_to_enterprises.rb @@ -1,4 +1,4 @@ -class AddTermsAndConditionsToEnterprises < ActiveRecord::Migration +class AddTermsAndConditionsToEnterprises < ActiveRecord::Migration[4.2] def change add_attachment :enterprises, :terms_and_conditions end diff --git a/db/migrate/20200907140555_add_customer_terms_and_conditions_accepted.rb b/db/migrate/20200907140555_add_customer_terms_and_conditions_accepted.rb index c48b1c19f2..95ed8158ba 100644 --- a/db/migrate/20200907140555_add_customer_terms_and_conditions_accepted.rb +++ b/db/migrate/20200907140555_add_customer_terms_and_conditions_accepted.rb @@ -1,4 +1,4 @@ -class AddCustomerTermsAndConditionsAccepted < ActiveRecord::Migration +class AddCustomerTermsAndConditionsAccepted < ActiveRecord::Migration[4.2] def change add_column :customers, :terms_and_conditions_accepted_at, :datetime end diff --git a/db/migrate/20200912190210_update_weight_calculators.rb b/db/migrate/20200912190210_update_weight_calculators.rb index 2a24138957..60adba69b1 100644 --- a/db/migrate/20200912190210_update_weight_calculators.rb +++ b/db/migrate/20200912190210_update_weight_calculators.rb @@ -1,4 +1,4 @@ -class UpdateWeightCalculators < ActiveRecord::Migration +class UpdateWeightCalculators < ActiveRecord::Migration[4.2] def change Spree::Calculator.connection.execute( "UPDATE spree_preferences SET key = replace( key, 'per_kg', 'per_unit') WHERE key ilike '/calculator/weight/per_kg/%'" diff --git a/db/migrate/20201113163155_repeat_move_all_calculators_outside_the_spree_namespace.rb b/db/migrate/20201113163155_repeat_move_all_calculators_outside_the_spree_namespace.rb index 60b127245f..47f4d76464 100644 --- a/db/migrate/20201113163155_repeat_move_all_calculators_outside_the_spree_namespace.rb +++ b/db/migrate/20201113163155_repeat_move_all_calculators_outside_the_spree_namespace.rb @@ -1,6 +1,6 @@ # For some unkonwn reason, after removing Spree as a dependency, some spree calculators appeared on live DBs # Here we repeat the migration -class RepeatMoveAllCalculatorsOutsideTheSpreeNamespace < ActiveRecord::Migration +class RepeatMoveAllCalculatorsOutsideTheSpreeNamespace < ActiveRecord::Migration[4.2] def up convert_calculator("DefaultTax") convert_calculator("FlatPercentItemTotal") diff --git a/db/migrate/20201113163227_repeat_move_calculators_preferences_outside_spree_namespace.rb b/db/migrate/20201113163227_repeat_move_calculators_preferences_outside_spree_namespace.rb index 24adad016b..84c52d26bf 100644 --- a/db/migrate/20201113163227_repeat_move_calculators_preferences_outside_spree_namespace.rb +++ b/db/migrate/20201113163227_repeat_move_calculators_preferences_outside_spree_namespace.rb @@ -1,6 +1,6 @@ # For some unkonwn reason, after removing Spree as a dependency, some spree calculators appeared on live DBs # Here we repeat the migration -class RepeatMoveCalculatorsPreferencesOutsideSpreeNamespace < ActiveRecord::Migration +class RepeatMoveCalculatorsPreferencesOutsideSpreeNamespace < ActiveRecord::Migration[4.2] def up replace_preferences_key("/spree/calculator", "/calculator") end diff --git a/db/migrate/20201219120055_add_order_to_adjustments.rb b/db/migrate/20201219120055_add_order_to_adjustments.rb index e0d6c32287..e1181c1eae 100644 --- a/db/migrate/20201219120055_add_order_to_adjustments.rb +++ b/db/migrate/20201219120055_add_order_to_adjustments.rb @@ -1,4 +1,4 @@ -class AddOrderToAdjustments < ActiveRecord::Migration +class AddOrderToAdjustments < ActiveRecord::Migration[4.2] class Spree::Adjustment < ActiveRecord::Base belongs_to :adjustable, polymorphic: true belongs_to :order, class_name: "Spree::Order" diff --git a/db/migrate/20201227122327_add_included_to_adjustments.rb b/db/migrate/20201227122327_add_included_to_adjustments.rb index 2ccbeab2a3..9fe8e838d4 100644 --- a/db/migrate/20201227122327_add_included_to_adjustments.rb +++ b/db/migrate/20201227122327_add_included_to_adjustments.rb @@ -1,4 +1,4 @@ -class AddIncludedToAdjustments < ActiveRecord::Migration +class AddIncludedToAdjustments < ActiveRecord::Migration[4.2] class Spree::TaxRate < ActiveRecord::Base; end class Spree::Adjustment < ActiveRecord::Base diff --git a/db/migrate/20210115143738_add_deleted_at_to_enterprise_fee.rb b/db/migrate/20210115143738_add_deleted_at_to_enterprise_fee.rb index f3afbf28d9..42fb42bb55 100644 --- a/db/migrate/20210115143738_add_deleted_at_to_enterprise_fee.rb +++ b/db/migrate/20210115143738_add_deleted_at_to_enterprise_fee.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToEnterpriseFee < ActiveRecord::Migration +class AddDeletedAtToEnterpriseFee < ActiveRecord::Migration[4.2] def change add_column :enterprise_fees, :deleted_at, :datetime end diff --git a/db/migrate/20210123044336_add_tax_totals_to_order.rb b/db/migrate/20210123044336_add_tax_totals_to_order.rb index 64d99da532..b64836588a 100644 --- a/db/migrate/20210123044336_add_tax_totals_to_order.rb +++ b/db/migrate/20210123044336_add_tax_totals_to_order.rb @@ -1,4 +1,4 @@ -class AddTaxTotalsToOrder < ActiveRecord::Migration +class AddTaxTotalsToOrder < ActiveRecord::Migration[4.2] def up add_column :spree_orders, :included_tax_total, :decimal, precision: 10, scale: 2, null: false, default: 0.0 diff --git a/db/migrate/20210125123000_remove_enable_mail_delivery_preference.rb b/db/migrate/20210125123000_remove_enable_mail_delivery_preference.rb index a08642e931..7b9235b0ad 100644 --- a/db/migrate/20210125123000_remove_enable_mail_delivery_preference.rb +++ b/db/migrate/20210125123000_remove_enable_mail_delivery_preference.rb @@ -1,4 +1,4 @@ -class RemoveEnableMailDeliveryPreference < ActiveRecord::Migration +class RemoveEnableMailDeliveryPreference < ActiveRecord::Migration[4.2] def up Spree::Preference.delete_all("key ilike '%enable_mail_delivery%'") end diff --git a/db/migrate/20210125171611_populate_order_tax_totals.rb b/db/migrate/20210125171611_populate_order_tax_totals.rb index b466eca11c..47b206f622 100644 --- a/db/migrate/20210125171611_populate_order_tax_totals.rb +++ b/db/migrate/20210125171611_populate_order_tax_totals.rb @@ -1,4 +1,4 @@ -class PopulateOrderTaxTotals < ActiveRecord::Migration +class PopulateOrderTaxTotals < ActiveRecord::Migration[4.2] def up # Updates new order tax total fields (additional_tax_total and included_tax_total). # Sums the relevant values from associated adjustments and updates the two columns. diff --git a/db/migrate/20210127174120_add_cascading_deletes.rb b/db/migrate/20210127174120_add_cascading_deletes.rb index 3babe886b0..62692b7546 100644 --- a/db/migrate/20210127174120_add_cascading_deletes.rb +++ b/db/migrate/20210127174120_add_cascading_deletes.rb @@ -1,4 +1,4 @@ -class AddCascadingDeletes < ActiveRecord::Migration +class AddCascadingDeletes < ActiveRecord::Migration[4.2] def change # Updates foreign key definitions between orders, shipments, and inventory_units # to allow for cascading deletes at database level. If an order is intentionally diff --git a/db/migrate/20210130135946_increase_precion_on_currency_fields.rb b/db/migrate/20210130135946_increase_precion_on_currency_fields.rb index c2c43531fa..7738f88d60 100644 --- a/db/migrate/20210130135946_increase_precion_on_currency_fields.rb +++ b/db/migrate/20210130135946_increase_precion_on_currency_fields.rb @@ -1,4 +1,4 @@ -class IncreasePrecionOnCurrencyFields < ActiveRecord::Migration +class IncreasePrecionOnCurrencyFields < ActiveRecord::Migration[4.2] def up change_column :spree_line_items, :price, :decimal, precision: 10, scale: 2 change_column :spree_line_items, :cost_price, :decimal, precision: 10, scale: 2 diff --git a/db/migrate/20210203214304_rename_migs_payment_methods_to_check.rb b/db/migrate/20210203214304_rename_migs_payment_methods_to_check.rb index bec8eca69b..0db3dd58d3 100644 --- a/db/migrate/20210203214304_rename_migs_payment_methods_to_check.rb +++ b/db/migrate/20210203214304_rename_migs_payment_methods_to_check.rb @@ -1,4 +1,4 @@ -class RenameMigsPaymentMethodsToCheck < ActiveRecord::Migration +class RenameMigsPaymentMethodsToCheck < ActiveRecord::Migration[4.2] def change Spree::PaymentMethod .where(type: "Spree::Gateway::Migs") diff --git a/db/migrate/20210203215049_rename_pin_payment_methods_to_check.rb b/db/migrate/20210203215049_rename_pin_payment_methods_to_check.rb index bde3427d16..e4c78659a0 100644 --- a/db/migrate/20210203215049_rename_pin_payment_methods_to_check.rb +++ b/db/migrate/20210203215049_rename_pin_payment_methods_to_check.rb @@ -1,4 +1,4 @@ -class RenamePinPaymentMethodsToCheck < ActiveRecord::Migration +class RenamePinPaymentMethodsToCheck < ActiveRecord::Migration[4.2] def change Spree::PaymentMethod .where(type: "Spree::Gateway::Pin") diff --git a/db/migrate/20210207120753_add_tax_category_id_to_shipping_methods.rb b/db/migrate/20210207120753_add_tax_category_id_to_shipping_methods.rb new file mode 100644 index 0000000000..cf2db90754 --- /dev/null +++ b/db/migrate/20210207120753_add_tax_category_id_to_shipping_methods.rb @@ -0,0 +1,5 @@ +class AddTaxCategoryIdToShippingMethods < ActiveRecord::Migration[4.2] + def change + add_column :spree_shipping_methods, :tax_category_id, :integer + end +end diff --git a/db/migrate/20210207120825_set_default_shipment_cost.rb b/db/migrate/20210207120825_set_default_shipment_cost.rb index ce45e9d2e5..be71748cb1 100644 --- a/db/migrate/20210207120825_set_default_shipment_cost.rb +++ b/db/migrate/20210207120825_set_default_shipment_cost.rb @@ -1,4 +1,4 @@ -class SetDefaultShipmentCost < ActiveRecord::Migration +class SetDefaultShipmentCost < ActiveRecord::Migration[4.2] def up change_column_null :spree_shipments, :cost, false, 0.0 change_column_default :spree_shipments, :cost, 0.0 diff --git a/db/migrate/20210207131247_add_tax_totals_to_shipment.rb b/db/migrate/20210207131247_add_tax_totals_to_shipment.rb new file mode 100644 index 0000000000..3e8a701159 --- /dev/null +++ b/db/migrate/20210207131247_add_tax_totals_to_shipment.rb @@ -0,0 +1,14 @@ +class AddTaxTotalsToShipment < ActiveRecord::Migration[4.2] + def up + add_column :spree_shipments, :included_tax_total, :decimal, + precision: 10, scale: 2, null: false, default: 0.0 + + add_column :spree_shipments, :additional_tax_total, :decimal, + precision: 10, scale: 2, null: false, default: 0.0 + end + + def down + remove_column :spree_shipments, :included_tax_total + remove_column :spree_shipments, :additional_tax_total + end +end diff --git a/db/migrate/20210207151520_add_adjustment_total_to_shipment.rb b/db/migrate/20210207151520_add_adjustment_total_to_shipment.rb new file mode 100644 index 0000000000..1c4139fbb2 --- /dev/null +++ b/db/migrate/20210207151520_add_adjustment_total_to_shipment.rb @@ -0,0 +1,31 @@ +class AddAdjustmentTotalToShipment < ActiveRecord::Migration[4.2] + def up + add_column :spree_shipments, :adjustment_total, :decimal, + precision: 10, scale: 2, null: false, default: 0.0 + + populate_adjustment_totals + end + + def down + remove_column :spree_shipments, :adjustment_total + end + + def populate_adjustment_totals + # Populates the new `adjustment_total` field in the spree_shipments table. Sets the value + # to the shipment's (shipping fee) adjustment amount. + + adjustment_totals_sql = <<-SQL + UPDATE spree_shipments + SET adjustment_total = shipping_adjustment.fee_amount + FROM ( + SELECT spree_adjustments.source_id AS shipment_id, spree_adjustments.amount AS fee_amount + FROM spree_adjustments + WHERE spree_adjustments.source_type = 'Spree::Shipment' + AND spree_adjustments.amount <> 0 + ) shipping_adjustment + WHERE spree_shipments.id = shipping_adjustment.shipment_id + SQL + + ActiveRecord::Base.connection.execute(adjustment_totals_sql) + end +end diff --git a/db/migrate/20210211115125_migrate_shipment_fees_to_shipments.rb b/db/migrate/20210211115125_migrate_shipment_fees_to_shipments.rb index 46c4f9e55c..4172cd9d93 100644 --- a/db/migrate/20210211115125_migrate_shipment_fees_to_shipments.rb +++ b/db/migrate/20210211115125_migrate_shipment_fees_to_shipments.rb @@ -1,4 +1,4 @@ -class MigrateShipmentFeesToShipments < ActiveRecord::Migration +class MigrateShipmentFeesToShipments < ActiveRecord::Migration[4.2] class Spree::Adjustment < ActiveRecord::Base belongs_to :originator, polymorphic: true end diff --git a/db/migrate/20210216203057_remove_cost_price_from_variant_and_line_item.rb b/db/migrate/20210216203057_remove_cost_price_from_variant_and_line_item.rb index 5c9af2937c..444087ef7e 100644 --- a/db/migrate/20210216203057_remove_cost_price_from_variant_and_line_item.rb +++ b/db/migrate/20210216203057_remove_cost_price_from_variant_and_line_item.rb @@ -1,4 +1,4 @@ -class RemoveCostPriceFromVariantAndLineItem < ActiveRecord::Migration +class RemoveCostPriceFromVariantAndLineItem < ActiveRecord::Migration[4.2] def up remove_column :spree_variants, :cost_price remove_column :spree_line_items, :cost_price diff --git a/db/migrate/20210224190247_migrate_shipping_taxes.rb b/db/migrate/20210224190247_migrate_shipping_taxes.rb new file mode 100644 index 0000000000..e1d6a34a92 --- /dev/null +++ b/db/migrate/20210224190247_migrate_shipping_taxes.rb @@ -0,0 +1,164 @@ +class MigrateShippingTaxes < ActiveRecord::Migration[4.2] + class Spree::Preference < ActiveRecord::Base; end + class Spree::TaxCategory < ActiveRecord::Base + has_many :tax_rates, class_name: "Spree::TaxRate", inverse_of: :tax_category + end + class Spree::Order < ActiveRecord::Base + has_many :adjustments, as: :adjustable + belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address' + belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address' + + def tax_zone + Spree::Zone.match(tax_address) || Spree::Zone.default_tax + end + + def tax_address + Spree::Config[:tax_using_ship_address] ? ship_address : bill_address + end + end + class Spree::Address < ActiveRecord::Base; end + class Spree::Shipment < ActiveRecord::Base + has_many :adjustments, as: :adjustable + end + class Spree::ShippingMethod < ActiveRecord::Base; end + class Spree::Zone < ActiveRecord::Base + has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember", inverse_of: :zone + has_many :tax_rates, class_name: "Spree::TaxRate", inverse_of: :zone + + def self.match(address) + return unless (matches = includes(:zone_members). + order('zone_members_count', 'created_at'). + select { |zone| zone.include? address }) + + ['state', 'country'].each do |zone_kind| + if (match = matches.detect { |zone| zone_kind == zone.kind }) + return match + end + end + matches.first + end + + def kind + return unless zone_members.any? && zone_members.none? { |member| member.try(:zoneable_type).nil? } + + zone_members.last.zoneable_type.demodulize.underscore + end + + def include?(address) + return false unless address + + zone_members.any? do |zone_member| + case zone_member.zoneable_type + when 'Spree::Country' + zone_member.zoneable_id == address.country_id + when 'Spree::State' + zone_member.zoneable_id == address.state_id + else + false + end + end + end + end + class Spree::ZoneMember < ActiveRecord::Base + belongs_to :zone, class_name: 'Spree::Zone', inverse_of: :zone_members + belongs_to :zoneable, polymorphic: true + end + class Spree::TaxRate < ActiveRecord::Base + belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates + belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates + has_one :calculator, class_name: "Spree::Calculator", as: :calculable, dependent: :destroy + accepts_nested_attributes_for :calculator + end + class Spree::Adjustment < ActiveRecord::Base + belongs_to :adjustable, polymorphic: true + belongs_to :originator, polymorphic: true + belongs_to :source, polymorphic: true + belongs_to :order, class_name: "Spree::Order" + + scope :shipping, -> { where(originator_type: 'Spree::ShippingMethod') } + end + + def up + return unless instance_uses_shipping_tax? + + create_shipping_tax_rates + assign_to_shipping_methods + migrate_tax_amounts_to_adjustments + end + + def instance_uses_shipping_tax? + Spree::Preference.find_by(key: '/spree/app_configuration/shipment_inc_vat')&.value || false + end + + def instance_shipping_tax_rate + Spree::Preference.find_by(key: '/spree/app_configuration/shipping_tax_rate')&.value || 0.0 + end + + def shipping_tax_category + @shipping_tax_category ||= Spree::TaxCategory.create(name: I18n.t(:shipping)) + end + + def create_shipping_tax_rates + # Create a shipping tax rate for each zone, set to current default rate + Spree::Zone.all.each do |tax_zone| + Spree::TaxRate.create!( + name: shipping_rate_label(tax_zone), + zone: tax_zone, + tax_category: shipping_tax_category, + amount: instance_shipping_tax_rate, + included_in_price: true, + calculator: Calculator::DefaultTax.new + ) + end + end + + def assign_to_shipping_methods + # Assign the new default shipping tax category to all existing shipping methods + Spree::ShippingMethod.update_all(tax_category_id: shipping_tax_category.id) + end + + def migrate_tax_amounts_to_adjustments + shipping_tax_rates = Spree::TaxRate.where(tax_category: shipping_tax_category).to_a + + # Migrate all shipping tax amounts from shipment field to tax adjustments + Spree::Adjustment.shipping.where("included_tax <> 0").includes(:source, :order).find_each do |shipping_fee| + shipment = shipping_fee.source + order = shipping_fee.order + next if order.nil? + + tax_rate = shipping_tax_rates.detect{ |rate| rate.zone == order.tax_zone } + + # Move all tax totals to adjustments + Spree::Adjustment.create!( + label: tax_adjustment_label(tax_rate), + amount: shipping_fee.included_tax, + included: true, + order_id: order.id, + state: "closed", + adjustable_type: "Spree::Shipment", + adjustable_id: shipment.id, + source_type: "Spree::Shipment", + source_id: shipment.id, + originator_type: "Spree::TaxRate", + originator_id: tax_rate.id + ) + + # Update shipment included tax total + shipment.update_columns( + included_tax_total: shipping_fee.included_tax + ) + end + end + + def shipping_rate_label(zone) + I18n.t(:shipping) + " - #{zone.name.chomp('_VAT')}" + end + + def tax_adjustment_label(tax_rate) + label = "" + label << tax_rate.name + label << " #{tax_rate.amount * 100}%" + label << " (#{I18n.t('models.tax_rate.included_in_price')})" + label + end +end diff --git a/db/migrate/20210227144926_migrate_payment_fees_to_payments.rb b/db/migrate/20210227144926_migrate_payment_fees_to_payments.rb new file mode 100644 index 0000000000..86b1a7857c --- /dev/null +++ b/db/migrate/20210227144926_migrate_payment_fees_to_payments.rb @@ -0,0 +1,22 @@ +class MigratePaymentFeesToPayments < ActiveRecord::Migration[4.2] + class Spree::Adjustment < ActiveRecord::Base + belongs_to :originator, polymorphic: true + end + + def up + # Payment fee adjustments currently have the order as the `adjustable` and the payment as + # the `source`. Both `source` and `adjustable` will now be the payment. The `originator` is + # the payment method, and this is unchanged. + Spree::Adjustment.where(originator_type: 'Spree::PaymentMethod').update_all( + "adjustable_id = source_id, adjustable_type = 'Spree::Payment'" + ) + end + + def down + # Just in case: reversing this migration requires setting the `adjustable` back to the order. + # The type is 'Spree::Order', and the order's id is still available on the `order_id` field. + Spree::Adjustment.where(originator_type: 'Spree::PaymentMethod').update_all( + "adjustable_id = order_id, adjustable_type = 'Spree::Order'" + ) + end +end diff --git a/db/migrate/20210228223114_migrate_line_item_fees.rb b/db/migrate/20210228223114_migrate_line_item_fees.rb new file mode 100644 index 0000000000..f7e0a0bcf7 --- /dev/null +++ b/db/migrate/20210228223114_migrate_line_item_fees.rb @@ -0,0 +1,22 @@ +class MigrateLineItemFees < ActiveRecord::Migration[4.2] + class Spree::Adjustment < ActiveRecord::Base + belongs_to :originator, polymorphic: true + belongs_to :source, polymorphic: true + end + + def up + Spree::Adjustment. + where(originator_type: 'EnterpriseFee', source_type: 'Spree::LineItem'). + update_all( + "adjustable_id = source_id, adjustable_type = 'Spree::LineItem'" + ) + end + + def down + Spree::Adjustment. + where(originator_type: 'EnterpriseFee', source_type: 'Spree::LineItem'). + update_all( + "adjustable_id = order_id, adjustable_type = 'Spree::Order'" + ) + end +end diff --git a/db/migrate/20210319155627_update_return_adjustments.rb b/db/migrate/20210319155627_update_return_adjustments.rb new file mode 100644 index 0000000000..cd6a9788c6 --- /dev/null +++ b/db/migrate/20210319155627_update_return_adjustments.rb @@ -0,0 +1,17 @@ +class UpdateReturnAdjustments < ActiveRecord::Migration[5.0] + class Spree::Adjustment < ActiveRecord::Base + belongs_to :source, polymorphic: true + end + + def up + Spree::Adjustment.where(source_type: 'Spree::ReturnAuthorization').update_all( + "originator_id = source_id, originator_type = 'Spree::ReturnAuthorization', source_id = NULL, source_type = NULL" + ) + end + + def down + Spree::Adjustment.where(originator_type: 'Spree::ReturnAuthorization').update_all( + "source_id = originator_id, source_type = 'Spree::ReturnAuthorization', originator_id = NULL, originator_type = NULL" + ) + end +end diff --git a/db/migrate/20210320003951_update_adjustments_indexes.rb b/db/migrate/20210320003951_update_adjustments_indexes.rb new file mode 100644 index 0000000000..4828b48399 --- /dev/null +++ b/db/migrate/20210320003951_update_adjustments_indexes.rb @@ -0,0 +1,8 @@ +class UpdateAdjustmentsIndexes < ActiveRecord::Migration[5.0] + def change + remove_index :spree_adjustments, :adjustable_id + + add_index :spree_adjustments, [:adjustable_type, :adjustable_id] + add_index :spree_adjustments, [:originator_type, :originator_id] + end +end diff --git a/db/migrate/20210326094519_create_flipper_tables.rb b/db/migrate/20210326094519_create_flipper_tables.rb new file mode 100644 index 0000000000..e7b94de750 --- /dev/null +++ b/db/migrate/20210326094519_create_flipper_tables.rb @@ -0,0 +1,22 @@ +class CreateFlipperTables < ActiveRecord::Migration[5.0] + def self.up + create_table :flipper_features do |t| + t.string :key, null: false + t.timestamps null: false + end + add_index :flipper_features, :key, unique: true + + create_table :flipper_gates do |t| + t.string :feature_key, null: false + t.string :key, null: false + t.string :value + t.timestamps null: false + end + add_index :flipper_gates, [:feature_key, :key, :value], unique: true + end + + def self.down + drop_table :flipper_gates + drop_table :flipper_features + end +end diff --git a/db/migrate/20210329123820_add_index_on_shipping_methods_tax_category.rb b/db/migrate/20210329123820_add_index_on_shipping_methods_tax_category.rb new file mode 100644 index 0000000000..dcc1103fdc --- /dev/null +++ b/db/migrate/20210329123820_add_index_on_shipping_methods_tax_category.rb @@ -0,0 +1,5 @@ +class AddIndexOnShippingMethodsTaxCategory < ActiveRecord::Migration[5.0] + def change + add_index :spree_shipping_methods, :tax_category_id + end +end diff --git a/db/migrate/20210407170804_add_deleted_at_to_return_authorizations.rb b/db/migrate/20210407170804_add_deleted_at_to_return_authorizations.rb new file mode 100644 index 0000000000..72b4f872b5 --- /dev/null +++ b/db/migrate/20210407170804_add_deleted_at_to_return_authorizations.rb @@ -0,0 +1,5 @@ +class AddDeletedAtToReturnAuthorizations < ActiveRecord::Migration[5.0] + def change + add_column :spree_return_authorizations, :deleted_at, :datetime + end +end diff --git a/db/migrate/20210414171109_add_unit_value_constraint.rb b/db/migrate/20210414171109_add_unit_value_constraint.rb new file mode 100644 index 0000000000..ac34a8d15a --- /dev/null +++ b/db/migrate/20210414171109_add_unit_value_constraint.rb @@ -0,0 +1,10 @@ +class AddUnitValueConstraint < ActiveRecord::Migration[5.0] + def up + execute "UPDATE spree_variants SET unit_value = 1 WHERE unit_value <= 0" + execute "ALTER TABLE spree_variants ADD CONSTRAINT positive_unit_value CHECK (unit_value > 0)" + end + + def down + execute "ALTER TABLE spree_variants DROP CONSTRAINT positive_unit_value" + end +end diff --git a/db/schema.rb b/db/schema.rb index ddd564122b..db58a7a083 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20210315163900) do +ActiveRecord::Schema.define(version: 20210414171109) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -250,6 +250,22 @@ ActiveRecord::Schema.define(version: 20210315163900) do t.index ["sender_id"], name: "index_exchanges_on_sender_id", using: :btree end + create_table "flipper_features", force: :cascade do |t| + t.string "key", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_flipper_features_on_key", unique: true, using: :btree + end + + create_table "flipper_gates", force: :cascade do |t| + t.string "feature_key", null: false + t.string "key", null: false + t.string "value" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true, using: :btree + end + create_table "inventory_items", force: :cascade do |t| t.integer "enterprise_id", null: false t.integer "variant_id", null: false @@ -372,8 +388,9 @@ ActiveRecord::Schema.define(version: 20210315163900) do t.string "state", limit: 255 t.integer "order_id" t.boolean "included", default: false - t.index ["adjustable_id"], name: "index_adjustments_on_order_id", using: :btree + t.index ["adjustable_type", "adjustable_id"], name: "index_spree_adjustments_on_adjustable_type_and_adjustable_id", using: :btree t.index ["order_id"], name: "index_spree_adjustments_on_order_id", using: :btree + t.index ["originator_type", "originator_id"], name: "index_spree_adjustments_on_originator_type_and_originator_id", using: :btree end create_table "spree_assets", force: :cascade do |t| @@ -468,14 +485,14 @@ ActiveRecord::Schema.define(version: 20210315163900) do create_table "spree_line_items", force: :cascade do |t| t.integer "order_id" t.integer "variant_id" - t.integer "quantity", null: false - t.decimal "price", precision: 10, scale: 2, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "quantity", null: false + t.decimal "price", precision: 10, scale: 2, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "max_quantity" - t.string "currency", limit: 255 - t.decimal "distribution_fee", precision: 10, scale: 2 - t.decimal "final_weight_volume", precision: 10, scale: 2 + t.string "currency", limit: 255 + t.decimal "distribution_fee", precision: 10, scale: 2 + t.decimal "final_weight_volume", precision: 10, scale: 2 t.integer "tax_category_id" t.index ["order_id"], name: "index_line_items_on_order_id", using: :btree t.index ["variant_id"], name: "index_line_items_on_variant_id", using: :btree @@ -753,6 +770,7 @@ ActiveRecord::Schema.define(version: 20210315163900) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "stock_location_id" + t.datetime "deleted_at" end create_table "spree_roles", force: :cascade do |t| @@ -767,16 +785,19 @@ ActiveRecord::Schema.define(version: 20210315163900) do end create_table "spree_shipments", force: :cascade do |t| - t.string "tracking", limit: 255 - t.string "number", limit: 255 - t.decimal "cost", precision: 10, scale: 2, default: "0.0", null: false + t.string "tracking", limit: 255 + t.string "number", limit: 255 + t.decimal "cost", precision: 10, scale: 2, default: "0.0", null: false t.datetime "shipped_at" t.integer "order_id" t.integer "address_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "state", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "state", limit: 255 t.integer "stock_location_id" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0", null: false t.index ["number"], name: "index_shipments_on_number", using: :btree t.index ["order_id"], name: "index_spree_shipments_on_order_id", unique: true, using: :btree end @@ -806,6 +827,8 @@ ActiveRecord::Schema.define(version: 20210315163900) do t.boolean "require_ship_address", default: true t.text "description" t.string "tracking_url", limit: 255 + t.integer "tax_category_id" + t.index ["tax_category_id"], name: "index_spree_shipping_methods_on_tax_category_id", using: :btree end create_table "spree_shipping_methods_zones", id: false, force: :cascade do |t| diff --git a/engines/order_management/app/services/order_management/order/updater.rb b/engines/order_management/app/services/order_management/order/updater.rb index 4aac1f7843..e1bd346619 100644 --- a/engines/order_management/app/services/order_management/order/updater.rb +++ b/engines/order_management/app/services/order_management/order/updater.rb @@ -61,7 +61,7 @@ module OrderManagement order.additional_tax_total = all_adjustments.tax.additional.sum(:amount) order.included_tax_total = order.line_item_adjustments.tax.inclusive.sum(:amount) + all_adjustments.enterprise_fee.sum(:included_tax) + - all_adjustments.shipping.sum(:included_tax) + + order.shipment_adjustments.tax.inclusive.sum(:amount) + adjustments.admin.sum(:included_tax) end @@ -122,7 +122,7 @@ module OrderManagement end def update_all_adjustments - order.adjustments.reload.each(&:update!) + order.all_adjustments.reload.each(&:update!) end def before_save_hook @@ -157,8 +157,7 @@ module OrderManagement def infer_payment_state_from_balance # This part added so that we don't need to override # order.outstanding_balance - balance = order.outstanding_balance - balance = -1 * order.payment_total if canceled_and_paid_for? + balance = order.new_outstanding_balance infer_state(balance) end @@ -184,20 +183,10 @@ module OrderManagement order.state_changed('payment') end - # Taken from order.outstanding_balance in Spree 2.4 - # See: https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a - def canceled_and_paid_for? - order.canceled? && paid? - end - def canceled_and_not_paid_for? order.state == 'canceled' && order.payment_total.zero? end - def paid? - payments.present? && !payments.completed.empty? - end - def failed_payments? payments.present? && payments.valid.empty? end diff --git a/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb b/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb index 1f658b189a..9b34c4a0fc 100644 --- a/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb +++ b/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb @@ -168,11 +168,7 @@ module OrderManagement end def customer_payments_amount_owed(line_items) - if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, @user) - unique_orders(line_items).sum(&:new_outstanding_balance) - else - unique_orders(line_items).sum(&:outstanding_balance) - end + unique_orders(line_items).sum(&:new_outstanding_balance) end def customer_payments_amount_paid(line_items) diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb index eafbdbbad6..78da81e503 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb @@ -52,7 +52,9 @@ module OrderManagement def for_orders chain_to_scope do - where(adjustable_type: ["Spree::Order", "Spree::Shipment"]) + where( + adjustable_type: ["Spree::Order", "Spree::Shipment", "Spree::LineItem", "Spree::Payment"] + ) end end @@ -179,8 +181,8 @@ module OrderManagement <<-JOIN_STRING.strip_heredoc LEFT OUTER JOIN spree_orders AS adjustment_source_orders ON ( - spree_adjustments.source_type = 'Spree::Order' - AND adjustment_source_orders.id = spree_adjustments.source_id + spree_adjustments.adjustable_type = 'Spree::Order' + AND adjustment_source_orders.id = spree_adjustments.adjustable_id ) JOIN_STRING ) @@ -205,8 +207,8 @@ module OrderManagement <<-JOIN_STRING.strip_heredoc LEFT OUTER JOIN spree_line_items ON ( - spree_adjustments.source_type = 'Spree::LineItem' - AND spree_line_items.id = spree_adjustments.source_id + spree_adjustments.adjustable_type = 'Spree::LineItem' + AND spree_line_items.id = spree_adjustments.adjustable_id ) JOIN_STRING ) @@ -215,7 +217,7 @@ module OrderManagement <<-JOIN_STRING.strip_heredoc LEFT OUTER JOIN spree_variants ON ( - spree_adjustments.source_type = 'Spree::LineItem' + spree_adjustments.adjustable_type = 'Spree::LineItem' AND spree_variants.id = spree_line_items.variant_id ) JOIN_STRING @@ -258,7 +260,7 @@ module OrderManagement ) ) ON ( - spree_adjustments.source_type = 'Spree::LineItem' + spree_adjustments.adjustable_type = 'Spree::LineItem' AND adjustment_metadata.enterprise_role = 'supplier' AND incoming_exchanges.order_cycle_id = spree_orders.order_cycle_id AND incoming_exchange_variants.id IS NOT NULL @@ -294,7 +296,7 @@ module OrderManagement ) ) ON ( - spree_adjustments.source_type = 'Spree::LineItem' + spree_adjustments.adjustable_type = 'Spree::LineItem' AND adjustment_metadata.enterprise_role = 'distributor' AND outgoing_exchanges.order_cycle_id = spree_orders.order_cycle_id AND outgoing_exchange_variants.id IS NOT NULL @@ -351,7 +353,7 @@ module OrderManagement "adjustment_metadata.enterprise_role", "spree_tax_categories.id", "product_tax_categories.id", - "spree_adjustments.source_type", + "spree_adjustments.adjustable_type", "adjustment_source_distributors.id", "incoming_exchange_enterprises.id", "outgoing_exchange_enterprises.id" @@ -376,7 +378,7 @@ module OrderManagement enterprise_fees.inherits_tax_category AS enterprise_fee_inherits_tax_category, product_tax_categories.name AS product_tax_category_name, adjustment_metadata.enterprise_role AS placement_enterprise_role, - spree_adjustments.source_type AS adjustment_source_type, + spree_adjustments.adjustable_type AS adjustment_adjustable_type, adjustment_source_distributors.name AS adjustment_source_distributor_name, incoming_exchange_enterprises.name AS incoming_exchange_enterprise_name, outgoing_exchange_enterprises.name AS outgoing_exchange_enterprise_name diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb index a58b549490..554c11999e 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb @@ -65,11 +65,11 @@ module OrderManagement end def for_order_adjustment_source? - data["adjustment_source_type"] == "Spree::Order" + data["adjustment_adjustable_type"] == "Spree::Order" end def for_line_item_adjustment_source? - data["adjustment_source_type"] == "Spree::LineItem" + data["adjustment_adjustable_type"] == "Spree::LineItem" end end end diff --git a/engines/order_management/app/services/order_management/subscriptions/summarizer.rb b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb index 86c7deadea..32c925fc03 100644 --- a/engines/order_management/app/services/order_management/subscriptions/summarizer.rb +++ b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb @@ -22,6 +22,10 @@ module OrderManagement summary_for(order).record_issue(type, order, message) end + def record_subscription_issue(subscription) + summary_for_shop_id(subscription.shop_id).record_subscription_issue(subscription) + end + def record_and_log_error(type, order, error_message = nil) return record_issue(type, order) unless order.errors.any? @@ -51,10 +55,13 @@ module OrderManagement private - def summary_for(order) - shop_id = order.distributor_id + def summary_for_shop_id(shop_id) @summaries[shop_id] ||= Summary.new(shop_id) end + + def summary_for(order) + summary_for_shop_id(order.distributor_id) + end end end end diff --git a/engines/order_management/app/services/order_management/subscriptions/summary.rb b/engines/order_management/app/services/order_management/subscriptions/summary.rb index c37272c6d3..e16b116bf8 100644 --- a/engines/order_management/app/services/order_management/subscriptions/summary.rb +++ b/engines/order_management/app/services/order_management/subscriptions/summary.rb @@ -3,13 +3,14 @@ module OrderManagement module Subscriptions class Summary - attr_reader :shop_id, :issues + attr_reader :shop_id, :issues, :subscription_issues def initialize(shop_id) @shop_id = shop_id @order_ids = [] @success_ids = [] @issues = {} + @subscription_issues = [] end def record_order(order) @@ -25,6 +26,10 @@ module OrderManagement issues[type][order.id] = message end + def record_subscription_issue(subscription) + @subscription_issues << subscription.id + end + def order_count @order_ids.count end @@ -34,7 +39,7 @@ module OrderManagement end def issue_count - (@order_ids - @success_ids).count + (@order_ids - @success_ids).count + @subscription_issues.count end def orders_affected_by(type) diff --git a/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb b/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb index 62181aebaf..781107795c 100644 --- a/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb +++ b/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb @@ -6,9 +6,9 @@ feature "bulk coop" do include AuthenticationHelper include WebHelper - scenario "generating Bulk Coop Supplier Report" do + scenario "generating Bulk Co-op Supplier Report" do login_as_admin_and_visit new_order_management_reports_bulk_coop_path - select "Bulk Coop Supplier Report", from: "report_report_type" + select "Bulk Co-op Supplier Report", from: "report_report_type" click_button 'Generate Report' expect(page).to have_table_row [ @@ -28,7 +28,7 @@ feature "bulk coop" do scenario "generating Bulk Co-op Allocation report" do login_as_admin_and_visit new_order_management_reports_bulk_coop_path - select "Bulk Coop Allocation", from: "report_report_type" + select "Bulk Co-op Allocation", from: "report_report_type" click_button 'Generate Report' expect(page).to have_table_row [ @@ -48,7 +48,7 @@ feature "bulk coop" do scenario "generating Bulk Co-op Packing Sheets report" do login_as_admin_and_visit new_order_management_reports_bulk_coop_path - select "Bulk Coop Packing Sheets", from: "report_report_type" + select "Bulk Co-op Packing Sheets", from: "report_report_type" click_button 'Generate Report' expect(page).to have_table_row [ @@ -61,7 +61,7 @@ feature "bulk coop" do scenario "generating Bulk Co-op Customer Payments report" do login_as_admin_and_visit new_order_management_reports_bulk_coop_path - select "Bulk Coop Customer Payments", from: "report_report_type" + select "Bulk Co-op Customer Payments", from: "report_report_type" click_button 'Generate Report' expect(page).to have_table_row [ diff --git a/engines/order_management/spec/services/order_management/order/updater_spec.rb b/engines/order_management/spec/services/order_management/order/updater_spec.rb index 47a92a520c..f85ccfa176 100644 --- a/engines/order_management/spec/services/order_management/order/updater_spec.rb +++ b/engines/order_management/spec/services/order_management/order/updater_spec.rb @@ -32,6 +32,7 @@ module OrderManagement allow(order).to receive_message_chain(:all_adjustments, :tax, :additional, :sum).and_return(20) allow(order).to receive_message_chain(:all_adjustments, :enterprise_fee, :sum).and_return(10) allow(order).to receive_message_chain(:all_adjustments, :shipping, :sum).and_return(5) + allow(order).to receive_message_chain(:shipment_adjustments, :tax, :inclusive, :sum).and_return(5) allow(order).to receive_message_chain(:adjustments, :admin, :sum).and_return(2) updater.update_adjustment_total diff --git a/engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb b/engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb index f667c8fdc6..8fdfc4e2d8 100644 --- a/engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb +++ b/engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb @@ -176,28 +176,9 @@ describe OrderManagement::Reports::BulkCoop::BulkCoopReport do let!(:line_item) { create(:line_item) } let(:order) { line_item.order } - context 'when the customer_balance feature is enabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } - end - - it 'calls #new_outstanding_balance' do - expect_any_instance_of(Spree::Order).to receive(:new_outstanding_balance) - subject.send(:customer_payments_amount_owed, [line_item]) - end - end - - context 'when the customer_balance feature is disabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { false } - end - - it 'calls #outstanding_balance' do - expect_any_instance_of(Spree::Order).to receive(:outstanding_balance) - subject.send(:customer_payments_amount_owed, [line_item]) - end + it 'calls #new_outstanding_balance' do + expect_any_instance_of(Spree::Order).to receive(:new_outstanding_balance) + subject.send(:customer_payments_amount_owed, [line_item]) end end end diff --git a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb index 32bf3874d0..b0bf259c41 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb @@ -9,7 +9,7 @@ module OrderManagement let(:payment_setup) { OrderManagement::Subscriptions::PaymentSetup.new(order) } describe "#call!" do - let!(:payment){ create(:payment, amount: 10) } + let!(:payment) { create(:payment, amount: 10) } context "when no pending payments are present" do let(:payment_method) { create(:payment_method) } @@ -17,7 +17,7 @@ module OrderManagement before do allow(order).to receive(:pending_payments).once { [] } - allow(order).to receive(:outstanding_balance) { 5 } + allow(order).to receive(:new_outstanding_balance) { 5 } allow(order).to receive(:subscription) { subscription } end @@ -31,14 +31,15 @@ module OrderManagement before { allow(order).to receive(:pending_payments).once { [payment] } } context "when the payment total doesn't match the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 5 } } + before { allow(order).to receive(:new_outstanding_balance) { 5 } } + it "updates the payment total to reflect the outstanding balance" do expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) end end context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } + before { allow(order).to receive(:new_outstanding_balance) { 10 } } it "does nothing" do expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) @@ -51,7 +52,7 @@ module OrderManagement let!(:payment2) { create(:payment, order: order) } before do - allow(order).to receive(:outstanding_balance) { 7 } + allow(order).to receive(:new_outstanding_balance) { 7 } allow(order).to receive(:pending_payments).once { [payment1, payment2] } end diff --git a/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb index 0c47277e47..8333eda906 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb @@ -94,6 +94,20 @@ module OrderManagement end end end + + describe "#record_subscription_issue" do + let(:subscription) { double(:subscription, shop_id: 1) } + + before do + allow(summarizer).to receive(:summary_for_shop_id). + with(subscription.shop_id) { summary } + end + + it "records a subscription issue" do + expect(summary).to receive(:record_subscription_issue).with(subscription).once + summarizer.record_subscription_issue(subscription) + end + end end describe "#send_placement_summary_emails" do diff --git a/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb index 454e2e5ba3..dcfd214008 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb @@ -56,6 +56,15 @@ module OrderManagement end end + describe "record_subscription_issue" do + let(:subscription) { double(:subscription, id: 101) } + + it "stores a new subscription issue" do + summary.record_subscription_issue(subscription) + expect(summary.subscription_issues).to eq [101] + end + end + describe "#order_count" do let(:order_ids) { [1, 2, 3, 4, 5, 6, 7] } it "counts the number of items in the order_ids instance_variable" do @@ -81,6 +90,21 @@ module OrderManagement summary.instance_variable_set(:@success_ids, success_ids) expect(summary.issue_count).to be 2 # 7 & 9 end + + context "when there are also subscription issues" do + let(:subscription) { double(:subscription, id: 101) } + let(:order) { double(:order, id: 1) } + + before do + summary.record_order(order) + summary.record_success(order) + summary.record_subscription_issue(subscription) + end + + it "includes subscription issues in the count" do + expect(summary.issue_count).to eq 1 + end + end end describe "#orders_affected_by" do diff --git a/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee b/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee index a35951943a..b9ee459a78 100644 --- a/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee +++ b/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee @@ -1,6 +1,6 @@ Darkswarm.controller "CookiesBannerCtrl", ($scope, CookiesBannerService, $http, $window)-> $scope.acceptCookies = -> - $http.post('/api/cookies/consent') + $http.post('/api/v0/cookies/consent') CookiesBannerService.close() CookiesBannerService.disable() diff --git a/engines/web/app/controllers/web/api/cookies_consent_controller.rb b/engines/web/app/controllers/web/api/cookies_consent_controller.rb deleted file mode 100644 index e0ea13bafe..0000000000 --- a/engines/web/app/controllers/web/api/cookies_consent_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -require_dependency 'web/cookies_consent' - -module Web - module Api - class CookiesConsentController < BaseController - include ActionController::Cookies - respond_to :json - - def show - render json: { cookies_consent: cookies_consent.exists? } - end - - def create - cookies_consent.set - show - end - - def destroy - cookies_consent.destroy - show - end - - private - - def cookies_consent - @cookies_consent ||= Web::CookiesConsent.new(cookies, request.host) - end - end - end -end diff --git a/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb b/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb new file mode 100644 index 0000000000..606ad3e237 --- /dev/null +++ b/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_dependency 'web/cookies_consent' + +module Web + module Api + module V0 + class CookiesConsentController < BaseController + include ActionController::Cookies + respond_to :json + + def show + render json: { cookies_consent: cookies_consent.exists? } + end + + def create + cookies_consent.set + show + end + + def destroy + cookies_consent.destroy + show + end + + private + + def cookies_consent + @cookies_consent ||= Web::CookiesConsent.new(cookies, request.host) + end + end + end + end +end diff --git a/engines/web/config/routes.rb b/engines/web/config/routes.rb index 4b6440e06a..b2a060617a 100644 --- a/engines/web/config/routes.rb +++ b/engines/web/config/routes.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true Openfoodnetwork::Application.routes.append do - scope '/api/cookies' do - resource :consent, only: [:show, :create, :destroy], controller: "web/api/cookies_consent" + scope '/api/v0/cookies' do + resource :consent, only: [:show, :create, :destroy], controller: "web/api/v0/cookies_consent" end get "/angular-templates/:id", to: "web/angular_templates#show", constraints: { name: %r{[\/\w\.]+} } diff --git a/lib/open_food_network/enterprise_fee_applicator.rb b/lib/open_food_network/enterprise_fee_applicator.rb index ab1c96eab1..fe4544c604 100644 --- a/lib/open_food_network/enterprise_fee_applicator.rb +++ b/lib/open_food_network/enterprise_fee_applicator.rb @@ -1,33 +1,23 @@ module OpenFoodNetwork class EnterpriseFeeApplicator < Struct.new(:enterprise_fee, :variant, :role) def create_line_item_adjustment(line_item) - create_adjustment(line_item_adjustment_label, line_item.order, line_item) + create_adjustment(line_item_adjustment_label, line_item) end def create_order_adjustment(order) - create_adjustment(order_adjustment_label, order, order) + create_adjustment(order_adjustment_label, order) end private - def create_adjustment(label, target, calculable) - adjustment = create_enterprise_fee_adjustment(label, target, calculable) + def create_adjustment(label, adjustable) + adjustment = enterprise_fee.create_adjustment(label, adjustable, true) AdjustmentMetadata.create! adjustment: adjustment, enterprise: enterprise_fee.enterprise, fee_name: enterprise_fee.name, fee_type: enterprise_fee.fee_type, enterprise_role: role adjustment.set_absolute_included_tax! adjustment_tax(adjustment) end - def create_enterprise_fee_adjustment(label, target, calculable) - adjustment = enterprise_fee.create_adjustment(label, target, calculable, true) - - # This is necessary when source is a line_item - # probably because the association order.adjustments contains "inverse_of :source" - # which overrides the value (the line item) set in calculated_adjustment.create_adjustment - adjustment.source = calculable - adjustment - end - def line_item_adjustment_label "#{variant.product.name} - #{base_adjustment_label}" end diff --git a/lib/open_food_network/feature_toggle.rb b/lib/open_food_network/feature_toggle.rb index f57e740bc4..2863ef4cee 100644 --- a/lib/open_food_network/feature_toggle.rb +++ b/lib/open_food_network/feature_toggle.rb @@ -25,44 +25,22 @@ module OpenFoodNetwork # - if feature? :new_shiny_feature, spree_current_user # = render "new_shiny_feature" # - class FeatureToggle + module FeatureToggle def self.enabled?(feature_name, user = nil) - new.enabled?(feature_name, user) + features = Thread.current[:features] || {} + + if Flipper[feature_name].exist? + Flipper.enabled?(feature_name, user) + else + feature = features.fetch(feature_name, DefaultFeature.new(feature_name)) + feature.enabled?(user) + end end def self.enable(feature_name, &block) Thread.current[:features] ||= {} Thread.current[:features][feature_name] = Feature.new(block) end - - def initialize - @features = Thread.current[:features] || {} - end - - def enabled?(feature_name, user) - if user.present? - feature = features.fetch(feature_name, NullFeature.new) - feature.enabled?(user) - else - true?(env_variable_value(feature_name)) - end - end - - private - - attr_reader :features - - def env_variable_value(feature_name) - ENV.fetch(env_variable_name(feature_name), nil) - end - - def env_variable_name(feature_name) - "OFN_FEATURE_#{feature_name.to_s.upcase}" - end - - def true?(value) - value.to_s.casecmp("true").zero? - end end class Feature @@ -79,9 +57,29 @@ module OpenFoodNetwork attr_reader :block end - class NullFeature + class DefaultFeature + attr_reader :feature_name + + def initialize(feature_name) + @feature_name = feature_name + end + def enabled?(_user) - false + true?(env_variable_value(feature_name)) + end + + private + + def env_variable_value(feature_name) + ENV.fetch(env_variable_name(feature_name), nil) + end + + def env_variable_name(feature_name) + "OFN_FEATURE_#{feature_name.to_s.upcase}" + end + + def true?(value) + value.to_s.casecmp("true").zero? end end end diff --git a/lib/open_food_network/order_cycle_management_report.rb b/lib/open_food_network/order_cycle_management_report.rb index 2e562c876a..c8b71f242a 100644 --- a/lib/open_food_network/order_cycle_management_report.rb +++ b/lib/open_food_network/order_cycle_management_report.rb @@ -1,4 +1,4 @@ -require 'open_food_network/user_balance_calculator' +# frozen_string_literal: true module OpenFoodNetwork class OrderCycleManagementReport @@ -46,34 +46,21 @@ module OpenFoodNetwork end def search - if FeatureToggle.enabled?(:customer_balance, @user) - Spree::Order. - finalized. - not_state(:canceled). - distributed_by_user(@user). - managed_by(@user). - search(params[:q]) - else - Spree::Order. - complete. - where("spree_orders.state != ?", :canceled). - distributed_by_user(@user). - managed_by(@user). - search(params[:q]) - end + Spree::Order. + finalized. + not_state(:canceled). + distributed_by_user(@user). + managed_by(@user). + search(params[:q]) end def orders - if FeatureToggle.enabled?(:customer_balance, @user) - search_result = search.result.order(:completed_at) - orders_with_balance = OutstandingBalance.new(search_result). - query. - select('spree_orders.*') + search_result = search.result.order(:completed_at) + orders_with_balance = OutstandingBalance.new(search_result). + query. + select('spree_orders.*') - filter(orders_with_balance) - else - filter search.result - end + filter(orders_with_balance) end def table_items @@ -92,12 +79,10 @@ module OpenFoodNetwork private + # This method relies on `balance_value` as a computed DB column. See `CompleteOrdersWithBalance` + # for reference. def balance(order) - if FeatureToggle.enabled?(:customer_balance, @user) - order.balance_value - else - UserBalanceCalculator.new(order.email, order.distributor).balance - end + order.balance_value end def payment_method_row(order) diff --git a/lib/open_food_network/order_cycle_permissions.rb b/lib/open_food_network/order_cycle_permissions.rb index 0e738f7311..2fea3258b0 100644 --- a/lib/open_food_network/order_cycle_permissions.rb +++ b/lib/open_food_network/order_cycle_permissions.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true + +require 'open_food_network/permissions' + module OpenFoodNetwork # Class which is used for determining the permissions around a single order cycle and user # both of which are set at initialization diff --git a/lib/open_food_network/packing_report.rb b/lib/open_food_network/packing_report.rb index 34c1e0e730..8fcc1eb904 100644 --- a/lib/open_food_network/packing_report.rb +++ b/lib/open_food_network/packing_report.rb @@ -53,7 +53,7 @@ module OpenFoodNetwork { group_by: proc { |line_item| line_item.order.distributor }, sort_by: proc { |distributor| distributor.name } }, { group_by: proc { |line_item| line_item.order }, - sort_by: proc { |order| order.bill_address.lastname }, + sort_by: proc { |order| order.bill_address.lastname.downcase }, summary_columns: [proc { |_line_items| "" }, proc { |_line_items| "" }, proc { |_line_items| "" }, @@ -89,7 +89,7 @@ module OpenFoodNetwork { group_by: proc { |line_item| line_item.full_name }, sort_by: proc { |full_name| full_name } }, { group_by: proc { |line_item| line_item.order }, - sort_by: proc { |order| order.bill_address.lastname } }] + sort_by: proc { |order| order.bill_address.lastname.downcase } }] end end diff --git a/lib/open_food_network/payments_report.rb b/lib/open_food_network/payments_report.rb index 4b88603abf..804bb58b45 100644 --- a/lib/open_food_network/payments_report.rb +++ b/lib/open_food_network/payments_report.rb @@ -100,7 +100,7 @@ module OpenFoodNetwork proc { |orders| orders.first.distributor.name }, proc { |orders| orders.to_a.sum(&:item_total) }, proc { |orders| orders.sum(&:ship_total) }, - proc { |orders| orders.sum(&:outstanding_balance) }, + proc { |orders| orders.sum{ |order| order.outstanding_balance.to_f } }, proc { |orders| orders.map(&:total).sum }] when "payment_totals" [proc { |orders| orders.first.payment_state }, @@ -124,7 +124,7 @@ module OpenFoodNetwork }.sum(&:amount) } }, - proc { |orders| orders.sum(&:outstanding_balance) }] + proc { |orders| orders.sum{ |order| order.outstanding_balance.to_f } }] else [proc { |payments| payments.first.order.payment_state }, proc { |payments| payments.first.order.distributor.name }, diff --git a/lib/open_food_network/sales_tax_report.rb b/lib/open_food_network/sales_tax_report.rb index 83bfadd8b6..5d1099e824 100644 --- a/lib/open_food_network/sales_tax_report.rb +++ b/lib/open_food_network/sales_tax_report.rb @@ -70,7 +70,7 @@ module OpenFoodNetwork def relevant_rates return @relevant_rates unless @relevant_rates.nil? - @relevant_rates = Spree::TaxRate.uniq + @relevant_rates = Spree::TaxRate.distinct end def totals_of(line_items) @@ -102,13 +102,5 @@ module OpenFoodNetwork def tax_included_in(line_item) line_item.adjustments.tax.inclusive.sum(:amount) end - - def shipment_inc_vat - Spree::Config.shipment_inc_vat - end - - def shipping_tax_rate - Spree::Config.shipping_tax_rate - end end end diff --git a/lib/open_food_network/user_balance_calculator.rb b/lib/open_food_network/user_balance_calculator.rb deleted file mode 100644 index 98af1600f9..0000000000 --- a/lib/open_food_network/user_balance_calculator.rb +++ /dev/null @@ -1,18 +0,0 @@ -module OpenFoodNetwork - class UserBalanceCalculator - def initialize(email, distributor) - @email = email - @distributor = distributor - end - - def balance - -completed_orders.to_a.sum(&:outstanding_balance) - end - - private - - def completed_orders - Spree::Order.where(distributor_id: @distributor, email: @email).complete.not_state(:canceled) - end - end -end diff --git a/lib/open_food_network/xero_invoices_report.rb b/lib/open_food_network/xero_invoices_report.rb index a7394defd6..fbb6f8fd4f 100644 --- a/lib/open_food_network/xero_invoices_report.rb +++ b/lib/open_food_network/xero_invoices_report.rb @@ -204,7 +204,7 @@ module OpenFoodNetwork end def tax_on_shipping_s(order) - tax_on_shipping = order.all_adjustments.shipping.sum(:included_tax) > 0 + tax_on_shipping = order.shipments.sum("additional_tax_total + included_tax_total").positive? tax_on_shipping ? I18n.t(:report_header_gst_on_income) : I18n.t(:report_header_gst_free_income) end diff --git a/lib/spree/core/calculated_adjustments.rb b/lib/spree/core/calculated_adjustments.rb index 301d821642..690dcb19a7 100644 --- a/lib/spree/core/calculated_adjustments.rb +++ b/lib/spree/core/calculated_adjustments.rb @@ -26,43 +26,29 @@ module Spree # (which is any class that has_many :adjustments) and sets amount based on the # calculator as applied to the given calculable (Order, LineItems[], Shipment, etc.) # By default the adjustment will not be considered mandatory - def create_adjustment(label, target, calculable, mandatory = false, state = "closed") - # Adjustment calculations done on Spree::Shipment objects MUST - # be done on their to_package'd variants instead - # It's only the package that contains the correct information. - # See https://github.com/spree/spree_active_shipping/pull/96 et. al - old_calculable = calculable - calculable = calculable.to_package if calculable.is_a?(Spree::Shipment) - amount = compute_amount(calculable) + def create_adjustment(label, adjustable, mandatory = false, state = "closed") + amount = compute_amount(adjustable) return if amount.zero? && !mandatory - target.adjustments.create( + adjustment_attributes = { amount: amount, - source: old_calculable, originator: self, - order: order_object_for(target), + order: order_object_for(adjustable), label: label, mandatory: mandatory, state: state, - included: tax_included?(self, target) - ) - end + included: tax_included?(self, adjustable) + } - # Updates the amount of the adjustment using our Calculator and - # calling the +compute+ method with the +calculable+ - # referenced passed to the method. - def update_adjustment(adjustment, calculable) - # Adjustment calculations done on Spree::Shipment objects MUST - # be done on their to_package'd variants instead - # It's only the package that contains the correct information. - # See https://github.com/spree/spree_active_shipping/pull/96 et. al - calculable = calculable.to_package if calculable.is_a?(Spree::Shipment) - adjustment.update_column(:amount, compute_amount(calculable)) + if adjustable.respond_to?(:adjustments) + adjustable.adjustments.create(adjustment_attributes) + else + adjustable.create_adjustment(adjustment_attributes) + end end # Calculate the amount to be used when creating an adjustment # NOTE: May be overriden by classes where this module is included into. - # Such as Spree::Promotion::Action::CreateAdjustment. def compute_amount(calculable) calculator.compute(calculable) end diff --git a/lib/spree/core/controller_helpers/order.rb b/lib/spree/core/controller_helpers/order.rb index d3f093cfd2..e0f7423613 100644 --- a/lib/spree/core/controller_helpers/order.rb +++ b/lib/spree/core/controller_helpers/order.rb @@ -52,7 +52,7 @@ module Spree return unless @current_order - @current_order.last_ip_address = ip_address + @current_order.update_columns(last_ip_address: ip_address) session[:order_id] = @current_order.id @current_order end diff --git a/lib/spree/core/delegate_belongs_to.rb b/lib/spree/core/delegate_belongs_to.rb index 6c96134b1e..f2e4fda770 100644 --- a/lib/spree/core/delegate_belongs_to.rb +++ b/lib/spree/core/delegate_belongs_to.rb @@ -90,5 +90,3 @@ module DelegateBelongsTo end protected :delegator_for end - -ActiveRecord::Base.include(DelegateBelongsTo) diff --git a/lib/spree/core/permalinks.rb b/lib/spree/core/permalinks.rb index b9d8a83274..b667de7b2c 100644 --- a/lib/spree/core/permalinks.rb +++ b/lib/spree/core/permalinks.rb @@ -23,14 +23,6 @@ module Spree before_validation(on: :create) { save_permalink } end - def find_by_param(value, *args) - __send__("find_by_#{permalink_field}", value, *args) - end - - def find_by_param!(value, *args) - __send__("find_by_#{permalink_field}!", value, *args) - end - def permalink_field permalink_options[:field] end @@ -70,6 +62,3 @@ module Spree end end end - -ActiveRecord::Base.include(Spree::Core::Permalinks) -ActiveRecord::Relation.include(Spree::Core::Permalinks) diff --git a/lib/spree/localized_number.rb b/lib/spree/localized_number.rb index f67f8ef9c6..c248fd98a1 100644 --- a/lib/spree/localized_number.rb +++ b/lib/spree/localized_number.rb @@ -13,7 +13,7 @@ module Spree attributes.each do |attribute| setter = "#{attribute}=" - old_setter = instance_method(setter) if table_exists? && !column_names.include?(attribute.to_s) + old_setter = instance_method(setter) if non_activerecord_attribute?(attribute) define_method(setter) do |number| if Spree::Config.enable_localized_number? && Spree::LocalizedNumber.valid_localizable_number?(number) @@ -24,8 +24,10 @@ module Spree number = nil end if has_attribute?(attribute) + # In this case it's a regular AR attribute with standard setters self[attribute] = number else + # In this case it's a Spree preference, and the interface is very different old_setter.bind(self).call(number) end end @@ -35,7 +37,7 @@ module Spree return unless Spree::Config.enable_localized_number? @invalid_localized_number.andand.each do |error_attribute| - errors.set(error_attribute, [I18n.t('spree.localized_number.invalid_format')]) + errors.add(error_attribute, I18n.t('spree.localized_number.invalid_format')) end end end @@ -66,5 +68,15 @@ module Spree # If does not end in ,00 / .00 then add trailing 00 to turn it into cents number << "00" unless number =~ /^.*[\.,]\d{2}$/ end + + private + + def non_activerecord_attribute?(attribute) + table_exists? && !column_names.include?(attribute.to_s) + rescue ::ActiveRecord::NoDatabaseError + # This class is now loaded during `rake db:create` (since Rails 5.2), and not only does the + # table not exist, but the database does not even exist yet, and throws a fatal error. + # We can rescue and safely ignore it in that case. + end end end diff --git a/lib/stripe/payment_intent_validator.rb b/lib/stripe/payment_intent_validator.rb index b6d1e52b7a..075e064fcc 100644 --- a/lib/stripe/payment_intent_validator.rb +++ b/lib/stripe/payment_intent_validator.rb @@ -23,9 +23,10 @@ module Stripe end def raise_if_not_in_capture_state(payment_intent_response) - return unless payment_intent_response.status != 'requires_capture' + state = payment_intent_response.status + return unless state != 'requires_capture' - raise Stripe::StripeError, I18n.t(:invalid_payment_state) + raise Stripe::StripeError, I18n.t(:invalid_payment_state, state: state) end end end diff --git a/lib/tasks/data.rake b/lib/tasks/data.rake index 33ac11f020..a8255b96bc 100644 --- a/lib/tasks/data.rake +++ b/lib/tasks/data.rake @@ -41,7 +41,7 @@ namespace :ofn do # For each variant in the exchange products = Spree::Product.joins(:variants_including_master).where('spree_variants.id IN (?)', exchange.variants).pluck(:id).uniq - producers = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).uniq + producers = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).distinct producers.each do |producer| next if producer == exchange.receiver diff --git a/lib/tasks/data/truncate_data.rb b/lib/tasks/data/truncate_data.rb index 3a314fe478..86781b7f14 100644 --- a/lib/tasks/data/truncate_data.rb +++ b/lib/tasks/data/truncate_data.rb @@ -69,17 +69,17 @@ class TruncateData end def truncate_adjustments - sql_delete_from "spree_adjustments where source_type = 'Spree::Order' - and source_id in (select id from spree_orders #{where_oc_id_in_ocs_to_delete})" + sql_delete_from "spree_adjustments where adjustable_type = 'Spree::Order' + and adjustable_id in (select id from spree_orders #{where_oc_id_in_ocs_to_delete})" - sql_delete_from "spree_adjustments where source_type = 'Spree::Shipment' - and source_id in (select id from spree_shipments #{where_order_id_in_orders_to_delete})" + sql_delete_from "spree_adjustments where adjustable_type = 'Spree::Shipment' + and adjustable_id in (select id from spree_shipments #{where_order_id_in_orders_to_delete})" - sql_delete_from "spree_adjustments where source_type = 'Spree::Payment' - and source_id in (select id from spree_payments #{where_order_id_in_orders_to_delete})" + sql_delete_from "spree_adjustments where adjustable_type = 'Spree::Payment' + and adjustable_id in (select id from spree_payments #{where_order_id_in_orders_to_delete})" - sql_delete_from "spree_adjustments where source_type = 'Spree::LineItem' - and source_id in (select id from spree_line_items #{where_order_id_in_orders_to_delete})" + sql_delete_from "spree_adjustments where adjustable_type = 'Spree::LineItem' + and adjustable_id in (select id from spree_line_items #{where_order_id_in_orders_to_delete})" end def truncate_order_cycle_data diff --git a/lib/tasks/specs.rake b/lib/tasks/specs.rake index e1b91c22a3..feb9052681 100644 --- a/lib/tasks/specs.rake +++ b/lib/tasks/specs.rake @@ -1,5 +1,34 @@ namespace :ofn do namespace :specs do + namespace :run do + def spec_folders + Pathname("spec/").children.select(&:directory?).map { |p| + p.split.last.to_s + } - %w(support factories javascripts performance) + end + + def execute_rspec_for_pattern(pattern) + system "bundle exec rspec --profile --pattern \"#{pattern}\"" + end + + def execute_rspec_for_spec_folder(folder) + execute_rspec_for_pattern("spec/#{folder}/{,/*/**}/*_spec.rb") + end + + def execute_rspec_for_spec_folders(folders) + folders = folders.join(",") + execute_rspec_for_pattern("spec/{#{folders}}/{,/*/**}/*_spec.rb") + end + + desc "Run Rspec tests excluding folders" + task :excluding_folders, [:folders] do |_task, args| + success = execute_rspec_for_spec_folders( + spec_folders - (args[:folders].split(",") + args.extras) + ) + abort "Failure when running tests" unless success + end + end + namespace :engines do def detect_engine_paths Pathname("engines/").children.select(&:directory?) diff --git a/package.json b/package.json index f9bbe28259..eedd46c0f6 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,15 @@ "type": "git", "url": "https://github.com/openfoodfoundation/openfoodnetwork" }, + "scripts": { + "storybook": "start-storybook" + }, "devDependencies": { + "@storybook/addon-controls": "^6.2.7", + "@storybook/addon-docs": "^6.2.7", + "@storybook/server": "^6.2.7", "jasmine-core": "~2.4.1", - "karma": "~0.13.22", + "karma": "~6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-coffee-preprocessor": "~1.0.1", "karma-jasmine": "~0.3.8" diff --git a/spec/components/distributor_title_component_spec.rb b/spec/components/distributor_title_component_spec.rb new file mode 100644 index 0000000000..3b206c4b2d --- /dev/null +++ b/spec/components/distributor_title_component_spec.rb @@ -0,0 +1,8 @@ +require "spec_helper" + +describe "DistributorTitle tests", type: :component do + it "displays distributor title with its name" do + render_inline(DistributorTitleComponent.new(name: "Freddy's Farm Shop")) { } + expect(page).to have_selector "h3", text: "Freddy's Farm Shop" + end +end diff --git a/spec/components/example_component_spec.rb b/spec/components/example_component_spec.rb new file mode 100644 index 0000000000..0cac3d8ff5 --- /dev/null +++ b/spec/components/example_component_spec.rb @@ -0,0 +1,8 @@ +require "spec_helper" + +describe "ExampleComponent tests", type: :component do + it "displays the h1 with the given parameter" do + render_inline(ExampleComponent.new(title: "Hello")) { } + expect(page).to have_selector "h1", text: "Hello" + end +end diff --git a/spec/components/stories/distributor_title_component_stories.rb b/spec/components/stories/distributor_title_component_stories.rb new file mode 100644 index 0000000000..9a292449b5 --- /dev/null +++ b/spec/components/stories/distributor_title_component_stories.rb @@ -0,0 +1,7 @@ +class DistributorTitleComponentStories < ViewComponent::Storybook::Stories + story(:default) do + controls do + text(:name, "Freddy s Farm Shop") + end + end +end diff --git a/spec/components/stories/example_component_stories.rb b/spec/components/stories/example_component_stories.rb new file mode 100644 index 0000000000..874b3cf576 --- /dev/null +++ b/spec/components/stories/example_component_stories.rb @@ -0,0 +1,13 @@ +class ExampleComponentStories < ViewComponent::Storybook::Stories + story(:with_short_text) do + controls do + text(:title, 'OK') + end + end + + story(:with_long_text) do + controls do + text(:title, 'This is a long text') + end + end +end diff --git a/spec/controllers/admin/bulk_line_items_controller_spec.rb b/spec/controllers/admin/bulk_line_items_controller_spec.rb index 4d94591a0e..a0e2a210f3 100644 --- a/spec/controllers/admin/bulk_line_items_controller_spec.rb +++ b/spec/controllers/admin/bulk_line_items_controller_spec.rb @@ -56,7 +56,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "when ransack params are passed in for line items" do before do - get :index, format: :json, q: { order_id_eq: order2.id } + get :index, as: :json, params: { q: { order_id_eq: order2.id } } end it "retrives a list of line items which match the criteria" do @@ -66,7 +66,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "when ransack params are passed in for orders" do before do - get :index, format: :json, q: { order: { completed_at_gt: 2.hours.ago } } + get :index, as: :json, params: { q: { order: { completed_at_gt: 2.hours.ago } } } end it "retrives a list of line items whose orders match the criteria" do @@ -90,7 +90,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "producer enterprise" do before do allow(controller).to receive_messages spree_current_user: supplier.owner - get :index, format: :json + get :index, as: :json end it "does not display line items for which my enterprise is a supplier" do @@ -101,7 +101,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "coordinator enterprise" do before do allow(controller).to receive_messages spree_current_user: coordinator.owner - get :index, format: :json + get :index, as: :json end it "retrieves a list of line_items" do @@ -113,7 +113,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "hub enterprise" do before do allow(controller).to receive_messages spree_current_user: distributor1.owner - get :index, format: :json + get :index, as: :json end it "retrieves a list of line_items" do @@ -130,7 +130,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "with pagination args" do it "returns paginated results" do - get :index, { page: 1, per_page: 2 }, format: :json + get :index, params: { page: 1, per_page: 2 }, as: :json expect(line_item_ids).to eq [line_item1.id, line_item2.id] expect(json_response['pagination']).to eq( @@ -139,7 +139,7 @@ describe Admin::BulkLineItemsController, type: :controller do end it "returns paginated results for a second page" do - get :index, { page: 2, per_page: 2 }, format: :json + get :index, params: { page: 2, per_page: 2 }, as: :json expect(line_item_ids).to eq [line_item3.id, line_item4.id] expect(json_response['pagination']).to eq( @@ -237,7 +237,7 @@ describe Admin::BulkLineItemsController, type: :controller do context "hub enterprise" do before do allow(controller).to receive_messages spree_current_user: distributor1.owner - xhr :put, :update, params + put :update, params: params, xhr: true end it "updates the line item" do diff --git a/spec/controllers/admin/customers_controller_spec.rb b/spec/controllers/admin/customers_controller_spec.rb index 6f289dc891..a63c023651 100644 --- a/spec/controllers/admin/customers_controller_spec.rb +++ b/spec/controllers/admin/customers_controller_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'open_food_network/user_balance_calculator' module Admin describe CustomersController, type: :controller do @@ -17,7 +16,7 @@ module Admin end it "returns an empty @collection" do - get :index, format: :html + get :index, as: :html expect(assigns(:collection)).to eq [] end end @@ -34,61 +33,34 @@ module Admin let(:params) { { format: :json, enterprise_id: enterprise.id } } it "scopes @collection to customers of that enterprise" do - get :index, params + get :index, params: params expect(assigns(:collection)).to eq [customer] end it "serializes the data" do expect(ActiveModel::ArraySerializer).to receive(:new) - get :index, params + get :index, params: params end - context 'when the customer_balance feature is enabled' do - let(:customers_with_balance) { instance_double(CustomersWithBalance) } + it 'calls CustomersWithBalance' do + customers_with_balance = instance_double(CustomersWithBalance) + allow(CustomersWithBalance) + .to receive(:new).with(enterprise) { customers_with_balance } - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, enterprise.owner) { true } - end + expect(customers_with_balance).to receive(:query) { Customer.none } - it 'calls CustomersWithBalance' do - allow(CustomersWithBalance) - .to receive(:new).with(enterprise) { customers_with_balance } - - expect(customers_with_balance).to receive(:query) { Customer.none } - - get :index, params - end - - it 'serializes using CustomerWithBalanceSerializer' do - expect(Api::Admin::CustomerWithBalanceSerializer).to receive(:new) - - get :index, params - end + get :index, params: params end - context 'when the customer_balance feature is not enabled' do - let(:calculator) do - instance_double(OpenFoodNetwork::UserBalanceCalculator, balance: 0) - end + it 'serializes using CustomerWithBalanceSerializer' do + expect(Api::Admin::CustomerWithBalanceSerializer).to receive(:new) - it 'calls Customer.of' do - expect(Customer).to receive(:of).twice.with(enterprise) { Customer.none } - - get :index, params - end - - it 'serializes calling the UserBalanceCalculator' do - expect(OpenFoodNetwork::UserBalanceCalculator) - .to receive(:new).with(customer.email, customer.enterprise) { calculator } - - get :index, params - end + get :index, params: params end context 'when the customer has no orders' do it 'includes the customer balance in the response' do - get :index, params + get :index, params: params expect(json_response.first["balance"]).to eq("$0.00") end end @@ -97,13 +69,8 @@ module Admin let(:order) { create(:order, customer: customer, state: 'complete') } let!(:line_item) { create(:line_item, order: order, price: 10.0) } - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, enterprise.owner) { true } - end - it 'includes the customer balance in the response' do - get :index, params + get :index, params: params expect(json_response.first["balance"]).to eq("$-10.00") end end @@ -114,9 +81,6 @@ module Admin let!(:payment) { create(:payment, order: order, amount: order.total) } before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, enterprise.owner) { true } - allow_any_instance_of(Spree::Payment).to receive(:completed?).and_return(true) order.process_payments! @@ -124,7 +88,7 @@ module Admin end it 'includes the customer balance in the response' do - get :index, params + get :index, params: params expect(json_response.first["balance"]).to eq("$10.00") end end @@ -134,7 +98,7 @@ module Admin let!(:line_item) { create(:line_item, order: order, price: 10.0) } it 'includes the customer balance in the response' do - get :index, params + get :index, params: params expect(json_response.first["balance"]).to eq("$0.00") end end @@ -145,9 +109,6 @@ module Admin let!(:payment) { create(:payment, order: order, amount: order.total) } before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, enterprise.owner) { true } - allow_any_instance_of(Spree::Payment).to receive(:completed?).and_return(true) order.process_payments! @@ -156,7 +117,7 @@ module Admin it 'includes the customer balance in the response' do expect(order.payment_total).to eq(0) - get :index, params + get :index, params: params expect(json_response.first["balance"]).to eq('$-10.00') end end @@ -164,7 +125,7 @@ module Admin context "and enterprise_id is not given in params" do it "returns an empty collection" do - get :index, format: :json + get :index, as: :json expect(assigns(:collection)).to eq [] end end @@ -176,7 +137,7 @@ module Admin end it "returns an empty collection" do - get :index, format: :json + get :index, as: :json expect(assigns(:collection)).to eq [] end end @@ -276,7 +237,7 @@ module Admin end it "renders the customer as json" do - get :show, format: :json, id: customer.id + get :show, as: :json, params: { id: customer.id } expect(JSON.parse(response.body)["id"]).to eq customer.id end end @@ -287,7 +248,7 @@ module Admin end it "prevents me from updating the customer" do - get :show, format: :json, id: customer.id + get :show, as: :json, params: { id: customer.id } expect(response).to redirect_to unauthorized_path end end diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb index 506fbf6b6a..381080cf6c 100644 --- a/spec/controllers/admin/enterprises_controller_spec.rb +++ b/spec/controllers/admin/enterprises_controller_spec.rb @@ -207,13 +207,13 @@ describe Admin::EnterprisesController, type: :controller do describe "tag rules" do let(:enterprise) { create(:distributor_enterprise) } - let!(:tag_rule) { create(:tag_rule, enterprise: enterprise) } + let!(:tag_rule) { create(:filter_order_cycles_tag_rule, enterprise: enterprise) } before do controller_login_as_enterprise_user [enterprise] end - context "discount order rules" do + context "with filter_order_cycles rule" do it "updates the existing rule with new attributes" do spree_put :update, id: enterprise, @@ -221,16 +221,13 @@ describe Admin::EnterprisesController, type: :controller do tag_rules_attributes: { '0' => { id: tag_rule.id, - type: "TagRule::DiscountOrder", - preferred_customer_tags: "some,new,tags", - calculator_type: "Calculator::FlatPercentItemTotal", - calculator_attributes: { id: tag_rule.calculator.id, preferred_flat_percent: "15" } + type: "TagRule::FilterOrderCycles", + preferred_exchange_tags: "some,new,tags" } } } tag_rule.reload - expect(tag_rule.preferred_customer_tags).to eq "some,new,tags" - expect(tag_rule.calculator.preferred_flat_percent).to eq 15 + expect(tag_rule.preferred_exchange_tags).to eq "some,new,tags" end it "creates new rules with new attributes" do @@ -240,17 +237,14 @@ describe Admin::EnterprisesController, type: :controller do tag_rules_attributes: { '0' => { id: "", - type: "TagRule::DiscountOrder", - preferred_customer_tags: "tags,are,awesome", - calculator_type: "Calculator::FlatPercentItemTotal", - calculator_attributes: { id: "", preferred_flat_percent: "24" } + type: "TagRule::FilterOrderCycles", + preferred_exchange_tags: "tags,are,awesome" } } } expect(tag_rule.reload).to be - new_tag_rule = TagRule::DiscountOrder.last - expect(new_tag_rule.preferred_customer_tags).to eq "tags,are,awesome" - expect(new_tag_rule.calculator.preferred_flat_percent).to eq 24 + new_tag_rule = TagRule::FilterOrderCycles.last + expect(new_tag_rule.preferred_exchange_tags).to eq "tags,are,awesome" end end end @@ -506,21 +500,21 @@ describe Admin::EnterprisesController, type: :controller do end context "when an order_cycle_id is provided in params" do - before { get :for_order_cycle, format: :json, order_cycle_id: 1 } + before { get :for_order_cycle, as: :json, params: { order_cycle_id: 1 } } it "initializes permissions with the existing OrderCycle" do expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle") end end context "when a coordinator is provided in params" do - before { get :for_order_cycle, format: :json, coordinator_id: 1 } + before { get :for_order_cycle, as: :json, params: { coordinator_id: 1 } } it "initializes permissions with a new OrderCycle" do expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "new OrderCycle") end end context "when both an order cycle and a coordinator are provided in params" do - before { get :for_order_cycle, format: :json, order_cycle_id: 1, coordinator_id: 1 } + before { get :for_order_cycle, as: :json, params: { order_cycle_id: 1, coordinator_id: 1 } } it "initializes permissions with the existing OrderCycle" do expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle") end diff --git a/spec/controllers/admin/invoice_settings_controller_spec.rb b/spec/controllers/admin/invoice_settings_controller_spec.rb index 67cc64af2b..54e5273e1f 100644 --- a/spec/controllers/admin/invoice_settings_controller_spec.rb +++ b/spec/controllers/admin/invoice_settings_controller_spec.rb @@ -20,7 +20,7 @@ describe Admin::InvoiceSettingsController, type: :controller do it "disables invoices" do expect { - post :update, params + post :update, params: params }.to change { Spree::Config[:enable_invoices?] }.to(false) @@ -28,7 +28,7 @@ describe Admin::InvoiceSettingsController, type: :controller do it "changes the invoice style" do expect { - post :update, params + post :update, params: params }.to change { Spree::Config[:invoice_style2?] }.to(true) @@ -36,7 +36,7 @@ describe Admin::InvoiceSettingsController, type: :controller do it "disables receipt printing" do expect { - post :update, params + post :update, params: params }.to change { Spree::Config[:enable_receipt_printing?] }.to(true) diff --git a/spec/controllers/admin/matomo_settings_controller_spec.rb b/spec/controllers/admin/matomo_settings_controller_spec.rb index 8644557a58..0bc9b35a16 100644 --- a/spec/controllers/admin/matomo_settings_controller_spec.rb +++ b/spec/controllers/admin/matomo_settings_controller_spec.rb @@ -20,7 +20,7 @@ describe Admin::MatomoSettingsController, type: :controller do it "changes Matomo settings" do expect { - post :update, params + post :update, params: params }.to change { [ Spree::Config[:matomo_url], diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 216631ce05..ab6450e42e 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -20,7 +20,7 @@ module Admin context "html" do it "doesn't load any data" do - get :index, format: :html + get :index, as: :html expect(assigns(:collection)).to be_empty end end @@ -28,7 +28,7 @@ module Admin context "json" do context "where ransack conditions are specified" do it "loads order cycles that closed within the past month, and orders without a close_at date" do - get :index, format: :json + get :index, as: :json expect(assigns(:collection)).to_not include oc1, oc2 expect(assigns(:collection)).to include oc3, oc4 end @@ -38,7 +38,7 @@ module Admin let(:q) { { orders_close_at_gt: 45.days.ago } } it "loads order cycles that closed after the specified date, and orders without a close_at date" do - get :index, format: :json, q: q + get :index, as: :json, params: { q: q } expect(assigns(:collection)).to_not include oc1 expect(assigns(:collection)).to include oc2, oc3, oc4 end @@ -47,7 +47,7 @@ module Admin before { q.merge!(id_not_in: [oc2.id, oc4.id]) } it "loads order cycles that meet all conditions" do - get :index, format: :json, q: q + get :index, format: :json, params: { q: q } expect(assigns(:collection)).to_not include oc1, oc2, oc4 expect(assigns(:collection)).to include oc3 end @@ -80,14 +80,14 @@ module Admin describe "and a coordinator_id is submitted as part of the request" do describe "when the user manages the enterprise" do it "renders the new template" do - get :new, coordinator_id: distributor1.id + get :new, params: { coordinator_id: distributor1.id } expect(response).to render_template :new end end describe "when the user does not manage the enterprise" do it "renders the set_coordinator template and sets a flash error" do - get :new, coordinator_id: distributor3.id + get :new, params: { coordinator_id: distributor3.id } expect(response).to render_template :set_coordinator expect(flash[:error]).to eq "You don't have permission to create an order cycle coordinated by that enterprise" end @@ -101,7 +101,7 @@ module Admin context "as a manager of a shop" do let(:form_mock) { instance_double(OrderCycleForm) } - let(:params) { { format: :json, order_cycle: {} } } + let(:params) { { as: :json, order_cycle: {} } } before do controller_login_as_enterprise_user([shop]) @@ -336,7 +336,7 @@ module Admin describe "when an order cycle is deleteable" do it "allows the order_cycle to be destroyed" do - get :destroy, id: oc.id + get :destroy, params: { id: oc.id } expect(OrderCycle.find_by(id: oc.id)).to be nil end end @@ -345,7 +345,7 @@ module Admin let!(:order) { create(:order, order_cycle: oc) } it "displays an error message when we attempt to delete it" do - get :destroy, id: oc.id + get :destroy, params: { id: oc.id } expect(response).to redirect_to admin_order_cycles_path expect(flash[:error]).to eq I18n.t('admin.order_cycles.destroy_errors.orders_present') end @@ -355,7 +355,7 @@ module Admin let!(:schedule) { create(:schedule, order_cycles: [oc]) } it "displays an error message when we attempt to delete it" do - get :destroy, id: oc.id + get :destroy, params: { id: oc.id } expect(response).to redirect_to admin_order_cycles_path expect(flash[:error]).to eq I18n.t('admin.order_cycles.destroy_errors.schedule_present') end diff --git a/spec/controllers/admin/proxy_orders_controller_spec.rb b/spec/controllers/admin/proxy_orders_controller_spec.rb index d98eccabeb..bd4145015e 100644 --- a/spec/controllers/admin/proxy_orders_controller_spec.rb +++ b/spec/controllers/admin/proxy_orders_controller_spec.rb @@ -42,7 +42,7 @@ describe Admin::ProxyOrdersController, type: :controller do context "when cancellation succeeds" do it 'renders the cancelled proxy_order as json' do - get :cancel, params + get :cancel, params: params json_response = JSON.parse(response.body) expect(json_response['state']).to eq "canceled" expect(json_response['id']).to eq proxy_order.id @@ -54,7 +54,7 @@ describe Admin::ProxyOrdersController, type: :controller do before { order_cycle.update(orders_close_at: 1.day.ago) } it "shows an error" do - get :cancel, params + get :cancel, params: params json_response = JSON.parse(response.body) expect(json_response['errors']).to eq ['Could not cancel the order'] end @@ -111,7 +111,7 @@ describe Admin::ProxyOrdersController, type: :controller do context "when resuming succeeds" do it 'renders the resumed proxy_order as json' do - get :resume, params + get :resume, params: params json_response = JSON.parse(response.body) expect(json_response['state']).to eq "resumed" expect(json_response['id']).to eq proxy_order.id @@ -123,7 +123,7 @@ describe Admin::ProxyOrdersController, type: :controller do before { order_cycle.update(orders_close_at: 1.day.ago) } it "shows an error" do - get :resume, params + get :resume, params: params json_response = JSON.parse(response.body) expect(json_response['errors']).to eq ['Could not resume the order'] end diff --git a/spec/controllers/admin/schedules_controller_spec.rb b/spec/controllers/admin/schedules_controller_spec.rb index 2718d75b65..544d31050d 100644 --- a/spec/controllers/admin/schedules_controller_spec.rb +++ b/spec/controllers/admin/schedules_controller_spec.rb @@ -21,13 +21,13 @@ describe Admin::SchedulesController, type: :controller do let(:params) { { format: :json } } it "scopes @collection to schedules containing order_cycles coordinated by enterprises I manage" do - get :index, params + get :index, params: params expect(assigns(:collection)).to eq [coordinated_schedule] end it "serializes the data" do expect(ActiveModel::ArraySerializer).to receive(:new) - get :index, params + get :index, params: params end context "and there is a schedule of an OC coordinated by _another_ enterprise I manage and the first enterprise is given" do @@ -37,7 +37,7 @@ describe Admin::SchedulesController, type: :controller do let(:params) { { format: :json, enterprise_id: managed_coordinator.id } } it "scopes @collection to schedules containing order_cycles coordinated by the first enterprise" do - get :index, params + get :index, params: params expect(assigns(:collection)).to eq [coordinated_schedule] end end @@ -45,7 +45,7 @@ describe Admin::SchedulesController, type: :controller do context "where I dont manage an order cycle coordinator" do it "returns an empty collection" do - get :index, format: :json + get :index, as: :json expect(assigns(:collection)).to be_nil end end diff --git a/spec/controllers/admin/stripe_accounts_controller_spec.rb b/spec/controllers/admin/stripe_accounts_controller_spec.rb index 3774c47921..bca1d2444e 100644 --- a/spec/controllers/admin/stripe_accounts_controller_spec.rb +++ b/spec/controllers/admin/stripe_accounts_controller_spec.rb @@ -15,7 +15,7 @@ describe Admin::StripeAccountsController, type: :controller do end it "redirects to Stripe Authorization url constructed OAuth" do - get :connect, enterprise_id: 1 # A deterministic id results in a deterministic state JWT token + get :connect, params: { enterprise_id: 1 } # A deterministic id results in a deterministic state JWT token expect(response).to redirect_to("https://connect.stripe.com/oauth/authorize?state=eyJhbGciOiJIUzI1NiJ9.eyJlbnRlcnByaXNlX2lkIjoiMSJ9.jSSFGn0bLhwuiQYK5ORmHWW7aay1l030bcfGwn1JbFg&scope=read_write&client_id=some_id&response_type=code") end @@ -98,7 +98,7 @@ describe Admin::StripeAccountsController, type: :controller do end it "redirects to unauthorized" do - get :status, params + get :status, params: params expect(response).to redirect_to unauthorized_path end end @@ -110,7 +110,7 @@ describe Admin::StripeAccountsController, type: :controller do context "when Stripe is not enabled" do it "returns with a status of 'stripe_disabled'" do - get :status, params + get :status, params: params json_response = JSON.parse(response.body) expect(json_response["status"]).to eq "stripe_disabled" end @@ -121,7 +121,7 @@ describe Admin::StripeAccountsController, type: :controller do context "when no stripe account is associated with the specified enterprise" do it "returns with a status of 'account_missing'" do - get :status, params + get :status, params: params json_response = JSON.parse(response.body) expect(json_response["status"]).to eq "account_missing" end @@ -136,7 +136,7 @@ describe Admin::StripeAccountsController, type: :controller do end it "returns with a status of 'access_revoked'" do - get :status, params + get :status, params: params json_response = JSON.parse(response.body) expect(json_response["status"]).to eq "access_revoked" end @@ -157,7 +157,7 @@ describe Admin::StripeAccountsController, type: :controller do end it "returns with a status of 'connected'" do - get :status, params + get :status, params: params json_response = JSON.parse(response.body) expect(json_response["status"]).to eq "connected" # serializes required attrs diff --git a/spec/controllers/admin/stripe_connect_settings_controller_spec.rb b/spec/controllers/admin/stripe_connect_settings_controller_spec.rb index c676cd002a..fe671dc666 100644 --- a/spec/controllers/admin/stripe_connect_settings_controller_spec.rb +++ b/spec/controllers/admin/stripe_connect_settings_controller_spec.rb @@ -82,7 +82,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do before { allow(controller).to receive(:spree_current_user) { user } } it "does not allow access" do - get :update, params + get :update, params: params expect(response).to redirect_to unauthorized_path end end @@ -95,7 +95,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do it "sets global config to the specified values" do expect(Spree::Config.stripe_connect_enabled).to be true - get :update, params + get :update, params: params expect(Spree::Config.stripe_connect_enabled).to be false end end diff --git a/spec/controllers/admin/subscriptions_controller_spec.rb b/spec/controllers/admin/subscriptions_controller_spec.rb index 65a8cde0c3..322a5e488e 100644 --- a/spec/controllers/admin/subscriptions_controller_spec.rb +++ b/spec/controllers/admin/subscriptions_controller_spec.rb @@ -19,7 +19,7 @@ describe Admin::SubscriptionsController, type: :controller do context 'as a regular user' do it 'redirects to unauthorized' do - get :index, params + get :index, params: params expect(response).to redirect_to unauthorized_path end end @@ -32,7 +32,7 @@ describe Admin::SubscriptionsController, type: :controller do let!(:subscription) { create(:subscription, shop: shop) } it 'renders the index page with appropriate data' do - get :index, params + get :index, params: params expect(response).to render_template 'index' expect(assigns(:collection)).to eq [] # No collection loaded expect(assigns(:shops)).to eq [shop] # Shops are loaded @@ -41,7 +41,7 @@ describe Admin::SubscriptionsController, type: :controller do context "where I don't manage a shop that is set up for subscriptions" do it 'renders the setup_explanation page' do - get :index, params + get :index, params: params expect(response).to render_template 'setup_explanation' expect(assigns(:collection)).to eq [] # No collection loaded expect(assigns(:shop)).to eq shop # First SO enabled shop is loaded @@ -56,7 +56,7 @@ describe Admin::SubscriptionsController, type: :controller do context 'as a regular user' do it 'redirects to unauthorized' do - get :index, params + get :index, params: params expect(response).to redirect_to unauthorized_path end end @@ -67,7 +67,7 @@ describe Admin::SubscriptionsController, type: :controller do let!(:subscription2) { create(:subscription, shop: shop2) } it 'renders the collection as json' do - get :index, params + get :index, params: params json_response = JSON.parse(response.body) expect(json_response.count).to be 2 expect(json_response.map{ |so| so['id'] }).to include subscription.id, subscription2.id @@ -77,7 +77,7 @@ describe Admin::SubscriptionsController, type: :controller do before { params.merge!(q: { shop_id_eq: shop2.id }) } it "restricts the list of subscriptions" do - get :index, params + get :index, params: params json_response = JSON.parse(response.body) expect(json_response.count).to be 1 ids = json_response.map{ |so| so['id'] } @@ -99,7 +99,7 @@ describe Admin::SubscriptionsController, type: :controller do it 'loads the preloads the necessary data' do expect(controller).to receive(:load_form_data) - get :new, subscription: { shop_id: shop.id } + get :new, params: { subscription: { shop_id: shop.id } } expect(assigns(:subscription)).to be_a_new Subscription expect(assigns(:subscription).shop).to eq shop end @@ -238,7 +238,7 @@ describe Admin::SubscriptionsController, type: :controller do it 'loads the preloads the necessary data' do expect(controller).to receive(:load_form_data) - get :edit, id: subscription.id + get :edit, params: { id: subscription.id } expect(assigns(:subscription)).to eq subscription end end diff --git a/spec/controllers/admin/tag_rules_controller_spec.rb b/spec/controllers/admin/tag_rules_controller_spec.rb index d80da09195..d54a371bfb 100644 --- a/spec/controllers/admin/tag_rules_controller_spec.rb +++ b/spec/controllers/admin/tag_rules_controller_spec.rb @@ -8,7 +8,7 @@ describe Admin::TagRulesController, type: :controller do let(:format) { :json } let(:enterprise) { create(:distributor_enterprise) } - let!(:tag_rule) { create(:tag_rule, enterprise: enterprise) } + let!(:tag_rule) { create(:filter_order_cycles_tag_rule, enterprise: enterprise) } let(:params) { { format: format, id: tag_rule.id } } context "where I don't manage the tag rule enterprise" do diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 1b3a3e3da7..44165bde23 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -21,7 +21,7 @@ describe Admin::VariantOverridesController, type: :controller do end it "redirects to unauthorized" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } expect(response).to redirect_to unauthorized_path end end @@ -33,7 +33,7 @@ describe Admin::VariantOverridesController, type: :controller do context "but the producer has not granted VO permission" do it "redirects to unauthorized" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } expect(response).to redirect_to unauthorized_path end @@ -41,7 +41,7 @@ describe Admin::VariantOverridesController, type: :controller do other_variant_override = create(:variant_override, hub: hub, variant: create(:variant)) expect(controller).not_to receive(:authorize!).with(:update, other_variant_override) - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } end end @@ -51,7 +51,7 @@ describe Admin::VariantOverridesController, type: :controller do end it "loads data" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } expect(assigns[:hubs]).to eq [hub] expect(assigns[:producers]).to eq [variant.product.supplier] expect(assigns[:hub_permissions]).to eq Hash[hub.id, [variant.product.supplier.id]] @@ -59,7 +59,7 @@ describe Admin::VariantOverridesController, type: :controller do end it "allows me to update the variant override" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } variant_override.reload expect(variant_override.price).to eq 123.45 @@ -72,7 +72,7 @@ describe Admin::VariantOverridesController, type: :controller do let(:variant_override_params) { [{ id: variant_override.id, price: "", count_on_hand: "", default_stock: nil, resettable: nil, sku: nil, on_demand: nil }] } it "destroys the variant override" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } expect(VariantOverride.find_by(id: variant_override.id)).to be_nil end end @@ -84,7 +84,7 @@ describe Admin::VariantOverridesController, type: :controller do before { deleted_variant.update_attribute :deleted_at, Time.zone.now } it "allows to update other variant overrides" do - put :bulk_update, format: format, variant_overrides: variant_override_params + put :bulk_update, as: format, params: { variant_overrides: variant_override_params } expect(response).to_not redirect_to unauthorized_path variant_override.reload @@ -118,7 +118,7 @@ describe Admin::VariantOverridesController, type: :controller do end it "redirects to unauthorized" do - put :bulk_reset, params + put :bulk_reset, params: params expect(response).to redirect_to unauthorized_path end end @@ -130,7 +130,7 @@ describe Admin::VariantOverridesController, type: :controller do context "where the producer has not granted create_variant_overrides permission to the hub" do it "restricts access" do - put :bulk_reset, params + put :bulk_reset, params: params expect(response).to redirect_to unauthorized_path end end @@ -139,7 +139,7 @@ describe Admin::VariantOverridesController, type: :controller do let!(:er1) { create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:create_variant_overrides]) } it "loads data" do - put :bulk_reset, params + put :bulk_reset, params: params expect(assigns[:hubs]).to eq [hub] expect(assigns[:producers]).to eq [producer] expect(assigns[:hub_permissions]).to eq Hash[hub.id, [producer.id]] @@ -149,7 +149,7 @@ describe Admin::VariantOverridesController, type: :controller do it "updates stock to default values where reset is enabled" do expect(variant_override1.reload.count_on_hand).to eq 5 # reset enabled expect(variant_override2.reload.count_on_hand).to eq 2 # reset disabled - put :bulk_reset, params + put :bulk_reset, params: params expect(variant_override1.reload.count_on_hand).to eq 7 # reset enabled expect(variant_override2.reload.count_on_hand).to eq 2 # reset disabled end @@ -164,7 +164,7 @@ describe Admin::VariantOverridesController, type: :controller do it "does not reset count_on_hand for variant_overrides not in params" do expect { - put :bulk_reset, params + put :bulk_reset, params: params }.to_not change{ variant_override3.reload.count_on_hand } end end diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/v0/base_controller_spec.rb similarity index 93% rename from spec/controllers/api/base_controller_spec.rb rename to spec/controllers/api/v0/base_controller_spec.rb index 2392c24343..ec9875723b 100644 --- a/spec/controllers/api/base_controller_spec.rb +++ b/spec/controllers/api/v0/base_controller_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' -describe Api::BaseController do +describe Api::V0::BaseController do render_views - controller(Api::BaseController) do + controller(Api::V0::BaseController) do skip_authorization_check only: :index def index @@ -44,7 +44,7 @@ describe Api::BaseController do end it "using an invalid token param" do - get :index, token: "fake_key" + get :index, params: { token: "fake_key" } expect(json_response).to eq( "error" => "Invalid API key (fake_key) specified." ) end end diff --git a/spec/controllers/api/customers_controller_spec.rb b/spec/controllers/api/v0/customers_controller_spec.rb similarity index 97% rename from spec/controllers/api/customers_controller_spec.rb rename to spec/controllers/api/v0/customers_controller_spec.rb index 2034d3118e..f06116a5ab 100644 --- a/spec/controllers/api/customers_controller_spec.rb +++ b/spec/controllers/api/v0/customers_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe CustomersController, type: :controller do + describe V0::CustomersController, type: :controller do include AuthenticationHelper render_views diff --git a/spec/controllers/api/enterprise_fees_controller_spec.rb b/spec/controllers/api/v0/enterprise_fees_controller_spec.rb similarity index 91% rename from spec/controllers/api/enterprise_fees_controller_spec.rb rename to spec/controllers/api/v0/enterprise_fees_controller_spec.rb index 85979beacb..40ed1e78e2 100644 --- a/spec/controllers/api/enterprise_fees_controller_spec.rb +++ b/spec/controllers/api/v0/enterprise_fees_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe EnterpriseFeesController, type: :controller do + describe V0::EnterpriseFeesController, type: :controller do include AuthenticationHelper let!(:unreferenced_fee) { create(:enterprise_fee) } diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/v0/enterprises_controller_spec.rb similarity index 98% rename from spec/controllers/api/enterprises_controller_spec.rb rename to spec/controllers/api/v0/enterprises_controller_spec.rb index 9ba546e50e..834eb42b1c 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/v0/enterprises_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Api::EnterprisesController, type: :controller do +describe Api::V0::EnterprisesController, type: :controller do render_views let(:enterprise) { create(:distributor_enterprise) } diff --git a/spec/controllers/api/exchange_products_controller_spec.rb b/spec/controllers/api/v0/exchange_products_controller_spec.rb similarity index 95% rename from spec/controllers/api/exchange_products_controller_spec.rb rename to spec/controllers/api/v0/exchange_products_controller_spec.rb index a0ae941c8a..01394ec215 100644 --- a/spec/controllers/api/exchange_products_controller_spec.rb +++ b/spec/controllers/api/v0/exchange_products_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe ExchangeProductsController, type: :controller do + describe V0::ExchangeProductsController, type: :controller do include AuthenticationHelper let(:order_cycle) { create(:order_cycle) } @@ -54,7 +54,7 @@ module Api let(:products_relation) { Spree::Product.includes(:variants).where("spree_variants.id": exchange.variants.map(&:id)) } before do - stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) + stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) end describe "when a specific page is requested" do diff --git a/spec/controllers/api/logos_controller_spec.rb b/spec/controllers/api/v0/logos_controller_spec.rb similarity index 98% rename from spec/controllers/api/logos_controller_spec.rb rename to spec/controllers/api/v0/logos_controller_spec.rb index e6e929d423..32815be1c4 100644 --- a/spec/controllers/api/logos_controller_spec.rb +++ b/spec/controllers/api/v0/logos_controller_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" module Api - describe LogosController, type: :controller do + describe V0::LogosController, type: :controller do include AuthenticationHelper let(:admin_user) { create(:admin_user) } diff --git a/spec/controllers/api/order_cycles_controller_spec.rb b/spec/controllers/api/v0/order_cycles_controller_spec.rb similarity index 99% rename from spec/controllers/api/order_cycles_controller_spec.rb rename to spec/controllers/api/v0/order_cycles_controller_spec.rb index d41d26aa43..274b9152fd 100644 --- a/spec/controllers/api/order_cycles_controller_spec.rb +++ b/spec/controllers/api/v0/order_cycles_controller_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" module Api - describe OrderCyclesController, type: :controller do + describe V0::OrderCyclesController, type: :controller do let!(:distributor) { create(:distributor_enterprise) } let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) } let!(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first } diff --git a/spec/controllers/api/orders_controller_spec.rb b/spec/controllers/api/v0/orders_controller_spec.rb similarity index 92% rename from spec/controllers/api/orders_controller_spec.rb rename to spec/controllers/api/v0/orders_controller_spec.rb index 2a5421e9cb..4a76605138 100644 --- a/spec/controllers/api/orders_controller_spec.rb +++ b/spec/controllers/api/v0/orders_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe OrdersController, type: :controller do + describe V0::OrdersController, type: :controller do include AuthenticationHelper render_views @@ -133,7 +133,7 @@ module Api end it 'can show only completed orders' do - get :index, format: :json, q: { completed_at_not_null: true, s: 'created_at desc' } + get :index, params: { q: { completed_at_not_null: true, s: 'created_at desc' } }, as: :json expect(json_response['orders']).to eq serialized_orders([order4, order3, order2, order1]) end @@ -145,7 +145,7 @@ module Api end it 'returns pagination data when query params contain :per_page]' do - get :index, per_page: 15, page: 1 + get :index, params: { per_page: 15, page: 1 } pagination_data = { 'results' => 2, @@ -166,12 +166,12 @@ module Api before { allow(controller).to receive(:spree_current_user) { admin_user } } it "when no order number is given" do - get :show, id: "" + get :show, params: { id: "" } expect(response).to have_http_status(:not_found) end it "when order number given is not in the systen" do - get :show, id: "X1321313232" + get :show, params: { id: "X1321313232" } expect(response).to have_http_status(:not_found) end end @@ -179,31 +179,31 @@ module Api context "access" do it "returns unauthorized, as a regular user" do allow(controller).to receive(:spree_current_user) { regular_user } - get :show, id: order.number + get :show, params: { id: order.number } assert_unauthorized! end it "returns the order, as an admin user" do allow(controller).to receive(:spree_current_user) { admin_user } - get :show, id: order.number + get :show, params: { id: order.number } expect_order end it "returns the order, as the order distributor owner" do allow(controller).to receive(:spree_current_user) { order.distributor.owner } - get :show, id: order.number + get :show, params: { id: order.number } expect_order end it "returns unauthorized, as the order product's supplier owner" do allow(controller).to receive(:spree_current_user) { order.line_items.first.variant.product.supplier.owner } - get :show, id: order.number + get :show, params: { id: order.number } assert_unauthorized! end it "returns the order, as the Order Cycle coorinator owner" do allow(controller).to receive(:spree_current_user) { order.order_cycle.coordinator.owner } - get :show, id: order.number + get :show, params: { id: order.number } expect_order end end @@ -215,19 +215,19 @@ module Api it "can view an order not in a standard state" do order.update(completed_at: nil, state: 'shipped') - get :show, id: order.number + get :show, params: { id: order.number } expect_order end it "can view an order with weight calculator (this validates case where options[current_order] is nil on the shipping method serializer)" do order.shipping_method.update_attribute(:calculator, create(:weight_calculator, calculable: order)) allow(controller).to receive(:current_order).and_return order - get :show, id: order.number + get :show, params: { id: order.number } expect_order end it "returns an order with all required fields" do - get :show, id: order.number + get :show, params: { id: order.number } expect_order expect(json_response.symbolize_keys.keys).to include(*order_detailed_attributes) @@ -244,7 +244,7 @@ module Api expect(json_response[:adjustments].first).to include( 'label' => "Transaction fee", - 'amount' => order.adjustments.payment_fee.first.amount.to_s + 'amount' => order.all_adjustments.payment_fee.first.amount.to_s ) expect(json_response[:adjustments].second).to include( 'label' => "Shipping", @@ -274,13 +274,13 @@ module Api before do order.finalize! - create(:check_payment, order: order, amount: order.total) + order.payments << create(:check_payment, order: order, amount: order.total) allow(controller).to receive(:spree_current_user) { order.distributor.owner } end describe "#capture" do it "captures payments and returns an updated order object" do - put :capture, id: order.number + put :capture, params: { id: order.number } expect(order.reload.pending_payments.empty?).to be true expect_order @@ -305,7 +305,7 @@ module Api end it "marks orders as shipped and returns an updated order object" do - put :ship, id: order.number + put :ship, params: { id: order.number } expect(order.reload.shipments.any?(&:shipped?)).to be true expect_order diff --git a/spec/controllers/api/product_images_controller_spec.rb b/spec/controllers/api/v0/product_images_controller_spec.rb similarity index 74% rename from spec/controllers/api/product_images_controller_spec.rb rename to spec/controllers/api/v0/product_images_controller_spec.rb index 95ee3bd3de..311654b745 100644 --- a/spec/controllers/api/product_images_controller_spec.rb +++ b/spec/controllers/api/v0/product_images_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe ProductImagesController, type: :controller do + describe V0::ProductImagesController, type: :controller do include AuthenticationHelper render_views @@ -19,14 +19,14 @@ module Api let(:current_api_user) { create(:admin_user) } it "saves a new image when none is present" do - xhr :post, :update_product_image, product_id: product_without_image.id, file: image, use_route: :product_images + post :update_product_image, xhr: true, params: { product_id: product_without_image.id, file: image, use_route: :product_images } expect(response.status).to eq 201 expect(product_without_image.images.first.id).to eq json_response['id'] end it "updates an existing product image" do - xhr :post, :update_product_image, product_id: product_with_image.id, file: image, use_route: :product_images + post :update_product_image, xhr: true, params: { product_id: product_with_image.id, file: image, use_route: :product_images } expect(response.status).to eq 200 expect(product_with_image.images.first.id).to eq json_response['id'] diff --git a/spec/controllers/api/products_controller_spec.rb b/spec/controllers/api/v0/products_controller_spec.rb similarity index 98% rename from spec/controllers/api/products_controller_spec.rb rename to spec/controllers/api/v0/products_controller_spec.rb index de509f89b5..8af0985e48 100644 --- a/spec/controllers/api/products_controller_spec.rb +++ b/spec/controllers/api/v0/products_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require 'spree/core/product_duplicator' -describe Api::ProductsController, type: :controller do +describe Api::V0::ProductsController, type: :controller do render_views let(:supplier) { create(:supplier_enterprise) } @@ -122,7 +122,7 @@ describe Api::ProductsController, type: :controller do expect(response.status).to eq(422) expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.") errors = json_response["errors"] - expect(errors.keys).to match_array(["name", "price", "primary_taxon", "shipping_category_id", "supplier", "variant_unit"]) + expect(errors.keys).to match_array(["name", "price", "primary_taxon", "shipping_category", "supplier", "variant_unit"]) end it "can update a product" do diff --git a/spec/controllers/api/promo_images_controller_spec.rb b/spec/controllers/api/v0/promo_images_controller_spec.rb similarity index 98% rename from spec/controllers/api/promo_images_controller_spec.rb rename to spec/controllers/api/v0/promo_images_controller_spec.rb index 9fe559456e..6c8d0f1319 100644 --- a/spec/controllers/api/promo_images_controller_spec.rb +++ b/spec/controllers/api/v0/promo_images_controller_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" module Api - describe PromoImagesController, type: :controller do + describe V0::PromoImagesController, type: :controller do include AuthenticationHelper let(:admin_user) { create(:admin_user) } diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/v0/shipments_controller_spec.rb similarity index 68% rename from spec/controllers/api/shipments_controller_spec.rb rename to spec/controllers/api/v0/shipments_controller_spec.rb index f82b30e1e5..b266c1c3e8 100644 --- a/spec/controllers/api/shipments_controller_spec.rb +++ b/spec/controllers/api/v0/shipments_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Api::ShipmentsController, type: :controller do +describe Api::V0::ShipmentsController, type: :controller do render_views let!(:shipment) { create(:shipment) } @@ -65,7 +65,7 @@ describe Api::ShipmentsController, type: :controller do spree_post :create, params - expect(json_response["id"]). to eq(original_shipment_id) + expect(json_response["id"]).to eq(original_shipment_id) expect_valid_response expect(order.shipment.reload.inventory_units.size).to eq 2 expect(order.reload.line_items.first.variant.price).to eq(variant.price) @@ -110,28 +110,69 @@ describe Api::ShipmentsController, type: :controller do expect(response.status).to eq(422) end - context 'for completed shipments' do + describe "#add and #remove" do let(:order) { create :completed_order_with_totals } + let(:line_item) { order.line_items.first } + let(:existing_variant) { line_item.variant } + let(:new_variant) { create(:variant) } + let(:params) { + { + quantity: 2, + order_id: order.to_param, + id: order.shipments.first.to_param + } + } - it 'adds a variant to a shipment' do - api_put :add, variant_id: variant.to_param, - quantity: 2, - order_id: order.to_param, - id: order.shipments.first.to_param - - expect(response.status).to eq(200) - expect(inventory_units_for(variant).size).to eq 2 + before do + line_item.update!(quantity: 3) end - it 'removes a variant from a shipment' do - order.contents.add(variant, 2) - api_put :remove, variant_id: variant.to_param, - quantity: 1, - order_id: order.to_param, - id: order.shipments.first.to_param + context 'for completed shipments' do + it 'adds a variant to a shipment' do + expect { + api_put :add, params.merge(variant_id: new_variant.to_param) + expect(response.status).to eq(200) + }.to change { inventory_units_for(new_variant).size }.by(2) + end - expect(response.status).to eq(200) - expect(inventory_units_for(variant).size).to eq(1) + it 'adjusts stock when adding a variant' do + expect { + api_put :add, params.merge(variant_id: new_variant.to_param) + }.to change { new_variant.reload.on_hand }.by(-2) + end + + it 'removes a variant from a shipment' do + expect { + api_put :remove, params.merge(variant_id: existing_variant.to_param) + expect(response.status).to eq(200) + }.to change { inventory_units_for(existing_variant).size }.by(-2) + end + + it 'adjusts stock when removing a variant' do + expect { + api_put :remove, params.merge(variant_id: existing_variant.to_param) + }.to change { existing_variant.reload.on_hand }.by(2) + end + end + + context "for canceled orders" do + before do + expect(order.cancel).to eq true + end + + it "doesn't adjust stock when adding a variant" do + expect { + api_put :add, params.merge(variant_id: existing_variant.to_param) + expect(response.status).to eq(422) + }.to_not change { existing_variant.reload.on_hand } + end + + it "doesn't adjust stock when removing a variant" do + expect { + api_put :remove, params.merge(variant_id: existing_variant.to_param) + expect(response.status).to eq(422) + }.to_not change { existing_variant.reload.on_hand } + end end end @@ -189,6 +230,28 @@ describe Api::ShipmentsController, type: :controller do expect(inventory_units_for(variant).size).to eq 2 expect(order.reload.line_items.last.price).to eq(variant_override.price) end + + context "when line items have fees" do + let(:fee_order) { + instance_double(Spree::Order, number: "123", distributor: variant.product.supplier) + } + let(:contents) { instance_double(Spree::OrderContents) } + + before do + allow(Spree::Order).to receive(:find_by!) { fee_order } + allow(controller).to receive(:find_and_update_shipment) { } + allow(controller).to receive(:refuse_changing_cancelled_orders) { } + allow(fee_order).to receive(:contents) { contents } + allow(contents).to receive(:add) { } + allow(fee_order).to receive(:recreate_all_fees!) + end + + it "recalculates fees for the line item" do + params[:order_id] = fee_order.number + spree_put :add, params + expect(fee_order).to have_received(:recreate_all_fees!) + end + end end context '#remove' do diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/v0/shops_controller_spec.rb similarity index 90% rename from spec/controllers/api/shops_controller_spec.rb rename to spec/controllers/api/v0/shops_controller_spec.rb index 22b40b22db..2863aaef53 100644 --- a/spec/controllers/api/shops_controller_spec.rb +++ b/spec/controllers/api/v0/shops_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Api::ShopsController, type: :controller do +describe Api::V0::ShopsController, type: :controller do include AuthenticationHelper render_views @@ -23,7 +23,7 @@ describe Api::ShopsController, type: :controller do describe "#show" do it "returns shopfront data for an enterprise" do - get :show, id: producer.id + get :show, params: { id: producer.id } expect(json_response['name']).to eq 'Shopfront Test Producer' expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub' @@ -33,7 +33,7 @@ describe Api::ShopsController, type: :controller do describe "#closed_shops" do it "returns data for all closed shops" do - get :closed_shops, {} + get :closed_shops, params: {} expect(json_response).not_to match hub.name diff --git a/spec/controllers/api/states_controller_spec.rb b/spec/controllers/api/v0/states_controller_spec.rb similarity index 98% rename from spec/controllers/api/states_controller_spec.rb rename to spec/controllers/api/v0/states_controller_spec.rb index 548fcb0ad1..e9d9d11ad9 100644 --- a/spec/controllers/api/states_controller_spec.rb +++ b/spec/controllers/api/v0/states_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe StatesController do + describe V0::StatesController do render_views let!(:state) { create(:state, name: "Victoria") } diff --git a/spec/controllers/api/statuses_controller_spec.rb b/spec/controllers/api/v0/statuses_controller_spec.rb similarity index 93% rename from spec/controllers/api/statuses_controller_spec.rb rename to spec/controllers/api/v0/statuses_controller_spec.rb index 40132eed5c..e79dca33a3 100644 --- a/spec/controllers/api/statuses_controller_spec.rb +++ b/spec/controllers/api/v0/statuses_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe StatusesController, type: :controller do + describe V0::StatusesController, type: :controller do render_views describe "job queue status" do diff --git a/spec/controllers/api/taxonomies_controller_spec.rb b/spec/controllers/api/v0/taxonomies_controller_spec.rb similarity index 96% rename from spec/controllers/api/taxonomies_controller_spec.rb rename to spec/controllers/api/v0/taxonomies_controller_spec.rb index 8f080c9748..8948465864 100644 --- a/spec/controllers/api/taxonomies_controller_spec.rb +++ b/spec/controllers/api/v0/taxonomies_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module Api - describe TaxonomiesController do + describe V0::TaxonomiesController do render_views let(:taxonomy) { create(:taxonomy) } diff --git a/spec/controllers/api/taxons_controller_spec.rb b/spec/controllers/api/v0/taxons_controller_spec.rb similarity index 98% rename from spec/controllers/api/taxons_controller_spec.rb rename to spec/controllers/api/v0/taxons_controller_spec.rb index f006bc3b6c..8f2b18c942 100644 --- a/spec/controllers/api/taxons_controller_spec.rb +++ b/spec/controllers/api/v0/taxons_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Api::TaxonsController do +describe Api::V0::TaxonsController do render_views let(:taxonomy) { create(:taxonomy) } diff --git a/spec/controllers/api/terms_and_conditions_controller_spec.rb b/spec/controllers/api/v0/terms_and_conditions_controller_spec.rb similarity index 96% rename from spec/controllers/api/terms_and_conditions_controller_spec.rb rename to spec/controllers/api/v0/terms_and_conditions_controller_spec.rb index ca6a38290c..68439f74cf 100644 --- a/spec/controllers/api/terms_and_conditions_controller_spec.rb +++ b/spec/controllers/api/v0/terms_and_conditions_controller_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" module Api - describe TermsAndConditionsController, type: :controller do + describe V0::TermsAndConditionsController, type: :controller do include AuthenticationHelper let(:enterprise_owner) { create(:user) } diff --git a/spec/controllers/api/variants_controller_spec.rb b/spec/controllers/api/v0/variants_controller_spec.rb similarity index 96% rename from spec/controllers/api/variants_controller_spec.rb rename to spec/controllers/api/v0/variants_controller_spec.rb index 4a26422b62..439a03e22d 100644 --- a/spec/controllers/api/variants_controller_spec.rb +++ b/spec/controllers/api/v0/variants_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Api::VariantsController, type: :controller do +describe Api::V0::VariantsController, type: :controller do render_views let(:supplier) { FactoryBot.create(:supplier_enterprise) } @@ -130,7 +130,7 @@ describe Api::VariantsController, type: :controller do it "can create a new variant" do original_number_of_variants = variant.product.variants.count - api_post :create, variant: { sku: "12345", unit_value: "weight", unit_description: "L" }, product_id: variant.product.to_param + api_post :create, variant: { sku: "12345", unit_value: "1", unit_description: "L" }, product_id: variant.product.to_param expect(attributes.all?{ |attr| json_response.include? attr.to_s }).to eq(true) expect(response.status).to eq(201) diff --git a/spec/controllers/cart_controller_spec.rb b/spec/controllers/cart_controller_spec.rb index b3f6d46c8f..585c96a37e 100644 --- a/spec/controllers/cart_controller_spec.rb +++ b/spec/controllers/cart_controller_spec.rb @@ -17,7 +17,7 @@ describe CartController, type: :controller do allow(cart_service).to receive(:populate) { true } allow(cart_service).to receive(:valid?) { true } allow(cart_service).to receive(:variants_h) { {} } - xhr :post, :populate, use_route: :spree, format: :json + post :populate, xhr: true, params: { use_route: :spree }, as: :json expect(response.status).to eq(200) end @@ -26,7 +26,7 @@ describe CartController, type: :controller do allow(cart_service).to receive(:valid?) { false } allow(cart_service).to receive(:errors) { errors } allow(errors).to receive(:full_messages).and_return(["Error: foo"]) - xhr :post, :populate, use_route: :spree, format: :json + post :populate, xhr: true, params: { use_route: :spree }, as: :json expect(response.status).to eq(412) end @@ -34,7 +34,7 @@ describe CartController, type: :controller do allow(cart_service).to receive(:variants_h) { {} } allow(cart_service).to receive(:valid?) { true } expect(cart_service).to receive(:populate).with({}, true) - xhr :post, :populate, use_route: :spree, format: :json + post :populate, xhr: true, params: { use_route: :spree }, as: :json end it "returns stock levels as JSON on success" do @@ -44,7 +44,7 @@ describe CartController, type: :controller do allow(cart_service).to receive(:valid?) { true } allow(cart_service).to receive(:variants_h) { {} } - xhr :post, :populate, use_route: :spree, format: :json + post :populate, xhr: true, params: { use_route: :spree }, as: :json data = JSON.parse(response.body) expect(data['stock_levels']).to eq('my_stock_levels') diff --git a/spec/controllers/checkout_controller_concurrency_spec.rb b/spec/controllers/checkout_controller_concurrency_spec.rb index 0804bc7492..63860717e1 100644 --- a/spec/controllers/checkout_controller_concurrency_spec.rb +++ b/spec/controllers/checkout_controller_concurrency_spec.rb @@ -42,16 +42,22 @@ describe CheckoutController, concurrency: true, type: :controller do allow(controller).to receive(:spree_current_user).and_return(order.user) allow(controller).to receive(:current_distributor).and_return(order.distributor) allow(controller).to receive(:current_order_cycle).and_return(order.order_cycle) + + # Avoid setting headers as Rails 5 is not thread-safe here: + allow(controller).to receive(:restrict_iframes) end - # This spec does not seem to be running in two threads in Rails 5. There are errors for the - # same response headers being set twice, possibly indicating that there is only one response - # as opposed to two separate requests in two threads? - xit "handles two concurrent orders successfully" do + it "handles two concurrent orders successfully" do # New threads start running straight away. The breakpoint is after loading # the order and before advancing the order's state and making payments. breakpoint.lock + checkout_workflow_original = controller.method(:checkout_workflow) + expect(controller).to receive(:checkout_workflow) do |shipping_method_id| + breakpoint.synchronize {} + checkout_workflow_original.call(shipping_method_id) + end + # Starting two checkout threads. The controller code will determine if # these two threads are synchronised correctly or run into a race condition. # diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb index 933348dfd7..f743d6c092 100644 --- a/spec/controllers/checkout_controller_spec.rb +++ b/spec/controllers/checkout_controller_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe CheckoutController, type: :controller do + include StripeStubs + let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } let(:order_cycle) { create(:simple_order_cycle) } let(:order) { create(:order) } @@ -38,13 +40,53 @@ describe CheckoutController, type: :controller do expect(flash[:info]).to eq(I18n.t('order_cycles_closed_for_hub')) end + describe "#update" do + let(:user) { order.user } + let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } + let(:order_cycle) { create(:order_cycle, distributors: [distributor]) } + let(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) } + let(:payment_method) { distributor.payment_methods.first } + let(:shipping_method) { distributor.shipping_methods.first } + + before do + order.line_items << create(:line_item, variant: order_cycle.variants_distributed_by(distributor).first) + + allow(controller).to receive(:current_distributor).and_return(distributor) + allow(controller).to receive(:current_order_cycle).and_return(order_cycle) + allow(controller).to receive(:current_order).and_return(order) + allow(controller).to receive(:spree_current_user).and_return(user) + + user.bill_address = create(:address) + user.ship_address = create(:address) + user.save! + end + + it "completes the order and redirects to the order confirmation page" do + params = { + "order" => { + "bill_address_attributes" => order.bill_address.attributes, + "default_bill_address" => false, + "default_ship_address" => false, + "email" => user.email, + "payments_attributes" => [{"payment_method_id" => payment_method.id}], + "ship_address_attributes" => order.bill_address.attributes, + "shipping_method_id" => shipping_method.id + } + } + expect { post :update, params: params }. + to change { Customer.count }.by(1) + expect(order.completed?).to be true + expect(response).to redirect_to order_path(order) + end + end + describe "redirection to cart and stripe" do let(:order_cycle_distributed_variants) { double(:order_cycle_distributed_variants) } before do allow(controller).to receive(:current_order).and_return(order) allow(order).to receive(:distributor).and_return(distributor) - order.order_cycle = order_cycle + order.update(order_cycle: order_cycle) allow(OrderCycleDistributedVariants).to receive(:new).and_return(order_cycle_distributed_variants) end @@ -97,21 +139,50 @@ describe CheckoutController, type: :controller do end describe "when the order is in payment state and a stripe payment intent is provided" do + let(:user) { order.user } + let(:order) { create(:order_with_totals) } + let(:payment_method) { create(:stripe_sca_payment_method) } + let(:payment) { + create( + :payment, + amount: order.total, + state: "pending", + payment_method: payment_method, + response_code: "pi_123" + ) + } + before do + allow(Stripe).to receive(:api_key) { "sk_test_12345" } + stub_payment_intent_get_request + stub_successful_capture_request(order: order) + + allow(controller).to receive(:spree_current_user).and_return(user) + user.bill_address = create(:address) + user.ship_address = create(:address) + user.save! + order.update_attribute :state, "payment" - order.ship_address = create(:address) - order.save! - order.payments << create(:payment, state: "pending", response_code: "pi_123") + order.payments << payment # this is called a 2nd time after order completion from the reset_order_service expect(order_cycle_distributed_variants).to receive(:distributes_order_variants?).twice.and_return(true) end it "completes the order and redirects to the order confirmation page" do - get :edit, { payment_intent: "pi_123" } + get :edit, params: { payment_intent: "pi_123" } expect(order.completed?).to be true expect(response).to redirect_to order_path(order) end + + it "creates a customer record" do + order.update_columns(customer_id: nil) + Customer.delete_all + + expect { + get :edit, params: { payment_intent: "pi_123" } + }.to change { Customer.count }.by(1) + end end end end @@ -189,12 +260,12 @@ describe CheckoutController, type: :controller do it 'expires the current order' do allow(controller).to receive(:expire_current_order) - put :update, order: {} + put :update, params: { order: {} } expect(controller).to have_received(:expire_current_order) end it 'sets the access_token of the session' do - put :update, order: {} + put :update, params: { order: {} } expect(session[:access_token]).to eq(controller.current_order.token) end end diff --git a/spec/controllers/enterprises_controller_spec.rb b/spec/controllers/enterprises_controller_spec.rb index 86ff995516..1328c04d73 100644 --- a/spec/controllers/enterprises_controller_spec.rb +++ b/spec/controllers/enterprises_controller_spec.rb @@ -18,7 +18,7 @@ describe EnterprisesController, type: :controller do end it "sets the shop as the distributor on the order when shopping for the distributor" do - get :shop, id: distributor + get :shop, params: { id: distributor } expect(controller.current_distributor).to eq(distributor) expect(controller.current_order.distributor).to eq(distributor) @@ -29,7 +29,7 @@ describe EnterprisesController, type: :controller do before { allow(controller).to receive(:spree_current_user) { user } } it "sets the shop as the distributor on the order when shopping for the distributor" do - get :shop, id: distributor + get :shop, params: { id: distributor } expect(controller.current_distributor).to eq(distributor) expect(controller.current_order.distributor).to eq(distributor) @@ -39,11 +39,11 @@ describe EnterprisesController, type: :controller do it "sorts order cycles by the distributor's preferred ordering attr" do distributor.update_attribute(:preferred_shopfront_order_cycle_order, 'orders_close_at') - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to eq([order_cycle1, order_cycle2].sort_by(&:orders_close_at)) distributor.update_attribute(:preferred_shopfront_order_cycle_order, 'orders_open_at') - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to eq([order_cycle1, order_cycle2].sort_by(&:orders_open_at)) end @@ -64,23 +64,23 @@ describe EnterprisesController, type: :controller do preferred_exchange_tags: "wholesale", preferred_matched_order_cycles_visibility: 'hidden') - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3 allow(controller).to receive(:spree_current_user) { user } - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3 oc3_exchange.update_attribute(:tag_list, "wholesale") - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2 expect(assigns(:order_cycles)).not_to include order_cycle3 customer.update_attribute(:tag_list, ["wholesale"]) - get :shop, id: distributor + get :shop, params: { id: distributor } expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3 end end @@ -89,7 +89,7 @@ describe EnterprisesController, type: :controller do line_item = create(:line_item) controller.current_order.line_items << line_item - get :shop, id: distributor + get :shop, params: { id: distributor } expect(controller.current_order.distributor).to eq(distributor) expect(controller.current_order.order_cycle).to be_nil @@ -97,7 +97,7 @@ describe EnterprisesController, type: :controller do end it "should not empty an order if returning to the same distributor" do - get :shop, id: current_distributor + get :shop, params: { id: current_distributor } expect(controller.current_order.distributor).to eq current_distributor expect(controller.current_order.line_items.first.variant).to eq line_item.variant @@ -117,7 +117,7 @@ describe EnterprisesController, type: :controller do end it "redirects to the cart" do - get :shop, id: current_distributor + get :shop, params: { id: current_distributor } expect(response).to redirect_to cart_path end @@ -129,7 +129,7 @@ describe EnterprisesController, type: :controller do order.save order_cycle1.update_attribute :orders_close_at, Time.zone.now - get :shop, id: distributor + get :shop, params: { id: distributor } expect(controller.current_order.distributor).to eq(distributor) expect(controller.current_order.order_cycle).to eq(order_cycle2) @@ -139,7 +139,7 @@ describe EnterprisesController, type: :controller do it "sets order cycle if only one is available at the chosen distributor" do order_cycle2.destroy - get :shop, id: distributor + get :shop, params: { id: distributor } expect(controller.current_order.distributor).to eq(distributor) expect(controller.current_order.order_cycle).to eq(order_cycle1) @@ -150,23 +150,23 @@ describe EnterprisesController, type: :controller do # let(:enterprise) { create(:enterprise, permalink: 'enterprise_permalink') } it "responds with status of 200 when the route does not exist" do - xhr :get, :check_permalink, permalink: 'some_nonexistent_route', format: :js + get :check_permalink, xhr: true, params: { permalink: 'some_nonexistent_route' }, as: :js expect(response.status).to be 200 end it "responds with status of 409 when the permalink matches an existing route" do # get :check_permalink, { permalink: 'enterprise_permalink', format: :js } # expect(response.status).to be 409 - xhr :get, :check_permalink, permalink: 'map', format: :js + get :check_permalink, xhr: true, params: { permalink: 'map' }, as: :js expect(response.status).to be 409 - xhr :get, :check_permalink, permalink: '', format: :js + get :check_permalink, xhr: true, params: { permalink: '' }, as: :js expect(response.status).to be 409 end end context "checking access on nonexistent enterprise" do before do - get :shop, id: "some_nonexistent_enterprise" + get :shop, params: { id: "some_nonexistent_enterprise" } end it "redirects to shops_path" do diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index ce91ad74df..0693f6f3d1 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -48,7 +48,7 @@ describe LineItemsController, type: :controller do context "where the item's order is not associated with the user" do it "denies deletion" do - delete :destroy, params + delete :destroy, params: params expect(response.status).to eq 403 end end @@ -61,7 +61,7 @@ describe LineItemsController, type: :controller do context "without an order cycle or distributor" do it "denies deletion" do - delete :destroy, params + delete :destroy, params: params expect(response.status).to eq 403 end end @@ -71,7 +71,7 @@ describe LineItemsController, type: :controller do context "where changes are not allowed" do it "denies deletion" do - delete :destroy, params + delete :destroy, params: params expect(response.status).to eq 403 end end @@ -80,7 +80,7 @@ describe LineItemsController, type: :controller do before { distributor.update_attributes!(allow_order_changes: true) } it "deletes the line item" do - delete :destroy, params + delete :destroy, params: params expect(response.status).to eq 204 expect { item.reload }.to raise_error ActiveRecord::RecordNotFound end @@ -91,7 +91,7 @@ describe LineItemsController, type: :controller do it 'updates the payment state' do expect(order.payment_state).to eq 'paid' - delete :destroy, params + delete :destroy, params: params order.reload expect(order.payment_state).to eq 'credit_owed' end @@ -103,37 +103,50 @@ describe LineItemsController, type: :controller do end context "on a completed order with shipping and payment fees" do + let(:zone) { create(:zone_with_member) } + let(:shipping_tax_rate) do + create(:tax_rate, included_in_price: true, + calculator: Calculator::DefaultTax.new, + amount: 0.25, + zone: zone) + end + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } let(:shipping_fee) { 3 } let(:payment_fee) { 5 } let(:distributor_with_taxes) { create(:distributor_enterprise_with_tax) } - let(:order) { create(:completed_order_with_fees, distributor: distributor_with_taxes, shipping_fee: shipping_fee, payment_fee: payment_fee) } + let(:order) { + create(:completed_order_with_fees, distributor: distributor_with_taxes, + shipping_fee: shipping_fee, payment_fee: payment_fee, + shipping_tax_category: shipping_tax_category) + } before do - Spree::Config.shipment_inc_vat = true - Spree::Config.shipping_tax_rate = 0.25 + allow(order).to receive(:tax_zone) { zone } + order.reload + order.create_tax_charge! end it "updates the fees" do # Sanity check fees item_num = order.line_items.length initial_fees = item_num * (shipping_fee + payment_fee) - expect(order.adjustment_total).to eq initial_fees - expect(order.shipments.last.fee_adjustment.included_tax).to eq 1.2 + + expect(order.shipment.adjustments.tax.count).to eq 1 + expect(order.shipment.included_tax_total).to eq 1.2 # Delete the item item = order.line_items.first allow(controller).to receive_messages spree_current_user: order.user - request = { format: :json, id: item } - delete :destroy, request + delete :destroy, format: :json, params: { id: item } expect(response.status).to eq 204 # Check the fees again order.reload order.shipment.reload expect(order.adjustment_total).to eq initial_fees - shipping_fee - payment_fee - expect(order.shipments.last.fee_adjustment.amount).to eq shipping_fee + expect(order.shipment.adjustment_total).to eq shipping_fee expect(order.payments.first.adjustment.amount).to eq payment_fee - expect(order.shipments.last.fee_adjustment.included_tax).to eq 0.6 + expect(order.shipment.included_tax_total).to eq 0.6 end end @@ -160,7 +173,7 @@ describe LineItemsController, type: :controller do expect(order.reload.adjustment_total).to eq calculator.preferred_discount_amount allow(controller).to receive_messages spree_current_user: user - delete :destroy, params + delete :destroy, params: params expect(response.status).to eq 204 expect(order.reload.adjustment_total).to eq calculator.preferred_normal_amount diff --git a/spec/controllers/spree/admin/adjustments_controller_spec.rb b/spec/controllers/spree/admin/adjustments_controller_spec.rb index 931112da4b..d36842e7ad 100644 --- a/spec/controllers/spree/admin/adjustments_controller_spec.rb +++ b/spec/controllers/spree/admin/adjustments_controller_spec.rb @@ -8,6 +8,41 @@ module Spree before { controller_login_as_admin } + describe "index" do + let!(:order) { create(:completed_order_with_totals) } + let!(:adjustment1) { + create(:adjustment, originator_type: "Spree::ShippingMethod", order: order, + adjustable: order.shipment) + } + let!(:adjustment2) { + create(:adjustment, originator_type: "Spree::PaymentMethod", eligible: true, order: order) + } + let!(:adjustment3) { + create(:adjustment, originator_type: "Spree::PaymentMethod", eligible: false, order: order) + } + let!(:adjustment4) { create(:adjustment, originator_type: "EnterpriseFee", order: order) } + let!(:adjustment5) { create(:adjustment, originator: nil, adjustable: order, order: order) } + + it "displays eligible adjustments" do + spree_get :index, order_id: order.number + + expect(assigns(:collection)).to include adjustment1, adjustment2 + expect(assigns(:collection)).to_not include adjustment3 + end + + it "displays admin adjustments" do + spree_get :index, order_id: order.number + + expect(assigns(:collection)).to include adjustment5 + end + + it "does not display enterprise fee adjustments" do + spree_get :index, order_id: order.number + + expect(assigns(:collection)).to_not include adjustment4 + end + end + describe "setting included tax" do let(:order) { create(:order) } let(:tax_rate) { create(:tax_rate, amount: 0.1, calculator: ::Calculator::DefaultTax.new) } @@ -72,5 +107,66 @@ module Spree end end end + + describe "#delete" do + let!(:order) { create(:completed_order_with_totals) } + let(:payment_fee) { create(:adjustment, amount: 0.50, order: order, adjustable: order.payments.first) } + + context "as an enterprise user with edit permissions on the order" do + before do + order.adjustments << payment_fee + controller_login_as_enterprise_user([order.distributor]) + end + + it "deletes the adjustment" do + spree_delete :destroy, order_id: order.number, id: payment_fee.id + + expect(response).to redirect_to spree.admin_order_adjustments_path(order) + expect(order.reload.all_adjustments.count).to be_zero + end + end + + context "as an enterprise user with no permissions on the order" do + before do + order.adjustments << payment_fee + controller_login_as_enterprise_user([create(:enterprise)]) + end + + it "is unauthorized, does not delete the adjustment" do + spree_delete :destroy, order_id: order.number, id: payment_fee.id + + expect(response).to redirect_to unauthorized_path + expect(order.reload.all_adjustments.count).to eq 1 + end + end + end + + describe "with a cancelled order" do + let(:order) { create(:completed_order_with_totals) } + let(:tax_rate) { create(:tax_rate, amount: 0.1, calculator: ::Calculator::DefaultTax.new) } + let(:adjustment) { + create(:adjustment, adjustable: order, order: order, amount: 1100, included_tax: 100) + } + + before do + expect(order.cancel).to eq true + end + + it "doesn't create adjustments" do + expect { + spree_post :create, order_id: order.number, adjustment: { label: "Testing", amount: "110" }, tax_rate_id: "" + }.to_not change { [Adjustment.count, order.reload.total] } + + expect(response).to redirect_to spree.admin_order_adjustments_path(order) + end + + it "doesn't change adjustments" do + expect { + spree_put :update, order_id: order.number, id: adjustment.id, adjustment: { label: "Testing", amount: "110" }, tax_rate_id: "" + }.to_not change { [adjustment.reload.amount, order.reload.total] } + + expect(response).to redirect_to spree.admin_order_adjustments_path(order) + end + end end end diff --git a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb index d7b67a7988..5ec3543894 100644 --- a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb +++ b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb @@ -45,12 +45,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "voids the payment" do order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 spree_put :fire, params expect(payment.reload.state).to eq 'void' order.reload expect(order.payment_total).to eq 0 - expect(order.outstanding_balance).to_not eq 0 + expect(order.outstanding_balance.to_f).to_not eq 0 end end @@ -64,12 +64,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "does not void the payment" do order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 expect(flash[:error]).to eq "Bup-bow!" end end @@ -104,12 +104,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "partially refunds the payment" do order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to eq order.total - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 end end @@ -123,12 +123,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "does not void the payment" do order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) expect(flash[:error]).to eq "Bup-bow!" end end @@ -169,12 +169,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "voids the payment" do order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 spree_put :fire, params expect(payment.reload.state).to eq 'void' order.reload expect(order.payment_total).to eq 0 - expect(order.outstanding_balance).to_not eq 0 + expect(order.outstanding_balance.to_f).to_not eq 0 end end @@ -189,12 +189,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "does not void the payment" do order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 expect(flash[:error]).to eq "Bup-bow!" end end @@ -211,12 +211,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "can still void the payment" do order.reload expect(order.payment_total).to_not eq 0 - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 spree_put :fire, params expect(payment.reload.state).to eq 'void' order.reload expect(order.payment_total).to eq 0 - expect(order.outstanding_balance).to_not eq 0 + expect(order.outstanding_balance.to_f).to_not eq 0 end end end @@ -252,12 +252,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "partially refunds the payment" do order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to eq order.total - expect(order.outstanding_balance).to eq 0 + expect(order.outstanding_balance.to_f).to eq 0 end end @@ -271,12 +271,12 @@ describe Spree::Admin::PaymentsController, type: :controller do it "does not void the payment" do order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) spree_put :fire, params expect(payment.reload.state).to eq 'completed' order.reload expect(order.payment_total).to eq order.total + 5 - expect(order.outstanding_balance).to eq(-5) + expect(order.outstanding_balance.to_f).to eq(-5) expect(flash[:error]).to eq "Bup-bow!" end end diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index 58daf89755..0d881bc82f 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -19,12 +19,14 @@ describe Spree::Admin::OrdersController, type: :controller do describe "view" do render_views - it "shows only eligible adjustments" do + it "does not show ineligible payment adjustments" do adjustment = create( :adjustment, - adjustable: order, + adjustable: build(:payment), + originator_type: "Spree::PaymentMethod", label: "invalid adjustment", eligible: false, + order: order, amount: 0 ) @@ -97,6 +99,40 @@ describe Spree::Admin::OrdersController, type: :controller do expect(order.reload.total).to eq order.item_total + (enterprise_fee.calculator.preferred_amount * 3) expect(order.adjustment_total).to eq enterprise_fee.calculator.preferred_amount * 3 end + + context "if the associated enterprise fee record is soft-deleted" do + it "removes adjustments for deleted enterprise fees" do + fee_amount = enterprise_fee.calculator.preferred_amount + + expect(order.total).to eq order.item_total + (fee_amount * 2) + expect(order.adjustment_total).to eq fee_amount * 2 + + enterprise_fee.destroy + + spree_put :update, { id: order.number } + + expect(order.reload.total).to eq order.item_total + expect(order.adjustment_total).to eq 0 + end + end + + context "if the associated enterprise fee record is hard-deleted" do + # Note: Enterprise fees are soft-deleted now, but we still have hard-deleted + # enterprise fees referenced as the originator of some adjustments (in production). + it "removes adjustments for deleted enterprise fees" do + fee_amount = enterprise_fee.calculator.preferred_amount + + expect(order.total).to eq order.item_total + (fee_amount * 2) + expect(order.adjustment_total).to eq fee_amount * 2 + + enterprise_fee.really_destroy! + + spree_put :update, { id: order.number } + + expect(order.reload.total).to eq order.item_total + expect(order.adjustment_total).to eq 0 + end + end end end diff --git a/spec/controllers/spree/admin/products_controller_spec.rb b/spec/controllers/spree/admin/products_controller_spec.rb index 081b85ebd8..7ee42b9aa2 100644 --- a/spec/controllers/spree/admin/products_controller_spec.rb +++ b/spec/controllers/spree/admin/products_controller_spec.rb @@ -66,7 +66,7 @@ describe Spree::Admin::ProductsController, type: :controller do ] expect(response).to redirect_to( - '/api/products/bulk_products' + '/api/v0/products/bulk_products' ) end end diff --git a/spec/controllers/spree/admin/reports_controller_spec.rb b/spec/controllers/spree/admin/reports_controller_spec.rb index 964ea31d62..4ae4e0cf13 100644 --- a/spec/controllers/spree/admin/reports_controller_spec.rb +++ b/spec/controllers/spree/admin/reports_controller_spec.rb @@ -291,6 +291,25 @@ describe Spree::Admin::ReportsController, type: :controller do end end + + context 'Order Cycle Management' do + let!(:present_objects) { [orderA1, orderA2, orderB1, orderB2] } + + before do + controller_login_as_enterprise_user [coordinator1] + end + + it 'renders the delivery report' do + spree_post :order_cycle_management, { + q: { completed_at_lt: 1.day.ago }, + shipping_method_in: [ "123" ], # We just need to search for shipping methods + report_type: "delivery", + } + + expect(response).to have_http_status(:ok) + end + end + context "Admin" do before { controller_login_as_admin } diff --git a/spec/controllers/spree/admin/tax_settings_controller_spec.rb b/spec/controllers/spree/admin/tax_settings_controller_spec.rb index 7b64d4e2cd..dbb320b1c6 100644 --- a/spec/controllers/spree/admin/tax_settings_controller_spec.rb +++ b/spec/controllers/spree/admin/tax_settings_controller_spec.rb @@ -4,15 +4,7 @@ require 'spec_helper' describe Spree::Admin::TaxSettingsController, type: :controller do describe "#update" do - let(:params) { - { - preferences: { - products_require_tax_category: "1", - shipment_inc_vat: "0", - shipping_tax_rate: "0.1", - } - } - } + let(:params) { { preferences: { products_require_tax_category: "1" } } } before do allow(controller).to receive(:spree_current_user) { create(:admin_user) } @@ -21,19 +13,7 @@ describe Spree::Admin::TaxSettingsController, type: :controller do it "changes Tax settings" do expect { spree_post :update, params - }.to change { - [ - Spree::Config[:products_require_tax_category], - Spree::Config[:shipment_inc_vat], - Spree::Config[:shipping_tax_rate], - ] - }.to( - [ - true, - false, - 0.1, - ] - ) + }.to change { Spree::Config[:products_require_tax_category] }.to(true) end end end diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index f136a51f64..36f5b4f386 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' describe Spree::OrdersController, type: :controller do include OpenFoodNetwork::EmailHelper + include CheckoutHelper let(:distributor) { double(:distributor) } let(:order) { create(:order) } @@ -22,12 +23,12 @@ describe Spree::OrdersController, type: :controller do let(:current_user) { nil } it "loads page" do - get :show, id: order.number, token: order.token + get :show, params: { id: order.number, token: order.token } expect(response).to be_success end it "stores order token in session as 'access_token'" do - get :show, id: order.number, token: order.token + get :show, params: { id: order.number, token: order.token } expect(session[:access_token]).to eq(order.token) end end @@ -41,7 +42,7 @@ describe Spree::OrdersController, type: :controller do end it "loads page" do - get :show, id: order.number + get :show, params: { id: order.number } expect(response).to be_success end end @@ -50,7 +51,7 @@ describe Spree::OrdersController, type: :controller do let(:current_user) { order.user } it "loads page" do - get :show, id: order.number + get :show, params: { id: order.number } expect(response).to be_success end end @@ -59,7 +60,7 @@ describe Spree::OrdersController, type: :controller do let(:current_user) { create(:user) } it "redirects to unauthorized" do - get :show, id: order.number + get :show, params: { id: order.number } expect(response).to redirect_to unauthorized_path end end @@ -72,7 +73,7 @@ describe Spree::OrdersController, type: :controller do end it "redirects to unauthorized" do - get :show, id: order.number + get :show, params: { id: order.number } expect(response).to redirect_to(root_path(anchor: "login?after_login=#{order_path(order)}")) expect(flash[:error]).to eq("Please log in to view your order.") end @@ -101,7 +102,7 @@ describe Spree::OrdersController, type: :controller do let(:payment_intent) { "pi_123" } it "completes the payment" do - get :show, id: order.number, payment_intent: payment_intent + get :show, params: { id: order.number, payment_intent: payment_intent } expect(response).to be_success payment.reload expect(payment.cvv_response_message).to be nil @@ -113,7 +114,7 @@ describe Spree::OrdersController, type: :controller do let(:payment_intent) { "invalid" } it "does not complete the payment" do - get :show, id: order.number, payment_intent: payment_intent + get :show, params: { id: order.number, payment_intent: payment_intent } expect(response).to be_success payment.reload expect(payment.cvv_response_message).to eq("https://stripe.com/redirect") @@ -225,10 +226,10 @@ describe Spree::OrdersController, type: :controller do it "should silently ignore the missing line item" do order = subject.current_order(true) li = order.add_variant(create(:simple_product, on_hand: 110).variants.first) - get :update, order: { line_items_attributes: { + get :update, params: { order: { line_items_attributes: { "0" => { quantity: "0", id: "9999" }, "1" => { quantity: "99", id: li.id } - } } + } } } expect(response.status).to eq(302) expect(li.reload.quantity).to eq(99) end @@ -253,9 +254,9 @@ describe Spree::OrdersController, type: :controller do line_item = order.add_variant(create(:simple_product, on_hand: 110).variants.first) adjustment = create(:adjustment, adjustable: order) - get :update, order: { line_items_attributes: { + get :update, params: { order: { line_items_attributes: { "1" => { quantity: "99", id: line_item.id } - } } + } } } expect(adjustment.state).to eq('open') end @@ -264,7 +265,12 @@ describe Spree::OrdersController, type: :controller do describe "removing items from a completed order" do context "with shipping and transaction fees" do let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) } - let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, included_in_price: true, zone: create(:zone_with_member)) } + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } + let(:order) { + create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, + payment_fee: payment_fee, shipping_tax_category: shipping_tax_category) + } let(:line_item1) { order.line_items.first } let(:line_item2) { order.line_items.second } let(:shipping_fee) { 3 } @@ -273,14 +279,16 @@ describe Spree::OrdersController, type: :controller do let(:expected_fees) { item_num * (shipping_fee + payment_fee) } before do - allow(Spree::Config).to receive(:shipment_inc_vat) { true } - allow(Spree::Config).to receive(:shipping_tax_rate) { 0.25 } + allow(order).to receive(:tax_zone) { shipping_tax_rate.zone } + order.reload + order.create_tax_charge! # Sanity check the fees - expect(order.all_adjustments.length).to eq 2 + expect(order.all_adjustments.length).to eq 3 expect(item_num).to eq 2 expect(order.adjustment_total).to eq expected_fees - expect(order.shipment.fee_adjustment.included_tax).to eq 1.2 + expect(order.shipment.adjustments.tax.first.amount).to eq 1.2 + expect(order.shipment.included_tax_total).to eq 1.2 allow(subject).to receive(:spree_current_user) { order.user } allow(subject).to receive(:order_to_update) { order } @@ -295,7 +303,8 @@ describe Spree::OrdersController, type: :controller do expect(order.reload.line_items.count).to eq 1 expect(order.adjustment_total).to eq(1 * (shipping_fee + payment_fee)) - expect(order.shipment.fee_adjustment.included_tax).to eq 0.6 + expect(order.shipment.adjustments.tax.first.amount).to eq 0.6 + expect(order.shipment.included_tax_total).to eq 0.6 end end diff --git a/spec/controllers/spree/paypal_controller_spec.rb b/spec/controllers/spree/paypal_controller_spec.rb index 5e55a6d02d..b239667772 100644 --- a/spec/controllers/spree/paypal_controller_spec.rb +++ b/spec/controllers/spree/paypal_controller_spec.rb @@ -4,13 +4,13 @@ require 'spec_helper' module Spree describe PaypalController, type: :controller do - context 'when cancelling' do + context '#cancel' do it 'redirects back to checkout' do expect(spree_get(:cancel)).to redirect_to checkout_path end end - context 'when confirming' do + context '#confirm' do let(:previous_order) { controller.current_order(true) } let(:payment_method) { create(:payment_method) } @@ -44,6 +44,59 @@ module Spree expect(order.payments.count).to eq 0 end end + + context "when order completion fails" do + before do + allow(previous_order).to receive(:complete?).and_return(false) + end + + it "redirects to checkout state path" do + expect(spree_post(:confirm, payment_method_id: payment_method.id)). + to redirect_to checkout_state_path(:cart) + end + end + end + + describe "#express" do + let(:order) { create(:order_with_distributor) } + let(:response) { true } + let(:provider_success_url) { "https://test.com/success" } + let(:response_mock) { double(:response, success?: response, errors: [] ) } + let(:provider_mock) { double(:provider, build_set_express_checkout: true, + set_express_checkout: response_mock, + express_checkout_url: provider_success_url) } + + before do + allow(controller).to receive(:current_order) { order } + allow(controller).to receive(:provider) { provider_mock } + allow(controller).to receive(:express_checkout_request_details) { {} } + end + + context "when processing is successful" do + it "redirects to a success URL generated by the payment provider" do + expect(spree_post :express).to redirect_to provider_success_url + end + end + + context "when processing fails" do + let(:response) { false } + + it "redirects to checkout_state_path with a flash error" do + expect(spree_post :express).to redirect_to checkout_state_path(:payment) + expect(flash[:error]).to eq "PayPal failed. " + end + end + + context "when a SocketError is encountered during processing" do + before do + allow(response_mock).to receive(:success?).and_raise(SocketError) + end + + it "redirects to checkout_state_path with a flash error" do + expect(spree_post :express).to redirect_to checkout_state_path(:payment) + expect(flash[:error]).to eq "Could not connect to PayPal." + end + end end describe '#expire_current_order' do diff --git a/spec/controllers/spree/users_controller_spec.rb b/spec/controllers/spree/users_controller_spec.rb index 49381e997d..4115860b33 100644 --- a/spec/controllers/spree/users_controller_spec.rb +++ b/spec/controllers/spree/users_controller_spec.rb @@ -21,6 +21,8 @@ describe Spree::UsersController, type: :controller do let(:orders) { assigns(:orders) } let(:shops) { Enterprise.where(id: orders.pluck(:distributor_id)) } + let(:outstanding_balance) { instance_double(OutstandingBalance) } + before do allow(controller).to receive(:spree_current_user) { u1 } end @@ -43,20 +45,11 @@ describe Spree::UsersController, type: :controller do expect(orders).not_to include d1o3 end - context 'when the customer_balance feature is enabled' do - let(:outstanding_balance) { instance_double(OutstandingBalance) } + it 'calls OutstandingBalance' do + allow(OutstandingBalance).to receive(:new).and_return(outstanding_balance) + expect(outstanding_balance).to receive(:query) { Spree::Order.none } - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, controller.spree_current_user) { true } - end - - it 'calls OutstandingBalance' do - allow(OutstandingBalance).to receive(:new).and_return(outstanding_balance) - expect(outstanding_balance).to receive(:query) { Spree::Order.none } - - spree_get :show - end + spree_get :show end end @@ -66,12 +59,12 @@ describe Spree::UsersController, type: :controller do let!(:user) { create(:user) } it "returns true if email corresponds to a registered user" do - post :registered_email, email: user.email + post :registered_email, params: { email: user.email } expect(json_response['registered']).to eq true end it "returns false if email does not correspond to a registered user" do - post :registered_email, email: 'nonregistereduser@example.com' + post :registered_email, params: { email: 'nonregistereduser@example.com' } expect(json_response['registered']).to eq false end end @@ -79,14 +72,14 @@ describe Spree::UsersController, type: :controller do context '#load_object' do it 'should redirect to signup path if user is not found' do allow(controller).to receive_messages(spree_current_user: nil) - put :update, user: { email: 'foobar@example.com' } + put :update, params: { user: { email: 'foobar@example.com' } } expect(response).to redirect_to('/login') end end context '#create' do it 'should create a new user' do - post :create, user: { email: 'foobar@example.com', password: 'foobar123', password_confirmation: 'foobar123' } + post :create, params: { user: { email: 'foobar@example.com', password: 'foobar123', password_confirmation: 'foobar123' } } expect(assigns[:user].new_record?).to be_falsey end end diff --git a/spec/controllers/stripe/webhooks_controller_spec.rb b/spec/controllers/stripe/webhooks_controller_spec.rb index 437c10b55c..c8390ca6e1 100644 --- a/spec/controllers/stripe/webhooks_controller_spec.rb +++ b/spec/controllers/stripe/webhooks_controller_spec.rb @@ -21,7 +21,7 @@ describe Stripe::WebhooksController, type: :controller do end it "responds with a 400" do - post 'create', params + post 'create', params: params expect(response.status).to eq 400 end end @@ -32,7 +32,7 @@ describe Stripe::WebhooksController, type: :controller do end it "responds with a 401" do - post 'create', params + post 'create', params: params expect(response.status).to eq 401 end end @@ -50,7 +50,7 @@ describe Stripe::WebhooksController, type: :controller do before { allow(handler).to receive(:handle) { :garbage } } it "falls back to 200" do - post 'create', params + post 'create', params: params expect(response.status).to eq 200 end end @@ -59,7 +59,7 @@ describe Stripe::WebhooksController, type: :controller do before { allow(handler).to receive(:handle) { :unknown } } it "responds with 202" do - post 'create', params + post 'create', params: params expect(response.status).to eq 202 end end @@ -73,7 +73,7 @@ describe Stripe::WebhooksController, type: :controller do context "when the stripe_account id on the event does not match any known accounts" do it "doesn't delete any Stripe accounts, responds with 204" do - post 'create', params + post 'create', params: params expect(response.status).to eq 204 expect(StripeAccount.all).to include stripe_account end @@ -83,7 +83,7 @@ describe Stripe::WebhooksController, type: :controller do before { params["account"] = "webhook_id" } it "deletes Stripe accounts in response to a webhook" do - post 'create', params + post 'create', params: params expect(response.status).to eq 200 expect(StripeAccount.all).not_to include stripe_account end diff --git a/spec/controllers/user_passwords_controller_spec.rb b/spec/controllers/user_passwords_controller_spec.rb index 72e399adf2..f66c7d1bf8 100644 --- a/spec/controllers/user_passwords_controller_spec.rb +++ b/spec/controllers/user_passwords_controller_spec.rb @@ -49,13 +49,13 @@ describe UserPasswordsController, type: :controller do describe "via ajax" do it "returns error when email not found" do - xhr :post, :create, spree_user: {}, use_route: :spree + post :create, xhr: true, params: { spree_user: {}, use_route: :spree } expect(response.status).to eq 404 expect(json_response).to eq 'error' => I18n.t('email_not_found') end it "returns error when user is unconfirmed" do - xhr :post, :create, spree_user: { email: unconfirmed_user.email }, use_route: :spree + post :create, xhr: true, params: { spree_user: { email: unconfirmed_user.email }, use_route: :spree } expect(response.status).to eq 401 expect(json_response).to eq 'error' => I18n.t('email_unconfirmed') end diff --git a/spec/controllers/user_registrations_controller_spec.rb b/spec/controllers/user_registrations_controller_spec.rb index b659266c64..9e77be34f2 100644 --- a/spec/controllers/user_registrations_controller_spec.rb +++ b/spec/controllers/user_registrations_controller_spec.rb @@ -25,7 +25,7 @@ describe UserRegistrationsController, type: :controller do end it "returns validation errors" do - xhr :post, :create, spree_user: {}, use_route: :spree + post :create, xhr: true, params: { spree_user: {}, use_route: :spree } expect(response.status).to eq(401) json = JSON.parse(response.body) expect(json).to eq("email" => ["can't be blank"], "password" => ["can't be blank"]) @@ -35,7 +35,7 @@ describe UserRegistrationsController, type: :controller do allow(Spree::UserMailer).to receive(:confirmation_instructions).and_raise("Some error") expect(OpenFoodNetwork::ErrorLogger).to receive(:notify) - xhr :post, :create, spree_user: user_params, use_route: :spree + post :create, xhr: true, params: { spree_user: user_params, use_route: :spree } expect(response.status).to eq(401) json = JSON.parse(response.body) @@ -43,7 +43,7 @@ describe UserRegistrationsController, type: :controller do end it "returns 200 when registration succeeds" do - xhr :post, :create, spree_user: user_params, use_route: :spree + post :create, xhr: true, params: { spree_user: user_params, use_route: :spree } expect(response.status).to eq(200) json = JSON.parse(response.body) expect(json).to eq("email" => "test@test.com") @@ -55,7 +55,7 @@ describe UserRegistrationsController, type: :controller do original_locale_cookie = cookies[:locale] cookies[:locale] = "pt" - xhr :post, :create, spree_user: user_params, use_route: :spree + post :create, xhr: true, params: { spree_user: user_params, use_route: :spree } expect(assigns[:user].locale).to eq("pt") I18n.locale = original_i18n_locale diff --git a/spec/factories/adjustment_factory.rb b/spec/factories/adjustment_factory.rb index 96360610b3..4b9fa8748f 100644 --- a/spec/factories/adjustment_factory.rb +++ b/spec/factories/adjustment_factory.rb @@ -5,7 +5,6 @@ FactoryBot.define do association(:adjustable, factory: :order) amount { 100.0 } label { 'Shipping' } - association(:source, factory: :shipment) eligible { true } end end diff --git a/spec/factories/calculator_factory.rb b/spec/factories/calculator_factory.rb index 3142de884c..91c571a8fe 100644 --- a/spec/factories/calculator_factory.rb +++ b/spec/factories/calculator_factory.rb @@ -25,4 +25,6 @@ FactoryBot.define do c.save! } end + + factory :default_tax_calculator, class: Calculator::DefaultTax end diff --git a/spec/factories/order_cycle_factory.rb b/spec/factories/order_cycle_factory.rb index a241672f6d..fadce85de2 100644 --- a/spec/factories/order_cycle_factory.rb +++ b/spec/factories/order_cycle_factory.rb @@ -4,41 +4,32 @@ FactoryBot.define do factory :order_cycle, parent: :simple_order_cycle do coordinator_fees { [create(:enterprise_fee, enterprise: coordinator)] } - after(:create) do |oc| - # Suppliers - supplier1 = create(:supplier_enterprise) - supplier2 = create(:supplier_enterprise) + transient do + suppliers { + [create(:supplier_enterprise), create(:supplier_enterprise)] + } + distributors { + [create(:distributor_enterprise), create(:distributor_enterprise)] + } + end - # Incoming Exchanges - ex1 = create(:exchange, order_cycle: oc, incoming: true, - sender: supplier1, receiver: oc.coordinator, - receival_instructions: 'instructions 0') - ex2 = create(:exchange, order_cycle: oc, incoming: true, - sender: supplier2, receiver: oc.coordinator, - receival_instructions: 'instructions 1') - ExchangeFee.create!(exchange: ex1, - enterprise_fee: create(:enterprise_fee, enterprise: ex1.sender)) - ExchangeFee.create!(exchange: ex2, - enterprise_fee: create(:enterprise_fee, enterprise: ex2.sender)) + after(:create) do |oc, proxy| + proxy.exchanges.incoming.each do |exchange| + ExchangeFee.create!( + exchange: exchange, + enterprise_fee: create(:enterprise_fee, enterprise: exchange.sender) + ) + end - # Distributors - distributor1 = create(:distributor_enterprise) - distributor2 = create(:distributor_enterprise) - - # Outgoing Exchanges - ex3 = create(:exchange, order_cycle: oc, incoming: false, - sender: oc.coordinator, receiver: distributor1, - pickup_time: 'time 0', pickup_instructions: 'instructions 0') - ex4 = create(:exchange, order_cycle: oc, incoming: false, - sender: oc.coordinator, receiver: distributor2, - pickup_time: 'time 1', pickup_instructions: 'instructions 1') - ExchangeFee.create!(exchange: ex3, - enterprise_fee: create(:enterprise_fee, enterprise: ex3.receiver)) - ExchangeFee.create!(exchange: ex4, - enterprise_fee: create(:enterprise_fee, enterprise: ex4.receiver)) + proxy.exchanges.outgoing.each do |exchange| + ExchangeFee.create!( + exchange: exchange, + enterprise_fee: create(:enterprise_fee, enterprise: exchange.receiver) + ) + end # Products with images - [ex1, ex2].each do |exchange| + proxy.exchanges.incoming.each do |exchange| product = create(:product, supplier: exchange.sender) image = File.open(File.expand_path('../../app/assets/images/logo-white.png', __dir__)) Spree::Image.create( @@ -52,8 +43,8 @@ FactoryBot.define do exchange.variants << product.variants.first end - variants = [ex1, ex2].map(&:variants).flatten - [ex3, ex4].each do |exchange| + variants = proxy.exchanges.incoming.map(&:variants).flatten + proxy.exchanges.outgoing.each do |exchange| variants.each { |v| exchange.variants << v } end end @@ -84,22 +75,24 @@ FactoryBot.define do end after(:create) do |oc, proxy| - proxy.suppliers.each do |supplier| + # Incoming Exchanges + proxy.suppliers.each.with_index do |supplier, i| ex = create(:exchange, order_cycle: oc, sender: supplier, receiver: oc.coordinator, incoming: true, - receival_instructions: 'instructions') + receival_instructions: "instructions #{i}") proxy.variants.each { |v| ex.variants << v } end - proxy.distributors.each do |distributor| + # Outgoing Exchanges + proxy.distributors.each.with_index do |distributor, i| ex = create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: distributor, incoming: false, - pickup_time: 'time', - pickup_instructions: 'instructions') + pickup_time: "time #{i}", + pickup_instructions: "instructions #{i}") proxy.variants.each { |v| ex.variants << v } end end diff --git a/spec/factories/order_factory.rb b/spec/factories/order_factory.rb index 7e75d7a05f..eab716bd0b 100644 --- a/spec/factories/order_factory.rb +++ b/spec/factories/order_factory.rb @@ -196,6 +196,7 @@ FactoryBot.define do transient do payment_fee { 5 } shipping_fee { 3 } + shipping_tax_category { nil } end ship_address { create(:address) } @@ -214,7 +215,8 @@ FactoryBot.define do state: 'checkout') create(:shipping_method_with, :shipping_fee, shipping_fee: evaluator.shipping_fee, - distributors: [order.distributor]) + distributors: [order.distributor], + tax_category: evaluator.shipping_tax_category) order.reload while !order.completed? do break unless order.next! end diff --git a/spec/factories/product_factory.rb b/spec/factories/product_factory.rb index bfe9791ccd..aefd7ba399 100644 --- a/spec/factories/product_factory.rb +++ b/spec/factories/product_factory.rb @@ -22,7 +22,7 @@ FactoryBot.define do shipping_category { DefaultShippingCategory.find_or_create } # ensure stock item will be created for this products master - before(:create) { create(:stock_location) if Spree::StockLocation.count == 0 } + before(:create) { create(:stock_location) if Spree::StockLocation.count.zero? } factory :product do transient do diff --git a/spec/factories/tag_rule_factory.rb b/spec/factories/tag_rule_factory.rb index 0dbdc6a208..e5a4b9286d 100644 --- a/spec/factories/tag_rule_factory.rb +++ b/spec/factories/tag_rule_factory.rb @@ -16,11 +16,4 @@ FactoryBot.define do factory :filter_payment_methods_tag_rule, class: TagRule::FilterPaymentMethods do enterprise factory: :distributor_enterprise end - - factory :tag_rule, class: TagRule::DiscountOrder do - enterprise { FactoryBot.create :distributor_enterprise } - before(:create) do |tr| - tr.calculator = Calculator::FlatPercentItemTotal.new(calculable: tr) - end - end end diff --git a/spec/factories/tax_rate_factory.rb b/spec/factories/tax_rate_factory.rb index 2cb9f6e780..fa72254674 100644 --- a/spec/factories/tax_rate_factory.rb +++ b/spec/factories/tax_rate_factory.rb @@ -3,7 +3,8 @@ FactoryBot.define do factory :tax_rate, class: Spree::TaxRate do zone - amount { 100.00 } + amount { 0.1 } tax_category + association(:calculator, factory: :default_tax_calculator, strategy: :build) end end diff --git a/spec/factories/variant_factory.rb b/spec/factories/variant_factory.rb index d1586dc19a..61badeed3e 100644 --- a/spec/factories/variant_factory.rb +++ b/spec/factories/variant_factory.rb @@ -15,7 +15,7 @@ FactoryBot.define do option_values { [create(:option_value)] } # ensure stock item will be created for this variant - before(:create) { create(:stock_location) if Spree::StockLocation.count == 0 } + before(:create) { create(:stock_location) if Spree::StockLocation.count.zero? } factory :variant do transient do diff --git a/spec/features/admin/adjustments_spec.rb b/spec/features/admin/adjustments_spec.rb index 9d74afd410..9e6b192bc3 100644 --- a/spec/features/admin/adjustments_spec.rb +++ b/spec/features/admin/adjustments_spec.rb @@ -87,4 +87,18 @@ feature ' expect(page).to have_selector 'td.amount', text: '110' expect(page).to have_selector 'td.included-tax', text: '10' end + + scenario "viewing adjustments on a canceled order" do + # Given a taxed adjustment + adjustment = create(:adjustment, label: "Extra Adjustment", adjustable: order, + amount: 110, included_tax: 10, order: order) + order.cancel! + + login_as_admin_and_visit spree.edit_admin_order_path(order) + + click_link 'Adjustments' + + expect(page).to_not have_selector('tr a.icon-edit') + expect(page).to_not have_selector('a.icon-plus'), text: I18n.t(:new_adjustment) + end end diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 5a1aae73de..943171eef5 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -199,7 +199,7 @@ feature ' expect(page).to have_field "price", with: "100.00" end click_button "Save Changes" - expect(page).to have_no_selector "#save-bar" + expect(page).to have_content "All changes saved" li1.reload expect(li1.final_weight_volume).to eq 2000 expect(li1.price).to eq 20.00 diff --git a/spec/features/admin/customers_spec.rb b/spec/features/admin/customers_spec.rb index b115d0f98d..f6ff3689f0 100644 --- a/spec/features/admin/customers_spec.rb +++ b/spec/features/admin/customers_spec.rb @@ -104,9 +104,6 @@ feature 'Customers' do let!(:payment1) { create(:payment, order: order1, state: 'completed', payment_method: payment_method, response_code: 'pi_123', amount: 88.00) } before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } - customer4.update enterprise: managed_distributor1 end @@ -133,6 +130,11 @@ feature 'Customers' do context "with an additional negative payment (or refund)" do let!(:payment2) { create(:payment, order: order1, state: 'completed', payment_method: payment_method, response_code: 'pi_123', amount: -25.00) } + before do + order1.user = user + order1.save! + end + it "displays an updated customer balance" do visit spree.admin_order_payments_path order1 expect(page).to have_content "$#{payment2.amount}" diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb index 4d5a37a8c8..32652eee59 100644 --- a/spec/features/admin/enterprises_spec.rb +++ b/spec/features/admin/enterprises_spec.rb @@ -237,7 +237,7 @@ feature ' expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s) # And the producer should have the property - expect(s.producer_properties(true).count).to eq(1) + expect(s.producer_properties.reload.count).to eq(1) expect(s.producer_properties.first.property.presentation).to eq("Certified Organic") expect(s.producer_properties.first.value).to eq("NASAA 12345") end @@ -259,7 +259,7 @@ feature ' expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s) # And the property should be updated - expect(s.producer_properties(true).count).to eq(1) + expect(s.producer_properties.reload.count).to eq(1) expect(s.producer_properties.first.property.presentation).to eq("Biodynamic") expect(s.producer_properties.first.value).to eq("Shininess") end @@ -280,7 +280,7 @@ feature ' # Then the property should have been removed expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s) expect(page).not_to have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic' - expect(s.producer_properties(true)).to be_empty + expect(s.producer_properties.reload).to be_empty end end @@ -422,7 +422,7 @@ feature ' page.evaluate_script("angular.element(enterprise_form).scope().setFormDirty()") click_button 'Update' - expect(supplier1.producer_properties(true).count).to eq(1) + expect(supplier1.producer_properties.reload.count).to eq(1) # -- Destroy pp = supplier1.producer_properties.first @@ -440,7 +440,7 @@ feature ' click_button 'Update' expect(page).to have_content 'Enterprise "First Supplier" has been successfully updated!' - expect(supplier1.producer_properties(true)).to be_empty + expect(supplier1.producer_properties.reload).to be_empty end end end diff --git a/spec/features/admin/external_services_spec.rb b/spec/features/admin/external_services_spec.rb deleted file mode 100644 index e4ec773840..0000000000 --- a/spec/features/admin/external_services_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -feature 'External services' do - include AuthenticationHelper - - describe "bugherd" do - before do - Spree::Config.bugherd_api_key = nil - login_to_admin_section - end - - it "lets me set an API key" do - visit spree.edit_admin_general_settings_path - - fill_in 'bugherd_api_key', with: 'abc123' - click_button 'Update' - - expect(page).to have_content 'General Settings has been successfully updated!' - expect(Spree::Config.bugherd_api_key).to eq 'abc123' - end - end -end diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb index c13e0dd8b1..892438c003 100644 --- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -16,7 +16,7 @@ feature ' let!(:new_product) { create(:product, supplier: supplier_enterprise) } before do - stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) + stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) login_as_admin_and_visit admin_order_cycle_incoming_path(order_cycle) expect(page).to have_content "1 / 2 selected" diff --git a/spec/features/admin/order_print_ticket_spec.rb b/spec/features/admin/order_print_ticket_spec.rb index 15fd46692a..9bfddf205d 100644 --- a/spec/features/admin/order_print_ticket_spec.rb +++ b/spec/features/admin/order_print_ticket_spec.rb @@ -75,7 +75,7 @@ feature ' def adjustments_in_print_data checkout_adjustments_for(order, exclude: [:line_item]). - reject { |a| a.amount == 0 }. + reject { |a| a.amount.zero? }. map do |adjustment| [raw(adjustment.label), display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index db430ceb18..17d8a99658 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -61,6 +61,13 @@ feature ' select2_select order_cycle.name, from: 'order_order_cycle_id' click_button 'Next' + expect(page).not_to have_selector '.flash.error' + expect(page).not_to have_content "Line items can't be blank" + + click_button "Update And Recalculate Fees" + expect(page).to have_selector '.flash.error' + expect(page).to have_content "Line items can't be blank" + # it suppresses validation errors when setting distribution expect(page).not_to have_selector '#errorExplanation' expect(page).to have_content 'ADD PRODUCT' @@ -85,7 +92,7 @@ feature ' find('button.add_variant').click expect(page).to have_selector 'td', text: product.name - expect(order.line_items(true).map(&:product)).to include product + expect(order.line_items.reload.map(&:product)).to include product end scenario "displays error when incorrect distribution for products is chosen" do @@ -146,6 +153,27 @@ feature ' expect(order.reload.line_items.first.quantity).to eq(max_quantity) end + scenario "there are infinite items available (variant is on demand)" do + # Move the order back to the cart state + order.state = 'cart' + order.completed_at = nil + order.line_items.first.variant.update_attribute(:on_demand, true) + + login_as_admin_and_visit spree.edit_admin_order_path(order) + + within("tr.stock-item", text: order.products.first.name) do + find("a.edit-item").click + expect(page).to have_input(:quantity) + fill_in(:quantity, with: 1000) + find("a.save-item").click + end + + within("tr.stock-item", text: order.products.first.name) do + expect(page).to have_text("1000 x") + end + expect(order.reload.line_items.first.quantity).to eq(1000) + end + scenario "can't change distributor or order cycle once order has been finalized" do login_as_admin_and_visit spree.edit_admin_order_path(order) @@ -343,6 +371,16 @@ feature ' end end end + + context "and the order has been canceled" do + it "does not allow modifying line items" do + order.cancel! + visit spree.edit_admin_order_path(order) + within("tr.stock-item", text: order.products.first.name) do + expect(page).to_not have_selector("a.edit-item") + end + end + end end scenario "creating an order with distributor and order cycle" do diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 7408d53005..63e9feb687 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -65,7 +65,7 @@ feature ' context "with a capturable order" do before do order.finalize! # ensure order has a payment to capture - create :check_payment, order: order, amount: order.total + order.payments << create(:check_payment, order: order, amount: order.total) end scenario "capture payment" do diff --git a/spec/features/admin/payments_spec.rb b/spec/features/admin/payments_spec.rb index 2c670c44ee..d6c5f38d66 100644 --- a/spec/features/admin/payments_spec.rb +++ b/spec/features/admin/payments_spec.rb @@ -10,10 +10,13 @@ feature ' let(:order) { create(:completed_order_with_fees) } - scenario "visiting the payment form" do - login_as_admin_and_visit spree.new_admin_order_payment_path order + describe "payments/new" do + it "displays the order balance as the default payment amount" do + login_as_admin_and_visit spree.new_admin_order_payment_path order - expect(page).to have_content "New Payment" + expect(page).to have_content I18n.t(:new_payment) + expect(page).to have_field(:payment_amount, with: order.outstanding_balance.to_f) + end end context "with sensitive payment fee" do @@ -26,10 +29,10 @@ feature ' payment_method.save! end - scenario "visiting the payment form" do + it "renders the new payment page" do login_as_admin_and_visit spree.new_admin_order_payment_path order - expect(page).to have_content "New Payment" + expect(page).to have_content I18n.t(:new_payment) end end end diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index e2a3b8a3c3..9e4544f657 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -470,16 +470,39 @@ feature ' expect("#{uri.path}?#{uri.query}").to eq spree.admin_product_images_path(product, filter) end - scenario "editing a product's variant unit scale", js: true do - product = create(:simple_product, name: 'a product', supplier: @supplier2) + context "editing a product's variant unit scale", js: true do + let(:product) { create(:simple_product, name: 'a product', supplier: @supplier2) } - visit spree.edit_admin_product_path product - select 'Weight (kg)', from: 'product_variant_unit_with_scale' - click_button 'Update' - expect(flash_message).to eq('Product "a product" has been successfully updated!') - product.reload - expect(product.variant_unit).to eq('weight') - expect(product.variant_unit_scale).to eq(1000) + # TODO below -> assertions commented out refer to bug: + # https://github.com/openfoodfoundation/openfoodnetwork/issues/7180 + + before do + allow(Spree::Config).to receive(:available_units).and_return("g,lb,oz,kg,T,mL,L,kL") + visit spree.edit_admin_product_path product + end + + shared_examples 'selecting a unit from dropdown' do |dropdown_option, var_unit:, var_unit_scale:| + it 'checks if the dropdown selection is persistent' do + select dropdown_option, from: 'product_variant_unit_with_scale' + click_button 'Update' + expect(flash_message).to eq('Product "a product" has been successfully updated!') + product.reload + expect(product.variant_unit).to eq(var_unit) + expect(page).to have_select('product_variant_unit_with_scale', selected: dropdown_option) + expect(product.variant_unit_scale).to eq(var_unit_scale) + end + end + + describe 'a shared example' do + it_behaves_like 'selecting a unit from dropdown', 'Weight (g)', var_unit: 'weight', var_unit_scale: 1 + it_behaves_like 'selecting a unit from dropdown', 'Weight (kg)', var_unit: 'weight', var_unit_scale: 1000 + it_behaves_like 'selecting a unit from dropdown', 'Weight (T)', var_unit: 'weight', var_unit_scale: 1_000_000 + it_behaves_like 'selecting a unit from dropdown', 'Weight (oz)', var_unit: 'weight', var_unit_scale: 28.35 + it_behaves_like 'selecting a unit from dropdown', 'Weight (lb)', var_unit: 'weight', var_unit_scale: 453.6 + it_behaves_like 'selecting a unit from dropdown', 'Volume (mL)', var_unit: 'volume', var_unit_scale: 0.001 + it_behaves_like 'selecting a unit from dropdown', 'Volume (L)', var_unit: 'volume', var_unit_scale: 1 + it_behaves_like 'selecting a unit from dropdown', 'Volume (kL)', var_unit: 'volume', var_unit_scale: 1000 + end end end end diff --git a/spec/features/admin/reports/payments_report_spec.rb b/spec/features/admin/reports/payments_report_spec.rb index b618bae352..11c828593e 100644 --- a/spec/features/admin/reports/payments_report_spec.rb +++ b/spec/features/admin/reports/payments_report_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' describe "Payments Reports" do include AuthenticationHelper - let!(:order) do + let(:order) do create( :order_with_distributor, state: 'complete', @@ -13,37 +13,87 @@ describe "Payments Reports" do order_cycle: order_cycle ) end - let(:order_cycle) { create(:simple_order_cycle) } - let!(:line_item) do - create(:line_item_with_shipment, order: order, product: product) + let(:other_order) do + create( + :order_with_distributor, + state: 'complete', + completed_at: Time.zone.now, + order_cycle: order_cycle, + distributor: order.distributor + ) end + let(:order_cycle) { create(:simple_order_cycle) } let(:product) { create(:product, supplier: supplier) } let(:supplier) { create(:supplier_enterprise) } - before { login_as_admin } + before do + create(:line_item_with_shipment, order: order, product: product) + create(:line_item_with_shipment, order: other_order, product: product) - it 'shows orders with payment state, their balance and totals' do - visit spree.payments_admin_reports_path + login_as_admin + end - select I18n.t(:report_itemised_payment), from: "report_type" - find("[type='submit']").click + context "when choosing itemised payments report type" do + it "shows orders with payment state, their balance and totals" do + visit spree.payments_admin_reports_path - expect(page.find("#listing_orders thead tr").text).to eq([ - I18n.t(:report_header_payment_state), - I18n.t(:report_header_distributor), - I18n.t(:report_header_product_total_price, currency: currency_symbol), - I18n.t(:report_header_shipping_total_price, currency: currency_symbol), - I18n.t(:report_header_outstanding_balance_price, currency: currency_symbol), - I18n.t(:report_header_total_price, currency: currency_symbol) - ].join(" ")) + select I18n.t(:report_itemised_payment), from: "report_type" + find("[type='submit']").click - expect(page.find("#listing_orders tbody tr").text).to eq([ - order.payment_state, - order.distributor.name, - order.item_total.to_f, - order.ship_total.to_f, - order.outstanding_balance.to_f, - order.total.to_f - ].join(" ")) + expect(page.find("#listing_orders thead tr").text).to eq([ + I18n.t(:report_header_payment_state), + I18n.t(:report_header_distributor), + I18n.t(:report_header_product_total_price, currency: currency_symbol), + I18n.t(:report_header_shipping_total_price, currency: currency_symbol), + I18n.t(:report_header_outstanding_balance_price, currency: currency_symbol), + I18n.t(:report_header_total_price, currency: currency_symbol) + ].join(" ")) + + expect(page.find("#listing_orders tbody tr").text).to eq([ + order.payment_state, + order.distributor.name, + order.item_total.to_f + other_order.item_total.to_f, + order.ship_total.to_f + other_order.ship_total.to_f, + order.outstanding_balance.to_f + other_order.outstanding_balance.to_f, + order.total.to_f + other_order.total.to_f + ].join(" ")) + end + end + + context 'when choosing payment totals report type' do + let(:paypal) { create(:payment_method, name: "PayPal") } + let!(:paypal_payment) { create(:payment, order: order, payment_method: paypal, state: "completed", amount: 5) } + + let(:eft) { create(:payment_method, name: "EFT") } + let!(:eft_payment) { create(:payment, order: other_order, payment_method: eft, state: "completed", amount: 6) } + + it 'shows orders with payment state, their balance and and payment totals' do + visit spree.payments_admin_reports_path + + select I18n.t(:report_payment_totals), from: "report_type" + find("[type='submit']").click + + expect(page.find("#listing_orders thead tr").text).to eq([ + I18n.t(:report_header_payment_state), + I18n.t(:report_header_distributor), + I18n.t(:report_header_product_total_price, currency: currency_symbol), + I18n.t(:report_header_shipping_total_price, currency: currency_symbol), + I18n.t(:report_header_total_price, currency: currency_symbol), + I18n.t(:report_header_eft_price, currency: currency_symbol), + I18n.t(:report_header_paypal_price, currency: currency_symbol), + I18n.t(:report_header_outstanding_balance_price, currency: currency_symbol), + ].join(" ")) + + expect(page.find("#listing_orders tbody tr").text).to eq([ + order.payment_state, + order.distributor.name, + order.item_total.to_f + other_order.item_total.to_f, + order.ship_total.to_f + other_order.ship_total.to_f, + order.total.to_f + other_order.total.to_f, + eft_payment.amount.to_f, + paypal_payment.amount.to_f, + order.outstanding_balance.to_f + other_order.outstanding_balance.to_f, + ].join(" ")) + end end end diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index 9b92596dd1..ec3799b646 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -93,8 +93,8 @@ feature ' login_as_admin_and_visit spree.admin_reports_path end - let(:bill_address1) { create(:address, lastname: "Aman") } - let(:bill_address2) { create(:address, lastname: "Bman") } + let(:bill_address1) { create(:address, lastname: "MULLER") } + let(:bill_address2) { create(:address, lastname: "Mistery") } let(:distributor_address) { create(:address, address1: "distributor address", city: 'The Shire', zipcode: "1234") } let(:distributor) { create(:distributor_enterprise, address: distributor_address) } let(:order1) { create(:order, distributor: distributor, bill_address: bill_address1) } @@ -129,6 +129,22 @@ feature ' expect(page).to have_selector 'table#listing_orders tbody tr', count: 5 # Totals row per order end + scenario "Alphabetically Sorted Pack by Customer" do + click_link "Pack By Customer" + click_button 'Search' + + rows = find("table#listing_orders").all("tr") + table = rows.map { |r| r.all("th,td").map { |c| c.text.strip }[3] } + expect(table).to eq([ + "Last Name", + order2.bill_address.lastname, + "", + order1.bill_address.lastname, + order1.bill_address.lastname, + "" + ]) + end + scenario "Pack By Supplier" do click_link "Pack By Supplier" fill_in 'q_completed_at_gt', with: '2013-04-25 13:00:00' @@ -166,7 +182,9 @@ feature ' let(:distributor2) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) } let(:user1) { create(:user, enterprises: [distributor1]) } let(:user2) { create(:user, enterprises: [distributor2]) } - let!(:shipping_method) { create(:shipping_method_with, :expensive_name, distributors: [distributor1]) } + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.20, included_in_price: true, zone: zone) } + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } + let!(:shipping_method) { create(:shipping_method_with, :expensive_name, distributors: [distributor1], tax_category: shipping_tax_category) } let(:enterprise_fee) { create(:enterprise_fee, enterprise: user1.enterprises.first, tax_category: product2.tax_category, calculator: Calculator::FlatRate.new(preferred_amount: 120.0)) } let(:order_cycle) { create(:simple_order_cycle, coordinator: distributor1, coordinator_fees: [enterprise_fee], distributors: [distributor1], variants: [product1.master]) } @@ -180,12 +198,12 @@ feature ' let!(:line_item2) { create(:line_item, variant: product2.master, price: 500.15, quantity: 3, order: order1) } before do - allow(Spree::Config).to receive(:shipment_inc_vat) { true } - allow(Spree::Config).to receive(:shipping_tax_rate) { 0.2 } - + order1.reload 2.times { order1.next } order1.select_shipping_method shipping_method.id order1.reload.recreate_all_fees! + order1.create_tax_charge! + order1.update! order1.finalize! login_as_admin_and_visit spree.admin_reports_path @@ -385,25 +403,20 @@ feature ' let(:product1) { create(:taxed_product, zone: zone, price: 12.54, tax_rate_amount: 0, sku: 'sku1') } let(:product2) { create(:taxed_product, zone: zone, price: 500.15, tax_rate_amount: 0.2, sku: 'sku2') } - before do - allow(Spree::Config).to receive(:shipment_inc_vat) { true } - allow(Spree::Config).to receive(:shipping_tax_rate) { 0.1 } - end - describe "with adjustments" do let!(:line_item1) { create(:line_item, variant: product1.master, price: 12.54, quantity: 1, order: order1) } let!(:line_item2) { create(:line_item, variant: product2.master, price: 500.15, quantity: 3, order: order1) } - let!(:adj_shipping) { create(:adjustment, order: order1, adjustable: order1, label: "Shipping", originator: shipping_method, amount: 100.55, included_tax: 10.06) } + let!(:adj_shipping) { create(:adjustment, order: order1, adjustable: order1, label: "Shipping", originator: shipping_method, amount: 100.55) } let!(:adj_fee1) { create(:adjustment, order: order1, adjustable: order1, originator: enterprise_fee1, label: "Enterprise fee untaxed", amount: 10, included_tax: 0) } let!(:adj_fee2) { create(:adjustment, order: order1, adjustable: order1, originator: enterprise_fee2, label: "Enterprise fee taxed", amount: 20, included_tax: 2) } - let!(:adj_manual1) { create(:adjustment, order: order1, adjustable: order1, originator: nil, source: nil, label: "Manual adjustment", amount: 30, included_tax: 0) } - let!(:adj_manual2) { create(:adjustment, order: order1, adjustable: order1, originator: nil, source: nil, label: "Manual adjustment", amount: 40, included_tax: 3) } + let!(:adj_manual1) { create(:adjustment, order: order1, adjustable: order1, originator: nil, label: "Manual adjustment", amount: 30, included_tax: 0) } + let!(:adj_manual2) { create(:adjustment, order: order1, adjustable: order1, originator: nil, label: "Manual adjustment", amount: 40, included_tax: 3) } before do order1.update_attribute :email, 'customer@email.com' + order1.shipment.update_columns(included_tax_total: 10.06) Timecop.travel(Time.zone.local(2015, 4, 25, 14, 0, 0)) { order1.finalize! } - login_as_admin_and_visit spree.admin_reports_path click_link 'Xero Invoices' diff --git a/spec/features/admin/subscriptions_spec.rb b/spec/features/admin/subscriptions_spec.rb index 0b73748b97..0059c7692e 100644 --- a/spec/features/admin/subscriptions_spec.rb +++ b/spec/features/admin/subscriptions_spec.rb @@ -17,6 +17,8 @@ feature 'Subscriptions' do context 'listing subscriptions' do let!(:subscription) { create(:subscription, shop: shop, with_items: true, with_proxy_orders: true) } + let!(:customer) { create(:customer, name: "Customer A") } + let!(:other_subscription) { create(:subscription, shop: shop, customer: customer, with_items: true, with_proxy_orders: true) } let!(:subscription2) { create(:subscription, shop: shop2, with_items: true, with_proxy_orders: true) } let!(:subscription_unmanaged) { create(:subscription, shop: shop_unmanaged, with_items: true, with_proxy_orders: true) } @@ -57,10 +59,27 @@ feature 'Subscriptions' do # Using the Quick Search expect(page).to have_selector "tr#so_#{subscription.id}" + expect(page).to have_selector "tr#so_#{other_subscription.id}" + + # Using the Quick Search: no result fill_in 'query', with: 'blah blah blah' expect(page).to have_no_selector "tr#so_#{subscription.id}" + expect(page).to have_no_selector "tr#so_#{other_subscription.id}" + + # Using the Quick Search: filter by email + fill_in 'query', with: other_subscription.customer.email + expect(page).to have_selector "tr#so_#{other_subscription.id}" + expect(page).to have_no_selector "tr#so_#{subscription.id}" + + # Using the Quick Search: filter by name + fill_in 'query', with: other_subscription.customer.name + expect(page).to have_selector "tr#so_#{other_subscription.id}" + expect(page).to have_no_selector "tr#so_#{subscription.id}" + + # Using the Quick Search: reset filter fill_in 'query', with: '' expect(page).to have_selector "tr#so_#{subscription.id}" + expect(page).to have_selector "tr#so_#{other_subscription.id}" # Toggling columns expect(page).to have_selector "th.customer" diff --git a/spec/features/admin/tag_rules_spec.rb b/spec/features/admin/tag_rules_spec.rb index b1ee2bedb6..610b0fe8b7 100644 --- a/spec/features/admin/tag_rules_spec.rb +++ b/spec/features/admin/tag_rules_spec.rb @@ -13,7 +13,7 @@ feature 'Tag Rules', js: true do visit_tag_rules end - xit "allows creation of rules of each type" do + it "allows creation of rules of each type" do # Creating a new tag expect(page).to have_content 'No tags apply to this enterprise yet' expect(page).to have_no_selector '.customer_tag' @@ -66,18 +66,8 @@ feature 'Tag Rules', js: true do expect(page).to have_content "not visible" end - # New DiscountOrder Rule - # click_button '+ Add A New Rule' - # select2_select 'Apply a discount to orders', from: 'rule_type_selector' - # click_button "Add Rule" - # fill_in "enterprise_tag_rules_attributes_1_calculator_attributes_preferred_flat_percent", with: 22 - click_button 'Update' - # tag_rule = TagRule::DiscountOrder.last - # expect(tag_rule.preferred_customer_tags).to eq "volunteer" - # expect(tag_rule.calculator.preferred_flat_percent).to eq -22 - tag_rule = TagRule::FilterShippingMethods.last expect(tag_rule.preferred_customer_tags).to eq "volunteer" expect(tag_rule.preferred_shipping_method_tags).to eq "volunteers-only" @@ -111,7 +101,6 @@ feature 'Tag Rules', js: true do let!(:fpm_tag_rule) { create(:filter_payment_methods_tag_rule, enterprise: enterprise, preferred_matched_payment_methods_visibility: "hidden", preferred_customer_tags: "trusted", preferred_payment_method_tags: "trusted" ) } let!(:foc_tag_rule) { create(:filter_order_cycles_tag_rule, enterprise: enterprise, preferred_matched_order_cycles_visibility: "visible", preferred_customer_tags: "wholesale", preferred_exchange_tags: "wholesale" ) } let!(:fsm_tag_rule) { create(:filter_shipping_methods_tag_rule, enterprise: enterprise, preferred_matched_shipping_methods_visibility: "hidden", preferred_customer_tags: "local", preferred_shipping_method_tags: "local" ) } - # let!(:do_tag_rule) { create(:tag_rule, enterprise: enterprise, preferred_customer_tags: "member" ) } before do visit_tag_rules @@ -171,12 +160,6 @@ feature 'Tag Rules', js: true do # Moving the Shipping Methods to top priority find(".customer_tag#tg_4 .header", ).drag_to find(".customer_tag#tg_1 .header") - # # DiscountOrder rule - # within "#tr_2" do - # expect(page).to have_field "enterprise_tag_rules_attributes_2_calculator_attributes_preferred_flat_percent", with: '0' - # fill_in "enterprise_tag_rules_attributes_2_calculator_attributes_preferred_flat_percent", with: 45 - # end - click_button 'Update' # DEFAULT FilterShippingMethods rule @@ -207,10 +190,6 @@ feature 'Tag Rules', js: true do expect(foc_tag_rule.preferred_customer_tags).to eq "volunteer" expect(foc_tag_rule.preferred_exchange_tags).to eq "volunteers-only3" expect(foc_tag_rule.preferred_matched_order_cycles_visibility).to eq "hidden" - - # DiscountOrder rule - # expect(do_tag_rule.preferred_customer_tags).to eq "member,volunteer" - # expect(do_tag_rule.calculator.preferred_flat_percent).to eq -45 end end diff --git a/spec/features/admin/tax_settings_spec.rb b/spec/features/admin/tax_settings_spec.rb index bbe8155bbf..e15c49b0df 100644 --- a/spec/features/admin/tax_settings_spec.rb +++ b/spec/features/admin/tax_settings_spec.rb @@ -8,11 +8,7 @@ feature 'Account and Billing Settings' do describe "updating" do before do - Spree::Config.set( - products_require_tax_category: false, - shipment_inc_vat: false, - shipping_tax_rate: 0 - ) + Spree::Config.set(products_require_tax_category: false) end context "as an admin user" do @@ -21,22 +17,16 @@ feature 'Account and Billing Settings' do click_link "Tax Settings" expect(page).to have_unchecked_field 'preferences_products_require_tax_category' - expect(page).to have_unchecked_field 'preferences_shipment_inc_vat' - expect(page).to have_field 'preferences_shipping_tax_rate' end it "attributes can be changed" do login_as_admin_and_visit spree.edit_admin_tax_settings_path check 'preferences_products_require_tax_category' - check 'preferences_shipment_inc_vat' - fill_in 'preferences_shipping_tax_rate', with: '0.12' click_button "Update" expect(Spree::Config.products_require_tax_category).to be true - expect(Spree::Config.shipment_inc_vat).to be true - expect(Spree::Config.shipping_tax_rate).to eq 0.12 end end end diff --git a/spec/features/admin/unit_price_spec.rb b/spec/features/admin/unit_price_spec.rb new file mode 100644 index 0000000000..b0d01ec252 --- /dev/null +++ b/spec/features/admin/unit_price_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +feature ' + As an admin + I want to check the unit price of my products/variants +' do + include AuthenticationHelper + include WebHelper + + let!(:stock_location) { create(:stock_location, backorderable_default: false) } + + before do + allow(OpenFoodNetwork::FeatureToggle).to receive(:enabled?).with(:unit_price, anything) { true } + end + + describe "product", js: true do + scenario "creating a new product" do + login_as_admin_and_visit spree.admin_products_path + click_link 'New Product' + select "Weight (kg)", from: 'product_variant_unit_with_scale' + fill_in 'Value', with: '1' + fill_in 'Price', with: '1' + + expect(find_field("Unit Price", disabled: true).value).to eq "$1.00 / kg" + end + end + + describe "variant", js: true do + scenario "creating a new variant" do + product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1") + login_as_admin_and_visit spree.admin_product_variants_path product + click_link 'New Variant' + fill_in 'Weight (g)', with: '1' + fill_in 'Price', with: '1' + + expect(find_field("Unit Price", disabled: true).value).to eq '$1,000.00 / kg' + end + + scenario "editing a variant" do + product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1") + variant = product.variants.first + variant.update(price: 1.0) + login_as_admin_and_visit spree.edit_admin_product_variant_path(product, variant) + + expect(find_field("Unit Price", disabled: true).value).to eq '$1,000.00 / kg' + end + end +end diff --git a/spec/features/consumer/caching/shops_caching_spec.rb b/spec/features/consumer/caching/shops_caching_spec.rb index f9684c2378..25ac1a1918 100644 --- a/spec/features/consumer/caching/shops_caching_spec.rb +++ b/spec/features/consumer/caching/shops_caching_spec.rb @@ -47,8 +47,8 @@ feature "Shops caching", js: true, caching: true do let(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first } let(:test_domain) { "#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}" } - let(:taxons_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" } - let(:properties_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" } + let(:taxons_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" } + let(:properties_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" } let(:options) { { expires_in: CacheService::FILTERS_EXPIRY } } before do diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 0994bd9dc6..9af20fa926 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -159,7 +159,7 @@ feature "full-page cart", js: true do end describe "updating quantities" do - let(:li) { order.line_items(true).last } + let(:li) { order.line_items.reload.last } let(:variant) { product_with_tax.variants.first } let(:variant2) { product_with_fee.variants.first } diff --git a/spec/features/consumer/shopping/checkout_auth_spec.rb b/spec/features/consumer/shopping/checkout_auth_spec.rb index 7bbb6e8922..2a9d178fc0 100644 --- a/spec/features/consumer/shopping/checkout_auth_spec.rb +++ b/spec/features/consumer/shopping/checkout_auth_spec.rb @@ -6,7 +6,7 @@ feature "As a consumer I want to check out my cart", js: true do include AuthenticationHelper include WebHelper include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include UIComponentHelper describe "using the checkout" do diff --git a/spec/features/consumer/shopping/checkout_paypal_spec.rb b/spec/features/consumer/shopping/checkout_paypal_spec.rb index 4e8f6dce30..3135aa1d35 100644 --- a/spec/features/consumer/shopping/checkout_paypal_spec.rb +++ b/spec/features/consumer/shopping/checkout_paypal_spec.rb @@ -4,7 +4,7 @@ require "spec_helper" feature "Check out with Paypal", js: true do include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include AuthenticationHelper include PaypalHelper diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index dc2b5832ce..14e6d151d0 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' feature "As a consumer I want to check out my cart", js: true do include AuthenticationHelper include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include WebHelper include UIComponentHelper @@ -17,9 +17,15 @@ feature "As a consumer I want to check out my cart", js: true do let(:product) { create(:taxed_product, supplier: supplier, price: 10, zone: zone, tax_rate_amount: 0.1) } let(:variant) { product.variants.first } let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil, ship_address_id: nil) } + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, zone: zone, included_in_price: true) } + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } let(:free_shipping) { create(:shipping_method, require_ship_address: true, name: "Frogs", description: "yellow", calculator: Calculator::FlatRate.new(preferred_amount: 0.00)) } - let(:shipping_with_fee) { create(:shipping_method, require_ship_address: false, name: "Donkeys", description: "blue", calculator: Calculator::FlatRate.new(preferred_amount: 4.56)) } + let(:shipping_with_fee) { + create(:shipping_method, require_ship_address: false, tax_category: shipping_tax_category, + name: "Donkeys", description: "blue", + calculator: Calculator::FlatRate.new(preferred_amount: 4.56)) + } let(:tagged_shipping) { create(:shipping_method, require_ship_address: false, name: "Local", tag_list: "local") } let!(:check_without_fee) { create(:payment_method, distributors: [distributor], name: "Roger rabbit", type: "Spree::PaymentMethod::Check") } let!(:check_with_fee) { create(:payment_method, distributors: [distributor], calculator: Calculator::FlatRate.new(preferred_amount: 5.67)) } @@ -32,9 +38,6 @@ feature "As a consumer I want to check out my cart", js: true do end before do - Spree::Config.shipment_inc_vat = true - Spree::Config.shipping_tax_rate = 0.25 - add_enterprise_fee enterprise_fee set_order order add_product_to_cart order, product @@ -462,7 +465,7 @@ feature "As a consumer I want to check out my cart", js: true do # There are two orders - our order and our new cart o = Spree::Order.complete.first - expect(o.adjustments.payment_fee.first.amount).to eq 5.67 + expect(o.all_adjustments.payment_fee.first.amount).to eq 5.67 expect(o.payments.first.amount).to eq(10 + 1.23 + 5.67) # items + fees + transaction end end diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index 07e1d98607..0ff0cfe412 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' feature "Check out with Stripe", js: true do include AuthenticationHelper include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include StripeHelper include StripeStubs @@ -219,7 +219,8 @@ feature "Check out with Stripe", js: true do stub_add_metadata_request(payment_method: "pm_123", response: {}) stub_payment_intents_post_request order: order stub_successful_capture_request order: order - stub_customers_post_request email: user.email + stub_customers_post_request email: "test@test.com" # First checkout with default details + stub_customers_post_request email: user.email # Second checkout with saved user details stub_payment_method_attach_request end diff --git a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb index ff15d4a46d..cd6ba81484 100644 --- a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb +++ b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb @@ -7,7 +7,7 @@ feature "Using embedded shopfront functionality", js: true do include AuthenticationHelper include WebHelper include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include UIComponentHelper describe "using iframes" do diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index ce8efc02ae..ce093f1c64 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -6,7 +6,7 @@ feature "shopping with variant overrides defined", js: true do include AuthenticationHelper include WebHelper include ShopWorkflow - include CheckoutHelper + include CheckoutRequestsHelper include UIComponentHelper let(:hub) { create(:distributor_enterprise, with_payment_and_shipping: true) } diff --git a/spec/helpers/admin/orders_helper_spec.rb b/spec/helpers/admin/orders_helper_spec.rb index 13079d4590..cfc9732a38 100644 --- a/spec/helpers/admin/orders_helper_spec.rb +++ b/spec/helpers/admin/orders_helper_spec.rb @@ -13,14 +13,22 @@ describe Admin::OrdersHelper, type: :helper do end it "filters shipping method adjustments" do - create(:adjustment, order: order, adjustable: order, amount: 1, originator_type: "Spree::ShippingMethod") + create(:adjustment, order: order, adjustable: build(:shipment), amount: 1, + originator_type: "Spree::ShippingMethod") expect(helper.order_adjustments_for_display(order)).to eq [] end - it "filters ineligible adjustments" do - create(:adjustment, adjustable: order, amount: 0, eligible: false, - originator_type: "Spree::TaxRate") + it "filters ineligible payment adjustments" do + create(:adjustment, adjustable: build(:payment), amount: 0, eligible: false, + originator_type: "Spree::PaymentMethod", order: order) + + expect(helper.order_adjustments_for_display(order)).to eq [] + end + + it "filters out line item adjustments" do + create(:adjustment, adjustable: build(:line_item), amount: 0, eligible: false, + originator_type: "EnterpriseFee", order: order) expect(helper.order_adjustments_for_display(order)).to eq [] end diff --git a/spec/helpers/checkout_helper_spec.rb b/spec/helpers/checkout_helper_spec.rb index 966569459a..b9fe4f54c9 100644 --- a/spec/helpers/checkout_helper_spec.rb +++ b/spec/helpers/checkout_helper_spec.rb @@ -36,7 +36,8 @@ describe CheckoutHelper, type: :helper do let(:order) { create(:order_with_totals_and_distribution) } let(:enterprise_fee) { create(:enterprise_fee, amount: 123) } let!(:fee_adjustment) { - create(:adjustment, originator: enterprise_fee, adjustable: order, source: order) + create(:adjustment, originator: enterprise_fee, adjustable: order, + order: order) } before do @@ -56,5 +57,18 @@ describe CheckoutHelper, type: :helper do expect(admin_fee_summary.label).to eq I18n.t(:orders_form_admin) expect(admin_fee_summary.amount).to eq 123 end + + context "with return authorization adjustments" do + let!(:return_adjustment) { + create(:adjustment, originator_type: 'Spree::ReturnAuthorization', adjustable: order, + order: order) + } + + it "includes return adjustments" do + adjustments = helper.checkout_adjustments_for(order) + + expect(adjustments).to include return_adjustment + end + end end end diff --git a/spec/helpers/shop_helper_spec.rb b/spec/helpers/shop_helper_spec.rb index 14dace89e3..660ab56257 100644 --- a/spec/helpers/shop_helper_spec.rb +++ b/spec/helpers/shop_helper_spec.rb @@ -2,14 +2,6 @@ require 'spec_helper' describe ShopHelper, type: :helper do - it "should build order cycle select options" do - distributor = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [distributor]) - allow(helper).to receive(:current_distributor).and_return distributor - - expect(helper.order_cycles_name_and_pickup_times([oc])).to eq([[helper.pickup_time(oc), oc.id]]) - end - describe "shop_tabs" do context "distributor with groups" do let(:group) { create(:enterprise_group) } diff --git a/spec/helpers/spree/admin/base_helper_spec.rb b/spec/helpers/spree/admin/base_helper_spec.rb index bfaadc53a4..867871bca1 100644 --- a/spec/helpers/spree/admin/base_helper_spec.rb +++ b/spec/helpers/spree/admin/base_helper_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' -describe Spree::BaseHelper, type: :helper do +describe Spree::Admin::BaseHelper, type: :helper do + helper 'spree/admin/navigation' + describe "#link_to_remove_fields" do let(:name) { 'Hola' } let(:form) { double('form_for', hidden_field: '') } diff --git a/spec/initializers/feature_toggles_spec.rb b/spec/initializers/feature_toggles_spec.rb deleted file mode 100644 index 0433d4508b..0000000000 --- a/spec/initializers/feature_toggles_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -describe 'config/initializers/feature_toggles.rb' do - # Executes the initializer's code block by reading the Ruby file. Note that `Kernel#require` would - # prevent this from happening twice. - subject(:execute_initializer) do - load Rails.root.join('config/initializers/feature_toggles.rb') - end - - let(:user) { build(:user) } - - around do |example| - original = ENV['BETA_TESTERS'] - example.run - ENV['BETA_TESTERS'] = original - end - - context 'when beta_testers is ["all"]' do - before { ENV['BETA_TESTERS'] = 'all' } - - it 'returns true' do - execute_initializer - - enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user) - expect(enabled).to eq(true) - end - end - - context 'when beta_testers is a list of emails' do - let(:other_user) { build(:user) } - - context 'and the user is in the list' do - before { ENV['BETA_TESTERS'] = "#{user.email}, #{other_user.email}" } - - it 'enables the feature' do - execute_initializer - - enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user) - expect(enabled).to eq(true) - end - end - - context 'and the user is not in the list' do - before { ENV['BETA_TESTERS'] = "#{other_user.email}" } - - it 'disables the feature' do - execute_initializer - - enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user) - expect(enabled).to eq(false) - end - end - - context 'and the list is empty' do - before { ENV['BETA_TESTERS'] = '' } - - it 'disables the feature' do - execute_initializer - - enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user) - expect(enabled).to eq(false) - end - end - end -end diff --git a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee index 81ea716f98..9369342591 100644 --- a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee @@ -820,7 +820,7 @@ describe "AdminProductEditCtrl", -> } ] $scope.dirtyProducts = {} - $httpBackend.expectDELETE("/api/products/13").respond 200, "data" + $httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data" $scope.deleteProduct $scope.products[1] $httpBackend.flush() @@ -839,7 +839,7 @@ describe "AdminProductEditCtrl", -> DirtyProducts.addProductProperty 9, "someProperty", "something" DirtyProducts.addProductProperty 13, "name", "P1" - $httpBackend.expectDELETE("/api/products/13").respond 200, "data" + $httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data" $scope.deleteProduct $scope.products[1] $httpBackend.flush() expect($scope.products).toEqual [ @@ -901,7 +901,7 @@ describe "AdminProductEditCtrl", -> } ] $scope.dirtyProducts = {} - $httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data" + $httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data" $scope.deleteVariant $scope.products[0], $scope.products[0].variants[0] $httpBackend.flush() @@ -931,7 +931,7 @@ describe "AdminProductEditCtrl", -> DirtyProducts.addVariantProperty 9, 4, "price", 6.0 DirtyProducts.addProductProperty 13, "name", "P1" - $httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data" + $httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data" $scope.deleteVariant $scope.products[0], $scope.products[0].variants[0] $httpBackend.flush() expect($scope.products[0].variants).toEqual [ diff --git a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee index 47c669e105..0e2101f0af 100644 --- a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee +++ b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee @@ -127,7 +127,7 @@ describe "Enterprises service", -> beforeEach -> enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", logo: {} }) - $httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"} + $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"} Enterprises.removeLogo(enterprise).then( -> resolved = true) $httpBackend.flush() @@ -144,7 +144,7 @@ describe "Enterprises service", -> beforeEach -> enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } ) - $httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 409, { error: "obj" } + $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 409, { error: "obj" } Enterprises.removeLogo(enterprise).catch( -> rejected = true) $httpBackend.flush() @@ -162,7 +162,7 @@ describe "Enterprises service", -> beforeEach -> enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", promo_image: {} }) - $httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"} + $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"} Enterprises.removePromoImage(enterprise).then( -> resolved = true) $httpBackend.flush() @@ -179,7 +179,7 @@ describe "Enterprises service", -> beforeEach -> enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } ) - $httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" } + $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" } Enterprises.removePromoImage(enterprise).catch( -> rejected = true) $httpBackend.flush() diff --git a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee index 4bc5513310..31a32f256a 100644 --- a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee @@ -45,7 +45,7 @@ describe "LineItemsCtrl", -> index: jasmine.createSpy('index').and.returnValue(lineItem) all: [lineItem] - httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} + httpBackend.expectGET("/api/v0/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor] httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle] httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier] diff --git a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee index 8372ee6819..9c19b2268d 100644 --- a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee +++ b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee @@ -19,7 +19,7 @@ describe "Orders service", -> beforeEach -> response = { orders: [{ id: 5, name: 'Order 1'}], pagination: {page: 1, pages: 1, results: 1} } - $httpBackend.expectGET('/api/orders.json').respond 200, response + $httpBackend.expectGET('/api/v0/orders.json').respond 200, response result = Orders.index() $httpBackend.flush() diff --git a/spec/javascripts/unit/admin/products/services/unit_prices_spec.js.coffee b/spec/javascripts/unit/admin/products/services/unit_prices_spec.js.coffee new file mode 100644 index 0000000000..489a40abff --- /dev/null +++ b/spec/javascripts/unit/admin/products/services/unit_prices_spec.js.coffee @@ -0,0 +1,140 @@ +describe "UnitPrices service", -> + UnitPrices = null + currencyconfig = + symbol: "$" + symbol_position: "before" + currency: "D" + hide_cents: "false" + + beforeEach -> + module "admin.products" + module ($provide)-> + $provide.value "availableUnits", "g,kg,T,mL,L,kL,oz,lb" + $provide.value "currencyConfig", currencyconfig + null + inject (_UnitPrices_) -> + UnitPrices = _UnitPrices_ + + describe "get correct unit price duo unit/value for weight", -> + unit_type = "weight" + + it "with scale: 1", -> + price = 1 + scale = 1 + unit_value = 1 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1000 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with scale and unit_value: 1000", -> + price = 1 + scale = 1000 + unit_value = 1000 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with scale: 1000 and unit_value: 2000", -> + price = 1 + scale = 1000 + unit_value = 2000 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 0.5 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with price: 2", -> + price = 2 + scale = 1 + unit_value = 1 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 2000 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with price: 2, scale and unit_value: 1000", -> + price = 2 + scale = 1000 + unit_value = 1000 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 2 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with price: 2, scale: 1000 and unit_value: 2000", -> + price = 2 + scale = 1000 + unit_value = 2000 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + it "with price: 2, scale: 1000 and unit_value: 500", -> + price = 2 + scale = 1000 + unit_value = 500 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 4 + expect(UnitPrices.unit(scale, unit_type)).toEqual "kg" + + + describe "get correct unit price duo unit/value for volume", -> + unit_type = "volume" + + it "with scale: 1", -> + price = 1 + scale = 1 + unit_value = 1 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "L" + + it "with price: 2 and unit_value: 0.5", -> + price = 2 + scale = 1 + unit_value = 0.5 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 4 + expect(UnitPrices.unit(scale, unit_type)).toEqual "L" + + it "with price: 2, scale: 0.001 and unit_value: 0.01", -> + price = 2 + scale = 0.001 + unit_value = 0.01 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 200 + expect(UnitPrices.unit(scale, unit_type)).toEqual "L" + + it "with price: 20000, scale: 1000 and unit_value: 10000", -> + price = 20000 + scale = 1000 + unit_value = 10000 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 2 + expect(UnitPrices.unit(scale, unit_type)).toEqual "L" + + describe "get correct unit price duo unit/value for items", -> + unit_type = "items" + scale = null + + it "with price: 1 and unit_value: 1", -> + price = 1 + unit_value = 1 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "item" + + it "with price: 1 and unit_value: 10", -> + price = 1 + unit_value = 10 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 0.1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "item" + + it "with price: 10 and unit_value: 1", -> + price = 10 + unit_value = 1 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 10 + expect(UnitPrices.unit(scale, unit_type)).toEqual "item" + + + describe "get correct unit price duo unit/value for weight in imperial system", -> + unit_type = "weight" + + it "with price: 1 and scale/unit_value: 28.35 (OZ)", -> + price = 1 + scale = 28.35 + unit_value = 28.35 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 16 + expect(UnitPrices.unit(scale, unit_type)).toEqual "lb" + + it "with price: 1 and scale/unit_value: 453.6 (LB)", -> + price = 1 + scale = 453.6 + unit_value = 453.6 + expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1 + expect(UnitPrices.unit(scale, unit_type)).toEqual "lb" diff --git a/spec/javascripts/unit/admin/products/units_controller_spec.js.coffee b/spec/javascripts/unit/admin/products/units_controller_spec.js.coffee index bb9175eaca..7e7ea03888 100644 --- a/spec/javascripts/unit/admin/products/units_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/products/units_controller_spec.js.coffee @@ -2,11 +2,17 @@ describe "unitsCtrl", -> ctrl = null scope = null product = null + currencyconfig = + symbol: "$" + symbol_position: "before" + currency: "D" + hide_cents: "false" beforeEach -> module('admin.products') module ($provide)-> $provide.value "availableUnits", "g,kg,T,mL,L,kL" + $provide.value "currencyConfig", currencyconfig null inject ($rootScope, $controller, VariantUnitManager) -> scope = $rootScope diff --git a/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee b/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee index 4fc1cca031..ece9d1f244 100644 --- a/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee @@ -13,9 +13,9 @@ describe "BulkProducts service", -> BulkProducts.products = [ id: 13 ] - $httpBackend.expectPOST("/api/products/13/clone").respond 201, + $httpBackend.expectPOST("/api/v0/products/13/clone").respond 201, id: 17 - $httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, [ + $httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, [ id: 17 ] BulkProducts.cloneProduct BulkProducts.products[0] @@ -30,8 +30,8 @@ describe "BulkProducts service", -> spyOn(BulkProducts, "insertProductAfter") spyOn(BulkProducts, "unpackProduct") BulkProducts.products = [originalProduct] - $httpBackend.expectPOST("/api/products/16/clone").respond 201, clonedProduct - $httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, clonedProduct + $httpBackend.expectPOST("/api/v0/products/16/clone").respond 201, clonedProduct + $httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, clonedProduct BulkProducts.cloneProduct BulkProducts.products[0] $httpBackend.flush() expect(BulkProducts.unpackProduct).toHaveBeenCalledWith clonedProduct diff --git a/spec/javascripts/unit/admin/tag_rules/controllers/tag_rules_controller_spec.js.coffee b/spec/javascripts/unit/admin/tag_rules/controllers/tag_rules_controller_spec.js.coffee index 280ef457b7..4758d4222e 100644 --- a/spec/javascripts/unit/admin/tag_rules/controllers/tag_rules_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/tag_rules/controllers/tag_rules_controller_spec.js.coffee @@ -25,11 +25,11 @@ describe "TagRulesCtrl", -> describe "adding a new tag group", -> beforeEach -> - scope.addNewRuleTo(scope.tagGroups[0], "DiscountOrder") + scope.addNewRuleTo(scope.tagGroups[0], "FilterOrderCycles") it "adds a new rule of the specified type to the rules array for the tagGroup", -> expect(scope.tagGroups[0].rules.length).toEqual 3 - expect(scope.tagGroups[0].rules[2].type).toEqual "TagRule::DiscountOrder" + expect(scope.tagGroups[0].rules[2].type).toEqual "TagRule::FilterOrderCycles" it "updates tagGroup start indices", -> expect(scope.tagGroups[0].startIndex).toEqual 1 diff --git a/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee index 6e614cffe6..8b421e33ec 100644 --- a/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee @@ -36,7 +36,7 @@ describe 'CreditCards service', -> it "loads a success flash", -> CreditCards.setDefault(card2) - $httpBackend.expectGET('/api/customers.json').respond 200, [] + $httpBackend.expectGET('/api/v0/customers.json').respond 200, [] $httpBackend.flush() expect(RailsFlashLoader.loadFlash).toHaveBeenCalledWith({success: t('js.default_card_updated')}) diff --git a/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee index 33a1d72cdc..a3f9a561ac 100644 --- a/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee @@ -17,14 +17,14 @@ describe 'Customer', -> it "nests the params inside 'customer'", -> $httpBackend - .expectPUT('/api/customers/3.json', { customer: { id: 3 } }) + .expectPUT('/api/v0/customers/3.json', { customer: { id: 3 } }) .respond 200, response customer.update() $httpBackend.flush() describe "when the request succeeds", -> it "shows a success flash", -> - $httpBackend.expectPUT('/api/customers/3.json').respond 200, response + $httpBackend.expectPUT('/api/v0/customers/3.json').respond 200, response customer.update() $httpBackend.flush() expect(RailsFlashLoaderMock.loadFlash) @@ -32,7 +32,7 @@ describe 'Customer', -> describe "when the request fails", -> it "shows a error flash", -> - $httpBackend.expectPUT('/api/customers/3.json').respond 400, { error: 'Some error' } + $httpBackend.expectPUT('/api/v0/customers/3.json').respond 400, { error: 'Some error' } customer.update() $httpBackend.flush() expect(RailsFlashLoaderMock.loadFlash) diff --git a/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee index 9680b89341..eaf788e9fe 100644 --- a/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee @@ -16,7 +16,7 @@ describe 'Customers', -> it "asks for customers and returns @all, promises to populate via @load", -> spyOn(Customers,'load').and.callThrough() - $httpBackend.expectGET('/api/customers.json').respond 200, customerList + $httpBackend.expectGET('/api/v0/customers.json').respond 200, customerList result = Customers.index() $httpBackend.flush() expect(Customers.load).toHaveBeenCalled() diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee index 4952c3c4fc..db1c801729 100644 --- a/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee @@ -32,7 +32,7 @@ describe "EnterpriseRegistrationService", -> describe "success", -> beforeEach -> spyOn(RegistrationServiceMock, "select") - $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 200, 6 + $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 200, 6 EnterpriseRegistrationService.create() $httpBackend.flush() @@ -46,7 +46,7 @@ describe "EnterpriseRegistrationService", -> beforeEach -> spyOn(RegistrationServiceMock, "select") spyOn(window, "alert") - $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, 6 + $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, 6 EnterpriseRegistrationService.create() $httpBackend.flush() @@ -60,7 +60,7 @@ describe "EnterpriseRegistrationService", -> beforeEach -> spyOn(RegistrationServiceMock, "select") spyOn(window, "alert") - $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }} + $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }} EnterpriseRegistrationService.create() $httpBackend.flush() @@ -78,7 +78,7 @@ describe "EnterpriseRegistrationService", -> describe "success", -> beforeEach -> - $httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 200, 6 + $httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 200, 6 EnterpriseRegistrationService.update('step') $httpBackend.flush() @@ -88,7 +88,7 @@ describe "EnterpriseRegistrationService", -> describe "failure", -> beforeEach -> spyOn(window, "alert") - $httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 400, 6 + $httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 400, 6 EnterpriseRegistrationService.update('step') $httpBackend.flush() diff --git a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee index d0114c05dd..df6446b433 100644 --- a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee @@ -13,7 +13,7 @@ describe 'Products service', -> properties = null taxons = null GmapsGeo = {} - endpoint = "/api/order_cycles/1/products.json?distributor=1" + endpoint = "/api/v0/order_cycles/1/products.json?distributor=1" beforeEach -> product = diff --git a/spec/jobs/subscription_placement_job_spec.rb b/spec/jobs/subscription_placement_job_spec.rb index 32a621c436..0f43d81781 100644 --- a/spec/jobs/subscription_placement_job_spec.rb +++ b/spec/jobs/subscription_placement_job_spec.rb @@ -115,6 +115,18 @@ describe SubscriptionPlacementJob do expect(changes[line_item2.id]).to be 3 expect(changes[line_item3.id]).to be 3 end + + context "and the order has been placed" do + before do + allow(order).to receive(:ensure_available_shipping_rates) { true } + allow(order).to receive(:process_each_payment) { true } + job.send(:place_order, order.reload) + end + + it "removes the unavailable items from the shipment" do + expect(order.shipment.manifest.size).to eq 1 + end + end end end end @@ -170,9 +182,9 @@ describe SubscriptionPlacementJob do allow(job).to receive(:unavailable_stock_lines_for) { order.line_items } end - it "does not place the order, clears, all adjustments, and sends an empty_order email" do + it "does not place the order, clears all adjustments, and sends an empty_order email" do expect{ job.send(:place_order, order) }.to_not change{ order.reload.completed_at }.from(nil) - expect(order.adjustments).to be_empty + expect(order.all_adjustments).to be_empty expect(order.total).to eq 0 expect(order.adjustment_total).to eq 0 expect(job).to_not have_received(:send_placement_email) @@ -205,6 +217,18 @@ describe SubscriptionPlacementJob do end end end + + context "when the proxy order fails to generate an order" do + before do + allow(proxy_order).to receive(:order) { nil } + end + + it "records an error " do + expect(job).to receive(:record_subscription_issue) + expect(job).to_not receive(:place_order) + job.send(:place_order_for, proxy_order) + end + end end describe "#send_placement_email" do diff --git a/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb b/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb index 6ea5597ddc..7ddab9d50d 100644 --- a/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb +++ b/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb @@ -16,8 +16,7 @@ module OpenFoodNetwork adjustment = Spree::Adjustment.last expect(adjustment.label).to eq('label') - expect(adjustment.adjustable).to eq(line_item.order) - expect(adjustment.source).to eq(line_item) + expect(adjustment.adjustable).to eq(line_item) expect(adjustment.originator).to eq(enterprise_fee) expect(adjustment).to be_mandatory @@ -40,7 +39,6 @@ module OpenFoodNetwork adjustment = Spree::Adjustment.last expect(adjustment.label).to eq('label') expect(adjustment.adjustable).to eq(order) - expect(adjustment.source).to eq(order) expect(adjustment.originator).to eq(enterprise_fee) expect(adjustment).to be_mandatory diff --git a/spec/lib/open_food_network/feature_toggle_spec.rb b/spec/lib/open_food_network/feature_toggle_spec.rb index d9904b0fd6..4d60fd060d 100644 --- a/spec/lib/open_food_network/feature_toggle_spec.rb +++ b/spec/lib/open_food_network/feature_toggle_spec.rb @@ -24,13 +24,25 @@ module OpenFoodNetwork expect(FeatureToggle.enabled?(:foo)).to be false end + it "uses Flipper configuration" do + Flipper.enable(:foo) + expect(FeatureToggle.enabled?(:foo)).to be true + end + + it "uses Flipper over static config" do + Flipper.enable(:foo, false) + stub_foo("true") + expect(FeatureToggle.enabled?(:foo)).to be false + end + def stub_foo(value) allow(ENV).to receive(:fetch).with("OFN_FEATURE_FOO", nil).and_return(value) end end context 'when specifying users' do - let(:user) { build(:user) } + let(:insider) { build(:user) } + let(:outsider) { build(:user, email: "different") } context 'and the block does not specify arguments' do before do @@ -38,19 +50,21 @@ module OpenFoodNetwork end it "returns the block's return value" do - expect(FeatureToggle.enabled?(:foo, user)).to eq('return value') + expect(FeatureToggle.enabled?(:foo, insider)).to eq('return value') end end context 'and the block specifies arguments' do - let(:users) { [user.email] } + let(:users) { [insider.email] } before do - FeatureToggle.enable(:foo) { |user| users.include?(user.email) } + FeatureToggle.enable(:foo) { |user| users.include?(user&.email) } end it "returns the block's return value" do - expect(FeatureToggle.enabled?(:foo, user)).to eq(true) + expect(FeatureToggle.enabled?(:foo, insider)).to eq(true) + expect(FeatureToggle.enabled?(:foo, outsider)).to eq(false) + expect(FeatureToggle.enabled?(:foo, nil)).to eq(false) end end end diff --git a/spec/lib/open_food_network/order_cycle_management_report_spec.rb b/spec/lib/open_food_network/order_cycle_management_report_spec.rb index 7e6afa240b..3beb2bd985 100644 --- a/spec/lib/open_food_network/order_cycle_management_report_spec.rb +++ b/spec/lib/open_food_network/order_cycle_management_report_spec.rb @@ -16,6 +16,15 @@ module OpenFoodNetwork end describe "fetching orders" do + let(:customers_with_balance) { instance_double(CustomersWithBalance) } + + it 'calls the OutstandingBalance query object' do + outstanding_balance = instance_double(OutstandingBalance, query: Spree::Order.none) + expect(OutstandingBalance).to receive(:new).and_return(outstanding_balance) + + subject.orders + end + it "fetches completed orders" do o1 = create(:order) o2 = create(:order, completed_at: 1.day.ago, state: 'complete') @@ -27,27 +36,11 @@ module OpenFoodNetwork expect(subject.orders).to eq([order]) end - context 'when the customer_balance feature is enabled' do - let(:customers_with_balance) { instance_double(CustomersWithBalance) } + it 'orders them by id' do + order1 = create(:order, completed_at: 1.day.ago, state: 'complete') + order2 = create(:order, completed_at: 2.days.ago, state: 'complete') - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, anything) { true } - end - - it 'calls OutstandingBalance query object' do - outstanding_balance = instance_double(OutstandingBalance, query: Spree::Order.none) - expect(OutstandingBalance).to receive(:new).and_return(outstanding_balance) - - subject.orders - end - - it 'orders them by id' do - order1 = create(:order, completed_at: 1.day.ago, state: 'complete') - order2 = create(:order, completed_at: 2.days.ago, state: 'complete') - - expect(subject.orders.pluck(:id)).to eq([order2.id, order1.id]) - end + expect(subject.orders.pluck(:id)).to eq([order2.id, order1.id]) end it "does not show cancelled orders" do diff --git a/spec/lib/open_food_network/user_balance_calculator_spec.rb b/spec/lib/open_food_network/user_balance_calculator_spec.rb deleted file mode 100644 index 36ba738e55..0000000000 --- a/spec/lib/open_food_network/user_balance_calculator_spec.rb +++ /dev/null @@ -1,149 +0,0 @@ -# frozen_string_literal: true - -require 'open_food_network/user_balance_calculator' -require 'spec_helper' - -module OpenFoodNetwork - describe UserBalanceCalculator do - describe "finding the account balance of a user with a hub" do - let!(:user1) { create(:user) } - let!(:hub1) { create(:distributor_enterprise) } - - let!(:o1) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:o2) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p1) { - create(:payment, order: o1, amount: 15.00, - state: "completed") - } - let!(:p2) { - create(:payment, order: o2, amount: 2.00, - state: "completed") - } - - before do - # Sanity check the order - expect(o1.total).to eq 13 - expect(o1.ready_to_ship?).to eq true - expect(o1.paid?).to eq true - end - - it "finds the correct balance for this email and enterprise" do - expect(UserBalanceCalculator.new(o1.email, hub1).balance).to eq(-9) # = 15 + 2 - 13 - 13 - end - - context "with another hub" do - let!(:hub2) { create(:distributor_enterprise) } - let!(:o3) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub2, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p3) { - create(:payment, order: o3, amount: 15.00, - state: "completed") - } - - it "does not find the balance for other enterprises" do - expect(UserBalanceCalculator.new(o3.email, hub2).balance).to eq(2) # = 15 - 13 - end - end - - context "with another user" do - let!(:user2) { create(:user) } - let!(:o4) { - create(:order_with_totals_and_distribution, :completed, - user: user2, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p3) { - create(:payment, order: o4, amount: 20.00, - state: "completed") - } - - it "does not find the balance for other users" do - expect(UserBalanceCalculator.new(o4.email, hub1).balance).to eq(7) # = 20 - 13 - end - end - - context "with canceled orders" do - let!(:o4) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago, state: "canceled") - } # total=13 (10 + 3 shipping fee) - let!(:p4) { - create(:payment, order: o4, amount: 20.00, - state: "completed") - } - - it "does not include canceled orders in the balance" do - expect(UserBalanceCalculator.new(o4.email, hub1).balance).to eq(-9) # = 15 + 2 - 13 - 13 - end - end - - context "with void payments" do - let!(:o4) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p4) { - create(:payment, order: o4, amount: 20.00, - state: "void") - } - - it "does not include void in the balance" do - expect(UserBalanceCalculator.new(o4.email, hub1).balance).to eq(-22) # = 15 + 2 - 13 - 13 - 10 - end - end - - context "with invalid payments" do - let!(:o4) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p4) { - create(:payment, order: o4, amount: 20.00, - state: "invalid") - } - - it "does not include invalid payments in the balance" do - expect(UserBalanceCalculator.new(o4.email, hub1).balance).to eq(-22) # = 15 + 2 - 13 - 13 - 10 - end - end - - context "with multiple payments on single order" do - let!(:o4) { - create(:order_with_totals_and_distribution, :completed, - user: user1, distributor: hub1, - completed_at: 1.day.ago) - } # total=13 (10 + 3 shipping fee) - let!(:p4) { - create(:payment, order: o4, amount: 4.00, - state: "completed") - } - let!(:p5) { - create(:payment, order: o4, amount: 5.00, - state: "completed") - } - let!(:p6) { - create(:payment, order: o4, amount: 6.00, - state: "completed") - } - - it "includes orders with multiple payments in the balance" do - expect(UserBalanceCalculator.new(o4.email, hub1).balance).to eq(-7) # = 15 + 2 + 4 + 5 + 6 - 13 - 13 - 10 - end - end - end - end -end diff --git a/spec/lib/spree/core/calculated_adjustments_spec.rb b/spec/lib/spree/core/calculated_adjustments_spec.rb index 484654e2eb..218ef63c92 100644 --- a/spec/lib/spree/core/calculated_adjustments_spec.rb +++ b/spec/lib/spree/core/calculated_adjustments_spec.rb @@ -25,24 +25,24 @@ describe Spree::Core::CalculatedAdjustments do it "should be associated with the target" do expect(target.adjustments).to receive(:create) - tax_rate.create_adjustment("foo", target, order) + tax_rate.create_adjustment("foo", target) end it "should be associated with the order" do - tax_rate.create_adjustment("foo", target, order) + tax_rate.create_adjustment("foo", target) expect(target.adjustments.first.order_id).to eq order.id end it "should have the correct originator and an amount derived from the calculator and supplied calculable" do - adjustment = tax_rate.create_adjustment("foo", target, order) + adjustment = tax_rate.create_adjustment("foo", target) expect(adjustment).not_to be_nil expect(adjustment.amount).to eq 10 - expect(adjustment.source).to eq order + expect(adjustment.adjustable).to eq order expect(adjustment.originator).to eq tax_rate end it "should be mandatory if true is supplied for that parameter" do - adjustment = tax_rate.create_adjustment("foo", target, order, true) + adjustment = tax_rate.create_adjustment("foo", target, true) expect(adjustment).to be_mandatory end @@ -50,7 +50,7 @@ describe Spree::Core::CalculatedAdjustments do before { allow(calculator).to receive_messages(compute: 0) } context "when adjustment is mandatory" do - before { tax_rate.create_adjustment("foo", target, order, true) } + before { tax_rate.create_adjustment("foo", target, true) } it "should create an adjustment" do expect(Spree::Adjustment.count).to eq 1 @@ -66,13 +66,4 @@ describe Spree::Core::CalculatedAdjustments do end end end - - context "#update_adjustment" do - it "should update the adjustment using its calculator (and the specified source)" do - adjustment = double(:adjustment).as_null_object - calculable = double :calculable - expect(adjustment).to receive(:update_column).with(:amount, 10) - tax_rate.update_adjustment(adjustment, calculable) - end - end end diff --git a/spec/lib/spree/i18n_spec.rb b/spec/lib/spree/i18n_spec.rb index 397dd36641..f535d4e5d3 100644 --- a/spec/lib/spree/i18n_spec.rb +++ b/spec/lib/spree/i18n_spec.rb @@ -21,6 +21,10 @@ describe "i18n" do } } ) + + allow(ActionView::Base). + to receive(:raise_on_missing_translations). + and_return(false) end it "translates within the spree scope" do diff --git a/spec/lib/stripe/payment_intent_validator_spec.rb b/spec/lib/stripe/payment_intent_validator_spec.rb index a6b983b367..ac4a06a83c 100644 --- a/spec/lib/stripe/payment_intent_validator_spec.rb +++ b/spec/lib/stripe/payment_intent_validator_spec.rb @@ -40,7 +40,7 @@ module Stripe it "raises Stripe error with an invalid_payment_state message" do expect { validator.call(payment_intent_id, stripe_account_id) - }.to raise_error Stripe::StripeError, "Invalid payment state" + }.to raise_error Stripe::StripeError, "Invalid payment state: failed" end end diff --git a/spec/mailers/order_mailer_spec.rb b/spec/mailers/order_mailer_spec.rb index d23b920c55..e05b71ccb7 100644 --- a/spec/mailers/order_mailer_spec.rb +++ b/spec/mailers/order_mailer_spec.rb @@ -15,7 +15,7 @@ describe Spree::OrderMailer do end context 'when the order has outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 123 } } + before { allow(order).to receive(:new_outstanding_balance) { 123 } } it 'renders the amount as money' do expect(email.body).to include('$123') @@ -23,7 +23,7 @@ describe Spree::OrderMailer do end context 'when the order has no outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 0 } } + before { allow(order).to receive(:new_outstanding_balance) { 0 } } it 'displays the payment status' do expect(email.body).to include(I18n.t(:email_payment_not_paid)) @@ -58,7 +58,7 @@ describe Spree::OrderMailer do end context 'when the order has outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 123 } } + before { allow(order).to receive(:new_outstanding_balance) { 123 } } it 'renders the amount as money' do expect(email.body).to include('$123') @@ -66,8 +66,6 @@ describe Spree::OrderMailer do end context 'when the order has no outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 0 } } - it 'displays the payment status' do expect(email.body).to include(I18n.t(:email_payment_not_paid)) end diff --git a/spec/mailers/subscription_mailer_spec.rb b/spec/mailers/subscription_mailer_spec.rb index 0cd77c047a..7950663e25 100644 --- a/spec/mailers/subscription_mailer_spec.rb +++ b/spec/mailers/subscription_mailer_spec.rb @@ -88,7 +88,7 @@ describe SubscriptionMailer, type: :mailer do end context 'when the order has outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 123 } } + before { allow(order).to receive(:new_outstanding_balance) { 123 } } it 'renders the amount as money' do expect(email.body).to include('$123') @@ -96,7 +96,7 @@ describe SubscriptionMailer, type: :mailer do end context 'when the order has no outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 0 } } + before { allow(order).to receive(:new_outstanding_balance) { 0 } } it 'displays the payment status' do expect(email.body).to include(I18n.t(:email_payment_not_paid)) @@ -141,7 +141,7 @@ describe SubscriptionMailer, type: :mailer do end context 'when the order has outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 123 } } + before { allow(order).to receive(:new_outstanding_balance) { 123 } } it 'renders the amount as money' do expect(email.body).to include('$123') @@ -149,7 +149,7 @@ describe SubscriptionMailer, type: :mailer do end context 'when the order has no outstanding balance' do - before { allow(order).to receive(:outstanding_balance) { 0 } } + before { allow(order).to receive(:new_outstanding_balance) { 0 } } it 'displays the payment status' do expect(email.body).to include(I18n.t(:email_payment_not_paid)) @@ -229,7 +229,10 @@ describe SubscriptionMailer, type: :mailer do let(:body) { strip_tags(SubscriptionMailer.deliveries.last.body.encoded) } let(:scope) { "subscription_mailer" } - before { allow(summary).to receive(:unrecorded_ids) { [] } } + before do + allow(summary).to receive(:unrecorded_ids) { [] } + allow(summary).to receive(:subscription_issues) { [] } + end context "when no issues were encountered while processing subscriptions" do before do @@ -339,7 +342,10 @@ describe SubscriptionMailer, type: :mailer do let(:body) { strip_tags(SubscriptionMailer.deliveries.last.body.encoded) } let(:scope) { "subscription_mailer" } - before { allow(summary).to receive(:unrecorded_ids) { [] } } + before do + allow(summary).to receive(:unrecorded_ids) { [] } + allow(summary).to receive(:subscription_issues) { [] } + end context "when no issues were encountered while processing subscriptions" do before do diff --git a/spec/models/concerns/balance_spec.rb b/spec/models/concerns/balance_spec.rb index 331e521442..b723284456 100644 --- a/spec/models/concerns/balance_spec.rb +++ b/spec/models/concerns/balance_spec.rb @@ -132,110 +132,4 @@ describe Balance do end end end - - context "#outstanding_balance" do - context 'when orders are in cart state' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'cart') } - - it 'returns the order balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when orders are in address state' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'address') } - - it 'returns the order balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when orders are in delivery state' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'delivery') } - - it 'returns the order balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when orders are in payment state' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'payment') } - - it 'returns the order balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when no orders where paid' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'complete') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order was paid' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'complete') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order is canceled' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'canceled') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order is resumed' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'resumed') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order is in payment' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'payment') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order is awaiting_return' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'awaiting_return') } - - it 'returns the customer balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when an order is returned' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'returned') } - - it 'returns the balance' do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when payment_total is less than total' do - let(:order) { build(:order, total: 100, payment_total: 10, state: 'complete') } - - it "returns positive" do - expect(order.outstanding_balance).to eq(100 - 10) - end - end - - context 'when payment_total is greater than total' do - let(:order) { create(:order, total: 8.20, payment_total: 10.20, state: 'complete') } - - it "returns negative amount" do - expect(order.outstanding_balance).to eq(-2.00) - end - end - end end diff --git a/spec/models/enterprise_caching_spec.rb b/spec/models/enterprise_caching_spec.rb index 01c1498046..e5506c46ab 100644 --- a/spec/models/enterprise_caching_spec.rb +++ b/spec/models/enterprise_caching_spec.rb @@ -92,6 +92,13 @@ describe Enterprise do enterprise.reload }.to change { enterprise.updated_at } end + + it "touches enterprise when a relevant exchange is updated" do + expect { + oc.exchanges.first.update!(updated_at: Time.zone.now) + enterprise.reload + }.to change { enterprise.updated_at } + end end it "touches enterprise when the product's variant is added to order cycle" do diff --git a/spec/models/enterprise_fee_spec.rb b/spec/models/enterprise_fee_spec.rb index 9cf76958d5..1533b29674 100644 --- a/spec/models/enterprise_fee_spec.rb +++ b/spec/models/enterprise_fee_spec.rb @@ -104,14 +104,14 @@ describe EnterpriseFee do line_item1 = create(:line_item, order: order, variant: order_cycle.variants.first) line_item2 = create(:line_item, order: order, variant: order_cycle.variants.second) - order_cycle.coordinator_fees[0].create_adjustment('foo1', line_item1.order, line_item1, true) - order_cycle.coordinator_fees[0].create_adjustment('foo2', line_item2.order, line_item2, true) - order_cycle.exchanges[0].enterprise_fees[0].create_adjustment('foo3', line_item1.order, line_item1, true) - order_cycle.exchanges[0].enterprise_fees[0].create_adjustment('foo4', line_item2.order, line_item2, true) + order_cycle.coordinator_fees[0].create_adjustment('foo1', line_item1.order, true) + order_cycle.coordinator_fees[0].create_adjustment('foo2', line_item2.order, true) + order_cycle.exchanges[0].enterprise_fees[0].create_adjustment('foo3', line_item1, true) + order_cycle.exchanges[0].enterprise_fees[0].create_adjustment('foo4', line_item2, true) expect do EnterpriseFee.clear_all_adjustments order - end.to change(order.adjustments, :count).by(-4) + end.to change(order.all_adjustments, :count).by(-4) end it "clears adjustments from per-order fees" do @@ -129,7 +129,6 @@ describe EnterpriseFee do order = create(:order) tax_rate = create(:tax_rate, calculator: build(:calculator)) order.adjustments.create({ amount: 12.34, - source: order, originator: tax_rate, state: 'closed', label: 'hello' }) diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index 492f21fc60..dc93d86b6f 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -482,7 +482,7 @@ describe Enterprise do let(:product1) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1]) } let(:product2) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1, taxon2]) } let(:product3) { create(:simple_product, primary_taxon: taxon3) } - let(:oc) { create(:order_cycle, distributors: [distributor]) } + let(:oc) { create(:order_cycle) } let(:ex) { create(:exchange, order_cycle: oc, incoming: false, sender: supplier, receiver: distributor) } it "gets all taxons of all distributed products" do diff --git a/spec/models/order_balance_spec.rb b/spec/models/order_balance_spec.rb index 93d5ca5d2c..bad8998733 100644 --- a/spec/models/order_balance_spec.rb +++ b/spec/models/order_balance_spec.rb @@ -8,212 +8,174 @@ describe OrderBalance do let(:user) { order.user } describe '#label' do - context 'when the customer_balance feature is disabled' do + context 'when the balance is positive' do before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { false } + allow(order).to receive(:new_outstanding_balance) { 10 } end - context 'when the balance is postive' do - before do - allow(order).to receive(:outstanding_balance) { 10 } - end - - it "returns 'balance due'" do - expect(order_balance.label).to eq(I18n.t(:balance_due)) - end - end - - context 'when the balance is negative' do - before do - allow(order).to receive(:outstanding_balance) { -10 } - end - - it "returns 'credit owed'" do - expect(order_balance.label).to eq(I18n.t(:credit_owed)) - end - end - - context 'when the balance is zero' do - before do - allow(order).to receive(:outstanding_balance) { 0 } - end - - it "returns 'balance due'" do - expect(order_balance.label).to eq(I18n.t(:balance_due)) - end + it "returns 'balance due'" do + expect(order_balance.label).to eq(I18n.t(:balance_due)) end end - context 'when the customer_balance feature is enabled' do + context 'when the balance is negative' do before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } + allow(order).to receive(:new_outstanding_balance) { -10 } end - context 'when the balance is postive' do - before do - allow(order).to receive(:new_outstanding_balance) { 10 } - end + it "returns 'credit owed'" do + expect(order_balance.label).to eq(I18n.t(:credit_owed)) + end + end - it "returns 'balance due'" do - expect(order_balance.label).to eq(I18n.t(:balance_due)) - end + context 'when the balance is zero' do + before do + allow(order).to receive(:new_outstanding_balance) { 0 } end - context 'when the balance is negative' do - before do - allow(order).to receive(:new_outstanding_balance) { -10 } - end + it "returns 'balance due'" do + expect(order_balance.label).to eq(I18n.t(:balance_due)) + end + end + end - it "returns 'credit owed'" do - expect(order_balance.label).to eq(I18n.t(:credit_owed)) - end + describe '#display_amount' do + before do + allow(order).to receive(:new_outstanding_balance) { 20 } + end + + it 'returns the balance wraped in a Money object' do + expect(order_balance.display_amount).to eq(Spree::Money.new(20, currency: ENV['currency'])) + end + end + + describe '#zero?' do + context 'when the balance is zero' do + before do + allow(order).to receive(:new_outstanding_balance) { 0 } end - context 'when the balance is zero' do - before do - allow(order).to receive(:new_outstanding_balance) { 0 } - end + it 'returns true' do + expect(order_balance.zero?).to eq(true) + end + end - it "returns 'balance due'" do - expect(order_balance.label).to eq(I18n.t(:balance_due)) - end + context 'when the balance is positive' do + before do + allow(order).to receive(:new_outstanding_balance) { 10 } + end + + it 'returns false' do + expect(order_balance.zero?).to eq(false) + end + end + + context 'when the balance is negative' do + before do + allow(order).to receive(:new_outstanding_balance) { -10 } + end + + it 'returns false' do + expect(order_balance.zero?).to eq(false) end end end describe '#amount' do - context 'when the customer_balance feature is disabled' do before do - allow(order).to receive(:outstanding_balance) { 10 } + allow(order).to receive(:new_outstanding_balance) { 123 } end + it 'calls #new_outstanding_balance' do + expect(order).to receive(:new_outstanding_balance) + expect(order_balance.amount).to eq(123) + end + end + + describe '#abs' do + context 'when the balance is zero' do before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { false } + allow(order).to receive(:new_outstanding_balance) { 0 } end - it 'returns the balance wraped in a Money object' do - expect(order_balance.amount).to eq(Spree::Money.new(10, currency: ENV['currency'])) + it 'returns its absolute value' do + expect(order_balance.abs).to eq(0) end end - context 'when the customer_balance feature is enabled' do + context 'when the balance is positive' do before do - allow(order).to receive(:new_outstanding_balance) { 20 } + allow(order).to receive(:new_outstanding_balance) { 10 } end + it 'returns its absolute value' do + expect(order_balance.abs).to eq(10) + end + end + + context 'when the balance is negative' do before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } + allow(order).to receive(:new_outstanding_balance) { -10 } end - it 'returns the balance wraped in a Money object' do - expect(order_balance.amount).to eq(Spree::Money.new(20, currency: ENV['currency'])) + it 'returns its absolute value' do + expect(order_balance.abs).to eq(10) end end end - describe '#zero?' do - context 'when the customer_balance feature is disabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { false } - end - - context 'when the balance is zero' do - before do - allow(order).to receive(:outstanding_balance) { 0 } - end - - it 'returns true' do - expect(order_balance.zero?).to eq(true) - end - end - - context 'when the balance is positive' do - before do - allow(order).to receive(:outstanding_balance) { 10 } - end - - it 'returns false' do - expect(order_balance.zero?).to eq(false) - end - end - - context 'when the balance is negative' do - before do - allow(order).to receive(:outstanding_balance) { -10 } - end - - it 'returns false' do - expect(order_balance.zero?).to eq(false) - end - end + describe '#to_s' do + before do + allow(order).to receive(:new_outstanding_balance) { 10 } end - context 'when the customer_balance feature is enabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } - end - - context 'when the balance is zero' do - before do - allow(order).to receive(:new_outstanding_balance) { 0 } - end - - it 'returns true' do - expect(order_balance.zero?).to eq(true) - end - end - - context 'when the balance is positive' do - before do - allow(order).to receive(:new_outstanding_balance) { 10 } - end - - it 'returns false' do - expect(order_balance.zero?).to eq(false) - end - end - - context 'when the balance is negative' do - before do - allow(order).to receive(:new_outstanding_balance) { -10 } - end - - it 'returns false' do - expect(order_balance.zero?).to eq(false) - end - end + it 'returns the balance as a string' do + expect(order_balance.to_s).to eq('10') end end describe '#to_f' do - context 'when the customer_balance feature is disabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { false } - end - - it 'calls #outstanding_balance' do - expect(order).to receive(:outstanding_balance) - order_balance.to_f - end + before do + allow(order).to receive(:new_outstanding_balance) { 10 } end - context 'when the customer_balance feature is enabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, user) { true } - end + it 'returns the balance as a float' do + expect(order_balance.to_f).to eq(10.0) + end + end - it 'calls #new_outstanding_balance' do - expect(order).to receive(:new_outstanding_balance) - order_balance.to_f - end + describe '#to_d' do + before do + allow(order).to receive(:new_outstanding_balance) { 10 } + end + + it 'returns the balance as a decimal' do + expect(order_balance.to_d).to eq(10.0) + end + end + + describe '#+' do + let(:other_order_balance) { described_class.new(order) } + + before do + allow(order).to receive(:new_outstanding_balance) { 10 } + end + + it 'returns the balance as a string' do + expect(order_balance + other_order_balance).to eq(20.0) + end + end + + describe '#< and #>' do + before do + allow(order).to receive(:new_outstanding_balance) { 10 } + end + + it 'correctly returns true or false' do + expect(order_balance > 5).to eq true + expect(order_balance > 20).to eq false + expect(order_balance < 15).to eq true + expect(order_balance < 5).to eq false end end end diff --git a/spec/models/spree/adjustment_spec.rb b/spec/models/spree/adjustment_spec.rb index b46a431041..d85fb3d3a3 100644 --- a/spec/models/spree/adjustment_spec.rb +++ b/spec/models/spree/adjustment_spec.rb @@ -8,8 +8,8 @@ module Spree let(:adjustment) { Spree::Adjustment.create(label: "Adjustment", amount: 5) } describe "scopes" do - let!(:arbitrary_adjustment) { create(:adjustment, source: nil, label: "Arbitrary") } - let!(:return_authorization_adjustment) { create(:adjustment, source: create(:return_authorization)) } + let!(:arbitrary_adjustment) { create(:adjustment, label: "Arbitrary") } + let!(:return_authorization_adjustment) { create(:adjustment, originator: create(:return_authorization)) } it "returns return_authorization adjustments" do expect(Spree::Adjustment.return_authorization.to_a).to eq [return_authorization_adjustment] @@ -18,39 +18,39 @@ module Spree context "#update!" do context "when originator present" do - let(:originator) { double("originator", update_adjustment: nil) } + let(:originator) { instance_double(EnterpriseFee, compute_amount: 10.0) } + before do - allow(originator).to receive_messages update_amount: true allow(adjustment).to receive_messages originator: originator, label: 'adjustment', amount: 0 end it "should do nothing when closed" do adjustment.close - expect(originator).not_to receive(:update_adjustment) + expect(originator).not_to receive(:compute_amount) adjustment.update! end it "should do nothing when finalized" do adjustment.finalize - expect(originator).not_to receive(:update_adjustment) + expect(originator).not_to receive(:compute_amount) adjustment.update! end - it "should ask the originator to update_adjustment" do - expect(originator).to receive(:update_adjustment) + it "should ask the originator to recalculate the amount" do + expect(originator).to receive(:compute_amount) adjustment.update! end context "using the :force argument" do it "should update adjustments without changing their state" do - expect(originator).to receive(:update_adjustment) + expect(originator).to receive(:compute_amount) adjustment.update!(force: true) expect(adjustment.state).to eq "open" end it "should update closed adjustments" do adjustment.close - expect(originator).to receive(:update_adjustment) + expect(originator).to receive(:compute_amount) adjustment.update!(force: true) end end @@ -58,7 +58,7 @@ module Spree it "should do nothing when originator is nil" do allow(adjustment).to receive_messages originator: nil - expect(adjustment).not_to receive(:amount=) + expect(adjustment).not_to receive(:update_columns) adjustment.update! end end @@ -186,7 +186,7 @@ module Spree end it "has tax included" do - expect(adjustment.amount).to be > 0 + expect(adjustment.amount).to be_positive expect(adjustment.included).to be true end @@ -197,11 +197,17 @@ module Spree end describe "Shipment adjustments" do + let(:zone) { create(:zone_with_member) } + let(:inclusive_tax) { true } + let(:tax_rate) { + create(:tax_rate, included_in_price: inclusive_tax, zone: zone, amount: 0.25) + } + let(:tax_category) { create(:tax_category, name: "Shipping", tax_rates: [tax_rate] ) } let(:hub) { create(:distributor_enterprise, charges_sales_tax: true) } let(:order) { create(:order, distributor: hub) } let(:line_item) { create(:line_item, order: order) } - let(:shipping_method) { create(:shipping_method_with, :flat_rate) } + let(:shipping_method) { create(:shipping_method_with, :flat_rate, tax_category: tax_category) } let(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) } describe "the shipping charge" do @@ -212,54 +218,114 @@ module Spree end end - describe "when tax on shipping is disabled" do + context "with tax" do before do - allow(Config).to receive(:shipment_inc_vat).and_return(false) + allow(order).to receive(:tax_zone) { zone } end - it "records 0% tax on shipment adjustments" do - allow(Config).to receive(:shipping_tax_rate).and_return(0) - order.shipments = [shipment] + context "when the shipment has an inclusive tax rate" do + it "calculates the shipment tax from the tax rate" do + order.shipments = [shipment] + order.create_tax_charge! + order.update_totals - expect(order.shipment_adjustments.first.included_tax).to eq(0) + # Finding the tax included in an amount that's already inclusive of tax: + # total - ( total / (1 + rate) ) + # 50 - ( 50 / (1 + 0.25) ) + # = 10 + expect(order.shipment_adjustments.tax.first.amount).to eq(10) + expect(order.shipment_adjustments.tax.first.included).to eq true + + expect(shipment.reload.cost).to eq(50) + expect(shipment.included_tax_total).to eq(10) + expect(shipment.additional_tax_total).to eq(0) + + expect(order.included_tax_total).to eq(10) + expect(order.additional_tax_total).to eq(0) + end end - it "records 0% tax on shipments when a rate is set but shipment_inc_vat is false" do - allow(Config).to receive(:shipping_tax_rate).and_return(0.25) - order.shipments = [shipment] + context "when the shipment has an added tax rate" do + let(:inclusive_tax) { false } - expect(order.shipment_adjustments.first.included_tax).to eq(0) - end - end + # Current behaviour. Will be replaced by the pending test below + it "records the tax on the order's adjustments" do + order.shipments = [shipment] + order.create_tax_charge! + order.update_totals - describe "when tax on shipping is enabled" do - before do - allow(Config).to receive(:shipment_inc_vat).and_return(true) + expect(order.shipment_adjustments.tax.count).to be_zero + + # Finding the added tax for an amount: + # total * rate + # 50 * 0.25 + # = 12.5 + expect(order.adjustments.tax.first.amount).to eq(12.50) + expect(order.adjustments.tax.first.included).to eq false + + expect(shipment.reload.cost).to eq(50) + expect(shipment.included_tax_total).to eq(0) + expect(shipment.additional_tax_total).to eq(0) + + expect(order.included_tax_total).to eq(0) + expect(order.additional_tax_total).to eq(12.50) + end + + xit "records the tax on the shipment's adjustments" do + order.shipments = [shipment] + order.create_tax_charge! + order.update_totals + + # Finding the added tax for an amount: + # total * rate + # 50 * 0.25 + # = 12.5 + expect(order.shipment_adjustments.tax.first.amount).to eq(12.50) + expect(order.shipment_adjustments.tax.first.included).to eq false + + expect(shipment.reload.cost).to eq(50) + expect(shipment.included_tax_total).to eq(0) + expect(shipment.additional_tax_total).to eq(12.50) + + expect(order.included_tax_total).to eq(0) + expect(order.additional_tax_total).to eq(12.50) + end end - it "takes the shipment adjustment tax included from the system setting" do - allow(Config).to receive(:shipping_tax_rate).and_return(0.25) - order.shipments = [shipment] + context "when the distributor does not charge sales tax" do + it "records 0% tax on shipments" do + order.distributor.update! charges_sales_tax: false + order.shipments = [shipment] + order.create_tax_charge! + order.update_totals - # Finding the tax included in an amount that's already inclusive of tax: - # total - ( total / (1 + rate) ) - # 50 - ( 50 / (1 + 0.25) ) - # = 10 - expect(order.shipment_adjustments.first.included_tax).to eq(10.00) + expect(order.shipment_adjustments.tax.count).to be_zero + + expect(shipment.reload.cost).to eq(50) + expect(shipment.included_tax_total).to eq(0) + expect(shipment.additional_tax_total).to eq(0) + + expect(order.included_tax_total).to eq(0) + expect(order.additional_tax_total).to eq(0) + end end - it "records 0% tax on shipments when shipping_tax_rate is not set" do - allow(Config).to receive(:shipping_tax_rate).and_return(0) - order.shipments = [shipment] + context "when the shipment has no applicable tax rate" do + it "records 0% tax on shipments" do + allow(shipment).to receive(:tax_category) { nil } + order.shipments = [shipment] + order.create_tax_charge! + order.update_totals - expect(order.shipment_adjustments.first.included_tax).to eq(0) - end + expect(order.shipment_adjustments.tax.count).to be_zero - it "records 0% tax on shipments when the distributor does not charge sales tax" do - order.distributor.update! charges_sales_tax: false - order.shipments = [shipment] + expect(shipment.reload.cost).to eq(50) + expect(shipment.included_tax_total).to eq(0) + expect(shipment.additional_tax_total).to eq(0) - expect(order.shipment_adjustments.first.included_tax).to eq(0) + expect(order.included_tax_total).to eq(0) + expect(order.additional_tax_total).to eq(0) + end end end end @@ -274,7 +340,7 @@ module Spree let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) } let(:line_item) { create(:line_item, variant: variant) } let(:order) { create(:order, line_items: [line_item], order_cycle: order_cycle, distributor: coordinator) } - let(:adjustment) { order.adjustments.reload.enterprise_fee.first } + let(:adjustment) { order.all_adjustments.reload.enterprise_fee.first } context "when enterprise fees have a fixed tax_category" do before do @@ -417,15 +483,6 @@ module Spree end end end - - describe "setting the included tax by tax rate" do - let(:adjustment) { Adjustment.new label: 'foo', amount: 50 } - - it "sets it, rounding to two decimal places" do - adjustment.set_included_tax! 0.25 - expect(adjustment.included_tax).to eq(10.00) - end - end end context "extends LocalizedNumber" do @@ -472,8 +529,7 @@ module Spree describe "inclusive and additional scopes" do let(:included) { true } let(:adjustment) { - create(:adjustment, adjustable: order, source: order, - originator: tax_rate, included: included) + create(:adjustment, adjustable: order, originator: tax_rate, included: included) } context "when tax is included in price" do @@ -491,5 +547,21 @@ module Spree end end end + + context "return authorization adjustments" do + let!(:return_authorization) { create(:return_authorization, amount: 123) } + let(:order) { return_authorization.order } + let!(:return_adjustment) { + create(:adjustment, originator: return_authorization, order: order, + adjustable: order, amount: 456) + } + + describe "#update!" do + it "sets a negative value equal to the return authorization amount" do + expect { return_adjustment.update! }. + to change { return_adjustment.reload.amount }.to(-123) + end + end + end end end diff --git a/spec/models/spree/classification_spec.rb b/spec/models/spree/classification_spec.rb index 65407747cc..6a35477f12 100644 --- a/spec/models/spree/classification_spec.rb +++ b/spec/models/spree/classification_spec.rb @@ -4,14 +4,16 @@ require 'spec_helper' module Spree describe Classification do - let(:product) { build_stubbed(:simple_product) } - let(:taxon) { build_stubbed(:taxon) } + let(:product) { create(:simple_product) } + let(:taxon) { create(:taxon) } it "won't destroy if classification is the primary taxon" do - classification = Classification.new(taxon: taxon, product: product) - product.primary_taxon = taxon + classification = Classification.create(taxon: taxon, product: product) + product.update(primary_taxon: taxon) + expect(classification.destroy).to be false expect(classification.errors.messages[:base]).to eq(["Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted"]) + expect(classification.reload).to be end end end diff --git a/spec/models/spree/gateway/stripe_sca_spec.rb b/spec/models/spree/gateway/stripe_sca_spec.rb new file mode 100644 index 0000000000..43844a3763 --- /dev/null +++ b/spec/models/spree/gateway/stripe_sca_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Spree::Gateway::StripeSCA, type: :model do + before { allow(Stripe).to receive(:api_key) { "sk_test_12345" } } + + describe "#purchase" do + let(:order) { create(:order_with_totals_and_distribution) } + let(:credit_card) { create(:credit_card) } + let(:payment) { + create( + :payment, + state: "checkout", + order: order, + amount: order.total, + payment_method: subject, + source: credit_card, + ) + } + let(:gateway_options) { + { order_id: order.number } + } + let(:payment_authorised) { + payment_intent(payment.amount, "requires_capture") + } + let(:capture_successful) { + payment_intent(payment.amount, "succeeded") + } + + it "captures the payment" do + stub_request(:get, "https://api.stripe.com/v1/payment_intents/12345"). + to_return(status: 200, body: payment_authorised) + stub_request(:post, "https://api.stripe.com/v1/payment_intents/12345/capture"). + with(body: {"amount_to_capture" => order.total}). + to_return(status: 200, body: capture_successful) + + response = subject.purchase(order.total, credit_card, gateway_options) + + expect(response.success?).to eq true + end + + it "provides an error message to help developer debug" do + stub_request(:get, "https://api.stripe.com/v1/payment_intents/12345"). + to_return(status: 200, body: capture_successful) + + response = subject.purchase(order.total, credit_card, gateway_options) + + expect(response.success?).to eq false + expect(response.message).to eq "Invalid payment state: succeeded" + end + end + + def payment_intent(amount, status) + JSON.generate( + object: "payment_intent", + amount: amount, + status: status, + charges: { data: [{ id: "ch_1234", amount: amount }] } + ) + end +end diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 0c0277f00a..a43d7fba97 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -190,8 +190,17 @@ module Spree end end - it "finds line items sorted by name and unit_value" do - expect(o.line_items.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + describe "#sorted_by_name_and_unit_value" do + it "finds line items sorted by name and unit_value" do + expect(o.line_items.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + end + + it "includes soft-deleted products/variants" do + li3.variant.product.destroy + + expect(o.line_items.reload.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + expect(o.line_items.sorted_by_name_and_unit_value.to_sql).to_not match "deleted_at" + end end it "finds line items from a given order cycle" do @@ -418,9 +427,7 @@ module Spree li = LineItem.new allow(li).to receive(:price) { 55.55 } - allow(li).to receive_message_chain(:order, :adjustments, :loaded?) - allow(li).to receive_message_chain(:order, :adjustments, :select) - allow(li).to receive_message_chain(:order, :adjustments, :where, :to_a, :sum) { 11.11 } + allow(li).to receive_message_chain(:adjustments, :enterprise_fee, :sum) { 11.11 } allow(li).to receive(:quantity) { 2 } expect(li.price_with_adjustments).to eq(61.11) end @@ -431,9 +438,7 @@ module Spree li = LineItem.new allow(li).to receive(:price) { 55.55 } - allow(li).to receive_message_chain(:order, :adjustments, :loaded?) - allow(li).to receive_message_chain(:order, :adjustments, :select) - allow(li).to receive_message_chain(:order, :adjustments, :where, :to_a, :sum) { 11.11 } + allow(li).to receive_message_chain(:adjustments, :enterprise_fee, :sum) { 11.11 } allow(li).to receive(:quantity) { 2 } expect(li.amount_with_adjustments).to eq(122.22) end diff --git a/spec/models/spree/order/adjustments_spec.rb b/spec/models/spree/order/adjustments_spec.rb index 639e058f87..4c2daf5ade 100644 --- a/spec/models/spree/order/adjustments_spec.rb +++ b/spec/models/spree/order/adjustments_spec.rb @@ -37,13 +37,11 @@ describe Spree::Order do before do @adj1 = line_item1.adjustments.create( amount: 2, - source: line_item1, label: "VAT 5%" ) @adj2 = line_item1.adjustments.create( amount: 5, - source: line_item1, label: "VAT 10%" ) end @@ -58,13 +56,11 @@ describe Spree::Order do before do @adj1 = line_item1.adjustments.create( amount: 2, - source: line_item1, label: "VAT 5%" ) @adj2 = line_item2.adjustments.create( amount: 5, - source: line_item2, label: "VAT 10%" ) end diff --git a/spec/models/spree/order/state_machine_spec.rb b/spec/models/spree/order/state_machine_spec.rb index 27d4e48c95..0b37ee41fa 100644 --- a/spec/models/spree/order/state_machine_spec.rb +++ b/spec/models/spree/order/state_machine_spec.rb @@ -48,24 +48,15 @@ describe Spree::Order do end end - context "when current state is address" do - before do - allow(order).to receive(:ensure_available_shipping_rates) - order.state = "address" - end - - it "adjusts tax rates when transitioning to delivery" do - # Once because the record is being saved - # Twice because it is transitioning to the delivery state - expect(Spree::TaxRate).to receive(:adjust).twice - order.next! - end - end - context "when current state is delivery" do before do + allow(order).to receive(:ensure_available_shipping_rates) order.state = "delivery" - allow(order).to receive_messages total: 10.0 + end + + it "adjusts tax rates when transitioning to payment" do + expect(Spree::TaxRate).to receive(:adjust) + order.next! end end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 6dbd4764c4..f9e258dc9d 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -310,7 +310,7 @@ describe Spree::Order do context "#display_outstanding_balance" do it "returns the value as a spree money" do - allow(order).to receive(:outstanding_balance) { 10.55 } + allow(order).to receive(:new_outstanding_balance) { 10.55 } expect(order.display_outstanding_balance).to eq Spree::Money.new(10.55) end end @@ -392,20 +392,6 @@ describe Spree::Order do end end - context "ensure shipments will be updated" do - before { Spree::Shipment.create!(order: order) } - - it "destroys current shipments" do - order.ensure_updated_shipments - expect(order.shipments).to be_empty - end - - it "puts order back in address state" do - order.ensure_updated_shipments - expect(order.state).to eql "address" - end - end - describe ".tax_address" do before { Spree::Config[:tax_using_ship_address] = tax_using_ship_address } subject { order.tax_address } @@ -490,6 +476,7 @@ describe Spree::Order do end describe "applying enterprise fees" do + subject { create(:order) } let(:fee_handler) { ::OrderFeesHandler.new(subject) } before do @@ -552,7 +539,7 @@ describe Spree::Order do it "returns the sum of eligible enterprise fee adjustments" do ef = create(:enterprise_fee, calculator: Calculator::FlatRate.new ) ef.calculator.set_preference :amount, 123.45 - a = ef.create_adjustment("adjustment", o, o, true) + a = ef.create_adjustment("adjustment", o, true) expect(o.admin_and_handling_total).to eq(123.45) end @@ -560,7 +547,7 @@ describe Spree::Order do it "does not include ineligible adjustments" do ef = create(:enterprise_fee, calculator: Calculator::FlatRate.new ) ef.calculator.set_preference :amount, 123.45 - a = ef.create_adjustment("adjustment", o, o, true) + a = ef.create_adjustment("adjustment", o, true) a.update_column :eligible, false @@ -570,7 +557,7 @@ describe Spree::Order do it "does not include adjustments that do not originate from enterprise fees" do sm = create(:shipping_method, calculator: Calculator::FlatRate.new ) sm.calculator.set_preference :amount, 123.45 - sm.create_adjustment("adjustment", o, o, true) + sm.create_adjustment("adjustment", o, true) expect(o.admin_and_handling_total).to eq(0) end @@ -578,7 +565,7 @@ describe Spree::Order do it "does not include adjustments whose source is a line item" do ef = create(:enterprise_fee, calculator: Calculator::PerItem.new ) ef.calculator.set_preference :amount, 123.45 - ef.create_adjustment("adjustment", li.order, li, true) + ef.create_adjustment("adjustment", li, true) expect(o.admin_and_handling_total).to eq(0) end @@ -635,16 +622,19 @@ describe Spree::Order do describe "getting the shipping tax" do let(:order) { create(:order) } - let(:shipping_method) { create(:shipping_method_with, :flat_rate) } + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, included_in_price: true, zone: create(:zone_with_member)) } + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } + let!(:shipping_method) { create(:shipping_method_with, :flat_rate, tax_category: shipping_tax_category) } context "with a taxed shipment" do - before do - allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true) - allow(Spree::Config).to receive(:shipping_tax_rate).and_return(0.25) - end - let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) } + before do + allow(order).to receive(:tax_zone) { shipping_tax_rate.zone } + order.reload + order.create_tax_charge! + end + it "returns the shipping tax" do expect(order.shipping_tax).to eq(10) end @@ -661,8 +651,14 @@ describe Spree::Order do let!(:order) { create(:order) } let(:enterprise_fee1) { create(:enterprise_fee) } let(:enterprise_fee2) { create(:enterprise_fee) } - let!(:adjustment1) { create(:adjustment, adjustable: order, originator: enterprise_fee1, label: "EF 1", amount: 123, included_tax: 10.00) } - let!(:adjustment2) { create(:adjustment, adjustable: order, originator: enterprise_fee2, label: "EF 2", amount: 123, included_tax: 2.00) } + let!(:adjustment1) { + create(:adjustment, adjustable: order, originator: enterprise_fee1, label: "EF 1", + amount: 123, included_tax: 10.00, order: order) + } + let!(:adjustment2) { + create(:adjustment, adjustable: order, originator: enterprise_fee2, label: "EF 2", + amount: 123, included_tax: 2.00, order: order) + } it "returns a sum of the tax included in all enterprise fees" do expect(order.reload.enterprise_fee_tax).to eq(12) @@ -670,11 +666,7 @@ describe Spree::Order do end describe "getting the total tax" do - before do - allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true) - allow(Spree::Config).to receive(:shipping_tax_rate).and_return(0.25) - end - + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25) } let(:order) { create(:order) } let(:shipping_method) { create(:shipping_method_with, :flat_rate) } let!(:shipment) do @@ -683,16 +675,11 @@ describe Spree::Order do let(:enterprise_fee) { create(:enterprise_fee) } before do - create( - :adjustment, - order: order, - adjustable: order, - originator: enterprise_fee, - label: "EF", - amount: 123, - included_tax: 2 - ) - order.reload + create(:adjustment, adjustable: order, originator: enterprise_fee, label: "EF", amount: 123, + included_tax: 2, order: order) + create(:adjustment, adjustable: shipment, originator: shipping_tax_rate, + amount: 10, order: order, state: "closed") + order.update! end it "returns a sum of all tax on the order" do @@ -783,8 +770,8 @@ describe Spree::Order do it "removes the variant's adjustment" do line_item = order.line_items.where(variant_id: v1.id).first - adjustment_scope = Spree::Adjustment.where(source_type: "Spree::LineItem", - source_id: line_item.id) + adjustment_scope = Spree::Adjustment.where(adjustable_type: "Spree::LineItem", + adjustable_id: line_item.id) expect(adjustment_scope.count).to eq(1) adjustment = adjustment_scope.first order.remove_variant v1 @@ -928,8 +915,74 @@ describe Spree::Order do end end + describe "#require_customer?" do + context "when the record is new" do + let(:order) { build(:order, state: state) } + + context "and the state is not cart" do + let(:state) { "complete" } + + it "returns true" do + expect(order.send(:require_customer?)).to eq(false) + end + end + + context "and the state is cart" do + let(:state) { "cart" } + + it "returns false" do + expect(order.send(:require_customer?)).to eq(false) + end + end + end + + context "when the record is not new" do + let(:order) { create(:order, state: state) } + + context "and the state is not cart" do + let(:state) { "complete" } + + it "returns true" do + expect(order.send(:require_customer?)).to eq(true) + end + end + + context "and the state is cart" do + let(:state) { "cart" } + + it "returns false" do + expect(order.send(:require_customer?)).to eq(false) + end + end + end + end + describe "associating a customer" do let(:distributor) { create(:distributor_enterprise) } + + context "when creating an order" do + it "does not create a customer" do + order = create(:order, distributor: distributor) + expect(order.customer).to be_nil + end + end + + context "when updating the order" do + let!(:order) { create(:order, distributor: distributor) } + + before do + order.state = "complete" + order.save! + end + + it "creates a customer" do + expect(order.customer).not_to be_nil + end + end + end + + describe "#associate_customer" do + let(:distributor) { create(:distributor_enterprise) } let!(:order) { create(:order, distributor: distributor) } context "when an email address is available for the order" do @@ -1035,22 +1088,30 @@ describe Spree::Order do describe "a completed order with shipping and transaction fees" do let(:distributor) { create(:distributor_enterprise_with_tax) } - let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } + let(:zone) { create(:zone_with_member) } + let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, included_in_price: true, zone: zone) } + let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) } + let(:order) { + create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, + payment_fee: payment_fee, + shipping_tax_category: shipping_tax_category) + } let(:shipping_fee) { 3 } let(:payment_fee) { 5 } let(:item_num) { order.line_items.length } let(:expected_fees) { item_num * (shipping_fee + payment_fee) } before do - Spree::Config.shipment_inc_vat = true - Spree::Config.shipping_tax_rate = 0.25 + order.reload + order.create_tax_charge! # Sanity check the fees - expect(order.adjustments.length).to eq 1 - expect(order.shipment_adjustments.length).to eq 1 + expect(order.all_adjustments.length).to eq 3 + expect(order.shipment_adjustments.length).to eq 2 expect(item_num).to eq 2 expect(order.adjustment_total).to eq expected_fees - expect(order.shipment.fee_adjustment.included_tax).to eq 1.2 + expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 1.2 + expect(order.shipment.included_tax_total).to eq 1.2 end context "removing line_items" do @@ -1059,11 +1120,12 @@ describe Spree::Order do order.save expect(order.adjustment_total).to eq expected_fees - shipping_fee - payment_fee - expect(order.shipment.fee_adjustment.included_tax).to eq 0.6 + expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 0.6 + expect(order.shipment.included_tax_total).to eq 0.6 end context "when finalized fee adjustments exist on the order" do - let(:payment_fee_adjustment) { order.adjustments.payment_fee.first } + let(:payment_fee_adjustment) { order.all_adjustments.payment_fee.first } let(:shipping_fee_adjustment) { order.shipment_adjustments.first } before do @@ -1078,7 +1140,8 @@ describe Spree::Order do # Check if fees got updated order.reload expect(order.adjustment_total).to eq expected_fees - expect(order.shipment.fee_adjustment.included_tax).to eq 1.2 + expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 1.2 + expect(order.shipment.included_tax_total).to eq 1.2 end end end @@ -1091,7 +1154,8 @@ describe Spree::Order do order.save expect(order.adjustment_total).to eq expected_fees - (item_num * shipping_fee) - expect(order.shipment.fee_adjustment.included_tax).to eq 0 + expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 0 + expect(order.shipment.included_tax_total).to eq 0 end end @@ -1175,7 +1239,7 @@ describe Spree::Order do it "advances to complete state without error" do advance_to_delivery_state(order) order.next! - create(:payment, order: order) + order.payments << create(:payment, order: order) expect { order.next! }.to change { order.state }.from("payment").to("complete") end @@ -1260,7 +1324,7 @@ describe Spree::Order do end end - describe '#charge_shipping_and_payment_fees!' do + describe '#set_payment_amount!' do let(:order) do shipment = build(:shipment_with, :shipping_method, shipping_method: build(:shipping_method)) build(:order, shipments: [shipment] ) @@ -1273,8 +1337,8 @@ describe Spree::Order do allow(order).to receive(:payment_required?) { true } end - it 'calls charge_shipping_and_payment_fees! and updates totals' do - expect(order).to receive(:charge_shipping_and_payment_fees!) + it 'calls #set_payment_amount! and updates totals' do + expect(order).to receive(:set_payment_amount!) expect(order).to receive(:update_totals).at_least(:once) order.next diff --git a/spec/models/spree/payment_spec.rb b/spec/models/spree/payment_spec.rb index 64d9c04afe..2820316bd0 100644 --- a/spec/models/spree/payment_spec.rb +++ b/spec/models/spree/payment_spec.rb @@ -7,7 +7,7 @@ describe Spree::Payment do let(:order) { create(:order) } let(:gateway) do gateway = Spree::Gateway::Bogus.new(environment: 'test', active: true) - gateway.stub source_required: true + allow(gateway).to receive(:source_required) { true } gateway end @@ -382,7 +382,7 @@ describe Spree::Payment do end it "resulting payment should have correct values" do - allow(payment.order).to receive(:outstanding_balance) { 100 } + allow(payment.order).to receive(:new_outstanding_balance) { 100 } allow(payment).to receive(:credit_allowed) { 10 } offsetting_payment = payment.credit! @@ -402,7 +402,7 @@ describe Spree::Payment do end it 'lets the new payment to be saved' do - allow(payment.order).to receive(:outstanding_balance) { 100 } + allow(payment.order).to receive(:new_outstanding_balance) { 100 } allow(payment).to receive(:credit_allowed) { 10 } offsetting_payment = payment.credit! @@ -856,8 +856,8 @@ describe Spree::Payment do expect(payment.state).to eq "failed" expect(payment.adjustment.eligible?).to be false expect(payment.adjustment.finalized?).to be true - expect(order.adjustments.payment_fee.count).to eq 1 - expect(order.adjustments.payment_fee.eligible).to_not include payment.adjustment + expect(order.all_adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.eligible).to_not include payment.adjustment end end @@ -875,8 +875,8 @@ describe Spree::Payment do expect(payment.state).to eq "invalid" expect(payment.adjustment.eligible?).to be false expect(payment.adjustment.finalized?).to be true - expect(order.adjustments.payment_fee.count).to eq 1 - expect(order.adjustments.payment_fee.eligible).to_not include payment.adjustment + expect(order.all_adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.eligible).to_not include payment.adjustment end end @@ -895,8 +895,8 @@ describe Spree::Payment do expect(order.payments).to include payment expect(payment.state).to eq "completed" expect(payment.adjustment.eligible?).to be true - expect(order.adjustments.payment_fee.count).to eq 1 - expect(order.adjustments.payment_fee.eligible).to include payment.adjustment + expect(order.all_adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.eligible).to include payment.adjustment expect(payment.adjustment.amount).to eq 1.5 end end diff --git a/spec/models/spree/preferences/preferable_spec.rb b/spec/models/spree/preferences/preferable_spec.rb index 3e156fce1f..8b7edba9f0 100644 --- a/spec/models/spree/preferences/preferable_spec.rb +++ b/spec/models/spree/preferences/preferable_spec.rb @@ -222,7 +222,7 @@ describe Spree::Preferences::Preferable do describe "persisted preferables" do before(:all) do - class CreatePrefTest < ActiveRecord::Migration + class CreatePrefTest < ActiveRecord::Migration[4.2] def self.up create_table :pref_tests do |t| t.string :col @@ -238,7 +238,7 @@ describe Spree::Preferences::Preferable do ActiveRecord::Migration.verbose = false CreatePrefTest.migrate(:up) - class PrefTest < ActiveRecord::Base + class PrefTest < ApplicationRecord preference :pref_test_pref, :string, default: 'abc' preference :pref_test_any, :any, default: [] end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index c1da45eddc..37fd516ada 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -88,13 +88,13 @@ module Spree describe 'Variants sorting' do context 'without master variant' do it 'sorts variants by position' do - expect(product.variants.to_sql).to match(/ORDER BY (\`|\")spree_variants(\`|\").position ASC/) + expect(product.variants.to_sql).to match(/ORDER BY spree_variants.position ASC/) end end context 'with master variant' do it 'sorts variants by position' do - expect(product.variants_including_master.to_sql).to match(/ORDER BY (\`|\")spree_variants(\`|\").position ASC/) + expect(product.variants_including_master.to_sql).to match(/ORDER BY spree_variants.position ASC/) end end end @@ -783,7 +783,7 @@ module Spree expect(v.option_values.map(&:name).include?("1g")).to eq(true) expect { p.update!(variant_unit: 'volume', variant_unit_scale: 0.001) - }.to change(p.master.option_values(true), :count).by(0) + }.to change(p.master.option_values.reload, :count).by(0) v.reload expect(v.option_values.map(&:name).include?("1L")).to eq(true) expect(v.option_values.map(&:name).include?("1g")).to eq(false) @@ -798,7 +798,7 @@ module Spree expect(p.master.option_values.map(&:name).include?("1g")).to eq(true) expect { p.update!(variant_unit: 'volume', variant_unit_scale: 0.001) - }.to change(p.master.option_values(true), :count).by(0) + }.to change(p.master.option_values.reload, :count).by(0) p.reload expect(p.master.option_values.map(&:name).include?("1L")).to eq(true) expect(p.master.option_values.map(&:name).include?("1g")).to eq(false) @@ -835,8 +835,8 @@ module Spree p.option_type_ids = p.option_type_ids.reject { |id| id == ot.id } # Then the associated option values should have been removed from the variants - expect(v1.option_values(true)).not_to include ov1 - expect(v2.option_values(true)).not_to include ov2 + expect(v1.option_values.reload).not_to include ov1 + expect(v2.option_values.reload).not_to include ov2 # And the option values themselves should still exist expect(Spree::OptionValue.where(id: [ov1.id, ov2.id]).count).to eq(2) @@ -864,13 +864,13 @@ module Spree it "removes the master variant from all order cycles" do e.variants << p.master p.destroy - expect(e.variants(true)).to be_empty + expect(e.variants.reload).to be_empty end it "removes all other variants from order cycles" do e.variants << v p.destroy - expect(e.variants(true)).to be_empty + expect(e.variants.reload).to be_empty end end end diff --git a/spec/models/spree/return_authorization_spec.rb b/spec/models/spree/return_authorization_spec.rb index d37bac00ed..5fa696f522 100644 --- a/spec/models/spree/return_authorization_spec.rb +++ b/spec/models/spree/return_authorization_spec.rb @@ -82,11 +82,15 @@ describe Spree::ReturnAuthorization do it "should add credit for specified amount" do return_authorization.amount = 20 - mock_adjustment = double - expect(mock_adjustment).to receive(:source=).with(return_authorization) - expect(mock_adjustment).to receive(:adjustable=).with(order) - expect(mock_adjustment).to receive(:save) - expect(Spree::Adjustment).to receive(:new).with(amount: -20, label: Spree.t(:rma_credit)).and_return(mock_adjustment) + + expect(Spree::Adjustment).to receive(:create).with( + amount: -20, + label: I18n.t('spree.rma_credit'), + order: order, + adjustable: order, + originator: return_authorization + ) + return_authorization.receive! end diff --git a/spec/models/spree/shipment_spec.rb b/spec/models/spree/shipment_spec.rb index 7359921472..559c7954bd 100644 --- a/spec/models/spree/shipment_spec.rb +++ b/spec/models/spree/shipment_spec.rb @@ -390,7 +390,7 @@ describe Spree::Shipment do it "should create adjustment when not present" do allow(shipment).to receive_messages(selected_shipping_rate_id: 1) expect(shipping_method).to receive(:create_adjustment).with(shipment.adjustment_label, - shipment, shipment, true, "open") + shipment, true, "open") shipment.__send__(:ensure_correct_adjustment) end @@ -423,13 +423,6 @@ describe Spree::Shipment do end end - context "update_order" do - it "should update order" do - expect(order).to receive_message_chain(:reload, :update!) - shipment.__send__(:update_order) - end - end - describe "#update_amounts" do it "persists the shipping cost from the shipping fee adjustment" do allow(shipment).to receive(:fee_adjustment) { double(:adjustment, amount: 10) } @@ -442,7 +435,7 @@ describe Spree::Shipment do context "after_save" do it "should run correct callbacks" do expect(shipment).to receive(:ensure_correct_adjustment) - expect(shipment).to receive(:update_order) + expect(shipment).to receive(:update_adjustments) shipment.run_callbacks(:save) end end diff --git a/spec/models/spree/shipping_rate_spec.rb b/spec/models/spree/shipping_rate_spec.rb index 03871722fe..d071b15c3c 100644 --- a/spec/models/spree/shipping_rate_spec.rb +++ b/spec/models/spree/shipping_rate_spec.rb @@ -10,21 +10,10 @@ describe Spree::ShippingRate do shipping_method: shipping_method, cost: 10.55) } - before { allow(Spree::TaxRate).to receive_messages(default: 0.05) } context "#display_price" do - context "when shipment includes VAT" do - before { Spree::Config[:shipment_inc_vat] = true } - it "displays the correct price" do - expect(shipping_rate.display_price.to_s).to eq "$11.08" # $10.55 * 1.05 == $11.08 - end - end - - context "when shipment does not include VAT" do - before { Spree::Config[:shipment_inc_vat] = false } - it "displays the correct price" do - expect(shipping_rate.display_price.to_s).to eq "$10.55" - end + it "displays the shipping price" do + expect(shipping_rate.display_price.to_s).to eq "$10.55" end context "when the currency is JPY" do diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index 3a6975a8c8..406f41fdca 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -189,4 +189,11 @@ describe Spree::User do expect { user.destroy }.to raise_exception(Spree::User::DestroyWithOrdersError) end end + + describe "#flipper_id" do + it "provides a unique id" do + user = Spree::User.new(id: 42) + expect(user.flipper_id).to eq "Spree::User;42" + end + end end diff --git a/spec/models/spree/variant_spec.rb b/spec/models/spree/variant_spec.rb index 50214cf6b4..3589df55aa 100644 --- a/spec/models/spree/variant_spec.rb +++ b/spec/models/spree/variant_spec.rb @@ -18,6 +18,11 @@ module Spree variant.price = 0 expect(variant).to be_valid end + + it "should validate unit_value is greater than 0" do + variant.unit_value = 0 + expect(variant).to be_invalid + end end context "price parsing" do @@ -742,4 +747,21 @@ module Spree end end end + + + describe "#default_price" do + let(:variant) { create(:variant) } + let(:default_price) { variant.default_price } + + context "when the default price is soft-deleted" do + it "can access the default price" do + price_id = default_price.id + + default_price.destroy + + expect(variant.reload.default_price).to be_a Spree::Price + expect(variant.default_price.id).to eq price_id + end + end + end end diff --git a/spec/models/tag_rule/discount_order_spec.rb b/spec/models/tag_rule/discount_order_spec.rb deleted file mode 100644 index 1da5635c5e..0000000000 --- a/spec/models/tag_rule/discount_order_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe TagRule::DiscountOrder, type: :model do - let!(:tag_rule) { create(:tag_rule) } - - pending "determining relevance based on additional requirements" do - let(:subject) { double(:subject) } - - before do - tag_rule.context = { subject: subject } - allow(tag_rule).to receive(:customer_tags_match?) { true } - allow(subject).to receive(:class) { Spree::Order } - end - - context "when already_applied? returns false" do - before { expect(tag_rule).to receive(:already_applied?) { false } } - - it "returns true" do - expect(tag_rule.send(:relevant?)).to be true - end - end - - context "when already_applied? returns true" do - before { expect(tag_rule).to receive(:already_applied?) { true } } - - it "returns false immediately" do - expect(tag_rule.send(:relevant?)).to be false - end - end - end - - pending "determining whether a the rule has already been applied to an order" do - let!(:order) { create(:order) } - let!(:adjustment) { order.adjustments.create({ amount: 12.34, source: order, originator: tag_rule, label: 'discount' }) } - - before do - tag_rule.context = { subject: order } - end - - context "where adjustments originating from the rule already exist" do - it { expect(tag_rule.send(:already_applied?)).to be true } - end - - context "where existing adjustments originate from other rules" do - before { adjustment.update_attribute(:originator_id, create(:tag_rule).id) } - it { expect(tag_rule.send(:already_applied?)).to be false } - end - end - - pending "applying the rule" do - # Assume that all validation is done by the TagRule base class - - let!(:line_item) { create(:line_item, price: 100.00) } - let!(:order) { line_item.order } - - before do - order.recreate_all_fees! - tag_rule.calculator.update_attribute(:preferred_flat_percent, -10.00) - tag_rule.context = { subject: order } - end - - context "in a simple scenario" do - let(:adjustment) { order.reload.adjustments.where(originator_id: tag_rule, originator_type: "TagRule").first } - - it "creates a new adjustment on the order" do - tag_rule.send(:apply!) - expect(adjustment).to be_a Spree::Adjustment - expect(adjustment.amount).to eq(-10.00) - expect(adjustment.label).to eq "Discount" - expect(order.adjustment_total).to eq(-10.00) - expect(order.total).to eq 90.00 - end - end - - context "when shipping charges apply" do - let!(:shipping_method) { create(:shipping_method, calculator: Calculator::FlatRate.new( preferred_amount: 25.00 ) ) } - before do - shipping_method.create_adjustment("Shipping", order, order, true) - end - - let(:adjustment) { order.reload.adjustments.where(originator_id: tag_rule, originator_type: "TagRule").first } - - it "the adjustment is made on line item total, ie. ignores the shipping amount" do - tag_rule.send(:apply!) - expect(adjustment).to be_a Spree::Adjustment - expect(adjustment.amount).to eq(-10.00) - expect(adjustment.label).to eq "Discount" - expect(order.adjustment_total).to eq 15.00 - expect(order.total).to eq 115.00 - end - end - end -end diff --git a/spec/performance/injection_helper_spec.rb b/spec/performance/injection_helper_spec.rb index 9bf1d8e147..1d67842640 100644 --- a/spec/performance/injection_helper_spec.rb +++ b/spec/performance/injection_helper_spec.rb @@ -22,7 +22,7 @@ describe InjectionHelper, type: :helper, performance: true do ActiveRecord::Base.connection.query_cache.clear Rails.cache.delete_matched('api\/cached_enterprise_serializer\/enterprises') result = Benchmark.measure { helper.inject_enterprises } - results << result.total if i > 0 + results << result.total if i.positive? puts result end diff --git a/spec/performance/shop_controller_spec.rb b/spec/performance/shop_controller_spec.rb index 6a052e67dc..ba116dbc66 100644 --- a/spec/performance/shop_controller_spec.rb +++ b/spec/performance/shop_controller_spec.rb @@ -37,7 +37,7 @@ describe ShopController, type: :controller, performance: true do it "returns products via json" do results = multi_benchmark(3, cache_key_patterns: cache_key_patterns) do - xhr :get, :products + get :products, xhr: true expect(response).to be_success end end diff --git a/spec/queries/outstanding_balance_spec.rb b/spec/queries/outstanding_balance_spec.rb index bd21b9da9e..2586d4eede 100644 --- a/spec/queries/outstanding_balance_spec.rb +++ b/spec/queries/outstanding_balance_spec.rb @@ -12,8 +12,8 @@ describe OutstandingBalance do normalized_sql_statement = normalize(outstanding_balance.statement) expect(normalized_sql_statement).to eq(normalize(<<-SQL)) - CASE WHEN state IN ('canceled', 'returned') THEN payment_total - WHEN state IS NOT NULL THEN payment_total - total + CASE WHEN "spree_orders"."state" IN ('canceled', 'returned') THEN "spree_orders"."payment_total" + WHEN "spree_orders"."state" IS NOT NULL THEN "spree_orders"."payment_total" - "spree_orders"."total" ELSE 0 END SQL end diff --git a/spec/requests/api/orders_spec.rb b/spec/requests/api/orders_spec.rb index 50b2c677ff..556ff4a619 100644 --- a/spec/requests/api/orders_spec.rb +++ b/spec/requests/api/orders_spec.rb @@ -2,8 +2,8 @@ require 'swagger_helper' -describe 'api/orders', type: :request do - path '/api/orders' do +describe 'api/v0/orders', type: :request do + path '/api/v0/orders' do get('list orders') do tags 'Orders' # type should be replaced with swagger 3.01 valid schema: {type: string} when rswag #317 is resolved: diff --git a/spec/requests/api/routes_spec.rb b/spec/requests/api/routes_spec.rb new file mode 100644 index 0000000000..fa7d1b20bc --- /dev/null +++ b/spec/requests/api/routes_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# test a single endpoint to make sure the redirects are working as intended. +require 'spec_helper' + +describe 'Orders Cycles endpoint', type: :request do + let(:distributor) { create(:distributor_enterprise) } + let(:order_cycle) { create(:order_cycle, distributors: [distributor]) } + + context "requesting the latest version" do + let(:path) { "/api/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}" } + + it "redirects to v0, preserving URL params" do + get path + expect(response).to redirect_to( + "/api/v0/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}" + ) + end + end + + context "requesting a specific API version" do + let(:path) { "/api/v0/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}" } + + it "does not redirect" do + get path + expect(response.status).to eq(200) + end + end +end diff --git a/spec/requests/checkout/failed_checkout_spec.rb b/spec/requests/checkout/failed_checkout_spec.rb index efd44cbb31..9dade977c1 100644 --- a/spec/requests/checkout/failed_checkout_spec.rb +++ b/spec/requests/checkout/failed_checkout_spec.rb @@ -16,7 +16,7 @@ describe "checking out an order that initially fails", type: :request do let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method) } let!(:order) { create(:order, shipments: [shipment], distributor: shop, order_cycle: order_cycle) } let(:params) do - { format: :json, order: { + { order: { shipping_method_id: shipping_method.id, payments_attributes: [{ payment_method_id: payment_method.id }], bill_address_attributes: address.attributes.slice("firstname", "lastname", "address1", "address2", "phone", "city", "zipcode", "state_id", "country_id"), @@ -46,7 +46,7 @@ describe "checking out an order that initially fails", type: :request do end it "clears shipments and payments before rendering the checkout" do - put update_checkout_path, params + put update_checkout_path, params: params, as: :json # Checking out a BogusGateway without a source fails at :payment # Shipments and payments should then be cleared before rendering checkout @@ -62,7 +62,8 @@ describe "checking out an order that initially fails", type: :request do # Use a check payment method, which should work params[:order][:payments_attributes][0][:payment_method_id] = check_payment_method.id - put update_checkout_path, params + + put update_checkout_path, params: params, as: :json expect(response.status).to be 200 order.reload diff --git a/spec/requests/checkout/paypal_spec.rb b/spec/requests/checkout/paypal_spec.rb index a6436d4347..c8ebbd7585 100644 --- a/spec/requests/checkout/paypal_spec.rb +++ b/spec/requests/checkout/paypal_spec.rb @@ -52,10 +52,10 @@ describe "checking out an order with a paypal express payment method", type: :re # Sanity check to condition of the order before we confirm the payment expect(order.payments.count).to eq 1 expect(order.payments.first.state).to eq "checkout" - expect(order.adjustments.payment_fee.count).to eq 1 - expect(order.adjustments.payment_fee.first.amount).to eq 1.5 + expect(order.all_adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.first.amount).to eq 1.5 - get spree.confirm_paypal_path, params + get spree.confirm_paypal_path, params: params # Processing was successful, order is complete expect(response).to redirect_to order_path(order, token: order.token) @@ -64,8 +64,8 @@ describe "checking out an order with a paypal express payment method", type: :re # We have only one payment, and one transaction fee expect(order.payments.count).to eq 1 expect(order.payments.first.state).to eq "completed" - expect(order.adjustments.payment_fee.count).to eq 1 - expect(order.adjustments.payment_fee.first.amount).to eq 1.5 + expect(order.all_adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.first.amount).to eq 1.5 end end end diff --git a/spec/requests/checkout/stripe_connect_spec.rb b/spec/requests/checkout/stripe_connect_spec.rb index 63eea0e5c8..9a01b28511 100644 --- a/spec/requests/checkout/stripe_connect_spec.rb +++ b/spec/requests/checkout/stripe_connect_spec.rb @@ -102,7 +102,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re context "and the charge request is successful" do it "should process the payment without storing card details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -124,7 +124,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -159,7 +159,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re context "and the store, token and charge requests are successful" do it "should process the payment, and stores the card/customer details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -181,7 +181,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -197,7 +197,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -213,7 +213,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re # Note, no requests have been stubbed it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -261,7 +261,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re context "and the charge and token requests are accepted" do it "should process the payment, and keep the profile ids and other card details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -283,7 +283,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -298,7 +298,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 diff --git a/spec/requests/checkout/stripe_sca_spec.rb b/spec/requests/checkout/stripe_sca_spec.rb index 49c99b7ce0..5b1df19196 100644 --- a/spec/requests/checkout/stripe_sca_spec.rb +++ b/spec/requests/checkout/stripe_sca_spec.rb @@ -128,7 +128,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques context "and the payment intent request is successful" do it "should process the payment without storing card details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -150,7 +150,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -216,7 +216,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques context "and the customer, payment_method and payment_intent requests are successful" do it "should process the payment, and store the card/customer details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -238,7 +238,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -254,7 +254,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -269,7 +269,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -301,7 +301,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques context "and the payment intent and payment method requests are accepted" do it "should process the payment, and keep the profile ids and other card details" do - put update_checkout_path, params + put update_checkout_path, params: params expect(json_response["path"]).to eq order_path(order) expect(order.payments.completed.count).to be 1 @@ -323,7 +323,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "should not process the payment" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 400 @@ -344,7 +344,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques end it "redirects the user to the authorization stripe url" do - put update_checkout_path, params + put update_checkout_path, params: params expect(response.status).to be 200 expect(response.body).to include stripe_redirect_url diff --git a/spec/serializers/api/admin/customer_serializer_spec.rb b/spec/serializers/api/admin/customer_serializer_spec.rb index bece0d1c53..8fe819ddae 100644 --- a/spec/serializers/api/admin/customer_serializer_spec.rb +++ b/spec/serializers/api/admin/customer_serializer_spec.rb @@ -5,7 +5,10 @@ require 'spec_helper' describe Api::Admin::CustomerSerializer do let(:tag_list) { ["one", "two", "three"] } let(:customer) { create(:customer, tag_list: tag_list) } - let!(:tag_rule) { create(:tag_rule, enterprise: customer.enterprise, preferred_customer_tags: "two") } + let!(:tag_rule) { + create(:filter_order_cycles_tag_rule, enterprise: customer.enterprise, + preferred_customer_tags: "two") + } it "serializes a customer with tags" do tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: customer.enterprise_id)) diff --git a/spec/serializers/api/order_serializer_spec.rb b/spec/serializers/api/order_serializer_spec.rb index d635cf0ada..7bad390442 100644 --- a/spec/serializers/api/order_serializer_spec.rb +++ b/spec/serializers/api/order_serializer_spec.rb @@ -6,6 +6,10 @@ describe Api::OrderSerializer do let(:serializer) { Api::OrderSerializer.new order } let(:order) { create(:completed_order_with_totals) } + before do + allow(order).to receive(:balance_value).and_return(-1.23) + end + describe '#serializable_hash' do let!(:completed_payment) do create(:payment, order: order, state: 'completed', amount: order.total - 1) @@ -31,30 +35,8 @@ describe Api::OrderSerializer do end describe '#outstanding_balance' do - context 'when the customer_balance feature is enabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, order.user) { true } - - allow(order).to receive(:balance_value).and_return(-1.23) - end - - it "returns the object's balance_value from the users perspective" do - expect(serializer.serializable_hash[:outstanding_balance]).to eq(1.23) - end - end - - context 'when the customer_balance is not enabled' do - before do - allow(OpenFoodNetwork::FeatureToggle) - .to receive(:enabled?).with(:customer_balance, order.user) { false } - - allow(order).to receive(:outstanding_balance).and_return(123.0) - end - - it 'calls #outstanding_balance on the object' do - expect(serializer.serializable_hash[:outstanding_balance]).to eq(123.0) - end + it "returns the object's balance_value from the users perspective" do + expect(serializer.serializable_hash[:outstanding_balance]).to eq(1.23) end end end diff --git a/spec/serializers/api/variant_serializer_spec.rb b/spec/serializers/api/variant_serializer_spec.rb index 730f91127d..26550a8f0b 100644 --- a/spec/serializers/api/variant_serializer_spec.rb +++ b/spec/serializers/api/variant_serializer_spec.rb @@ -25,4 +25,22 @@ describe Api::VariantSerializer do :tag_list # Used to apply tag rules ) end + + describe "#unit_price_price" do + context "without fees" do + it "displays the price divided by the unit price denominator" do + allow(subject).to receive_message_chain(:unit_price, :denominator) { 1000 } + + expect(subject.unit_price_price).to eq(variant.price / 1000) + end + end + + context "when the denominator returns nil" do + it "returns the price" do + allow(subject).to receive_message_chain(:unit_price, :denominator) { nil } + + expect(subject.unit_price_price).to eq(variant.price) + end + end + end end diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 3a89609de2..78a324f0f2 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -1,9 +1,11 @@ # frozen_string_literal: false require 'spec_helper' +require 'spree/admin/payments_helper' describe BulkInvoiceService do include ActiveJob::TestHelper + include Spree::Admin::PaymentsHelper let(:service) { BulkInvoiceService.new } diff --git a/spec/services/cart_service_spec.rb b/spec/services/cart_service_spec.rb index b8144f867b..51e8f2b882 100644 --- a/spec/services/cart_service_spec.rb +++ b/spec/services/cart_service_spec.rb @@ -27,7 +27,8 @@ describe CartService do describe "#populate" do it "adds a variant" do cart_service.populate( - { variants: { variant.id.to_s => { quantity: '1', max_quantity: '2' } } }, + ActionController::Parameters.new({ variants: { variant.id.to_s => { quantity: '1', + max_quantity: '2' } } }), true ) li = order.find_line_item_by_variant(variant) @@ -41,7 +42,8 @@ describe CartService do order.add_variant variant, 1, 2 cart_service.populate( - { variants: { variant.id.to_s => { quantity: '2', max_quantity: '3' } } }, + ActionController::Parameters.new({ variants: { variant.id.to_s => { quantity: '2', + max_quantity: '3' } } }), true ) li = order.find_line_item_by_variant(variant) @@ -54,7 +56,7 @@ describe CartService do it "removes a variant" do order.add_variant variant, 1, 2 - cart_service.populate({ variants: {} }, true) + cart_service.populate(ActionController::Parameters.new({ variants: {} }), true) order.line_items.reload li = order.find_line_item_by_variant(variant) expect(li).not_to be @@ -67,7 +69,7 @@ describe CartService do it "does not add the deleted variant to the cart" do variant.delete - cart_service.populate({ variants: { variant.id.to_s => { quantity: '2' } } }, true) + cart_service.populate(ActionController::Parameters.new({ variants: { variant.id.to_s => { quantity: '2' } } }), true) expect(relevant_line_item).to be_nil expect(cart_service.errors.count).to be 0 @@ -82,7 +84,7 @@ describe CartService do it "removes the line_item from the cart" do variant.delete - cart_service.populate({ variants: { variant.id.to_s => { quantity: '3' } } }, true) + cart_service.populate(ActionController::Parameters.new({ variants: { variant.id.to_s => { quantity: '3' } } }), true) expect(Spree::LineItem.where(id: relevant_line_item).first).to be_nil expect(cart_service.errors.count).to be 0 diff --git a/spec/services/invoice_renderer_spec.rb b/spec/services/invoice_renderer_spec.rb index d78f5e97a8..cb861d2da6 100644 --- a/spec/services/invoice_renderer_spec.rb +++ b/spec/services/invoice_renderer_spec.rb @@ -1,8 +1,11 @@ # frozen_string_literal: true require 'spec_helper' +require 'spree/admin/payments_helper' describe InvoiceRenderer do + include Spree::Admin::PaymentsHelper + let(:service) { described_class.new } let(:order) do order = create(:completed_order_with_fees) @@ -17,7 +20,7 @@ describe InvoiceRenderer do it 'uses the invoice2 template' do renderer = instance_double(ApplicationController) expect(renderer) - .to receive(:render_to_string) + .to receive(:render_to_string_with_wicked_pdf) .with(include(template: 'spree/admin/orders/invoice2')) described_class.new(renderer).render_to_string(order) @@ -35,7 +38,7 @@ describe InvoiceRenderer do it 'uses the invoice template' do renderer = instance_double(ApplicationController) expect(renderer) - .to receive(:render_to_string) + .to receive(:render_to_string_with_wicked_pdf) .with(include(template: 'spree/admin/orders/invoice')) described_class.new(renderer).render_to_string(order) diff --git a/spec/services/order_checkout_restart_spec.rb b/spec/services/order_checkout_restart_spec.rb index a5b7258e74..07c8c294b6 100644 --- a/spec/services/order_checkout_restart_spec.rb +++ b/spec/services/order_checkout_restart_spec.rb @@ -53,18 +53,18 @@ describe OrderCheckoutRestart do expect(order.state).to eq 'payment' expect(order.shipments.count).to eq 1 - expect(order.adjustments.shipping.count).to eq 0 + expect(order.all_adjustments.shipping.count).to eq 0 expect(order.payments.count).to eq 2 - expect(order.adjustments.payment_fee.count).to eq 2 + expect(order.all_adjustments.payment_fee.count).to eq 2 end end def expect_cart_state_and_reset_adjustments expect(order.state).to eq 'cart' expect(order.shipments.count).to eq 0 - expect(order.adjustments.shipping.count).to eq 0 + expect(order.all_adjustments.shipping.count).to eq 0 expect(order.payments.count).to eq 1 - expect(order.adjustments.payment_fee.count).to eq 1 + expect(order.all_adjustments.payment_fee.count).to eq 1 end end end diff --git a/spec/services/order_tax_adjustments_fetcher_spec.rb b/spec/services/order_tax_adjustments_fetcher_spec.rb index f5edd0d848..866927d39f 100644 --- a/spec/services/order_tax_adjustments_fetcher_spec.rb +++ b/spec/services/order_tax_adjustments_fetcher_spec.rb @@ -46,7 +46,7 @@ describe OrderTaxAdjustmentsFetcher do end let(:admin_adjustment) do create(:adjustment, order: order, amount: 50.0, included_tax: tax_rate25.compute_tax(50.0), - source: nil, label: "Admin Adjustment") + label: "Admin Adjustment") end let(:order_cycle) do @@ -66,14 +66,9 @@ describe OrderTaxAdjustmentsFetcher do distributor: coordinator ) end - - before do - allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true) - allow(Spree::Config).to receive(:shipping_tax_rate).and_return(tax_rate15.amount) - end - let(:shipping_method) do - create(:shipping_method, calculator: Calculator::FlatRate.new(preferred_amount: 46.0)) + create(:shipping_method, calculator: Calculator::FlatRate.new(preferred_amount: 46.0), + tax_category: tax_category15) end let!(:shipment) do create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) diff --git a/spec/services/paypal_items_builder_spec.rb b/spec/services/paypal_items_builder_spec.rb index 86a6646878..168089c0d1 100644 --- a/spec/services/paypal_items_builder_spec.rb +++ b/spec/services/paypal_items_builder_spec.rb @@ -21,11 +21,12 @@ describe PaypalItemsBuilder do context "listing adjustments" do let!(:admin_adjustment) { create(:adjustment, label: "Admin Adjustment", order: order, adjustable: order, - amount: 12, source: nil, originator: nil, state: "closed") + amount: 12, originator: nil, state: "closed") } let!(:ineligible_adjustment) { create(:adjustment, label: "Ineligible Adjustment", order: order, adjustable: order, - amount: 34, eligible: false, state: "closed") + amount: 34, eligible: false, state: "closed", + originator_type: "Spree::PaymentMethod") } let!(:zone) { create(:zone_with_member) } let!(:included_tax_rate) { @@ -47,9 +48,8 @@ describe PaypalItemsBuilder do } let!(:enterprise_fee) { create(:enterprise_fee) } let!(:line_item_enterprise_fee) { - create(:adjustment, label: "Line Item Fee", order: order, adjustable: order, - amount: 91, originator: enterprise_fee, source: order.line_items.first, - state: "closed") + create(:adjustment, label: "Line Item Fee", order: order, adjustable: order.line_items.first, + amount: 91, originator: enterprise_fee, state: "closed") } let!(:order_enterprise_fee) { create(:adjustment, label: "Order Fee", order: order, adjustable: order, diff --git a/spec/services/unit_prices_spec.rb b/spec/services/unit_prices_spec.rb new file mode 100644 index 0000000000..0e836f2c29 --- /dev/null +++ b/spec/services/unit_prices_spec.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe UnitPrice do + subject { UnitPrice.new(variant) } + let(:variant) { Spree::Variant.new } + let(:product) { instance_double(Spree::Product) } + + before do + allow(variant).to receive(:product) { product } + end + + describe "#unit" do + context "metric" do + before do + allow(product).to receive(:variant_unit_scale) { 1.0 } + end + + it "returns kg for weight" do + allow(product).to receive(:variant_unit) { "weight" } + expect(subject.unit).to eq("kg") + end + + it "returns L for volume" do + allow(product).to receive(:variant_unit) { "volume" } + expect(subject.unit).to eq("L") + end + end + + context "imperial" do + it "returns lbs" do + allow(product).to receive(:variant_unit_scale) { 453.6 } + allow(product).to receive(:variant_unit) { "weight" } + expect(subject.unit).to eq("lb") + end + end + + context "items" do + it "returns items if no unit is specified" do + allow(product).to receive(:variant_unit_name) { nil } + allow(product).to receive(:variant_unit_scale) { nil } + allow(product).to receive(:variant_unit) { "items" } + expect(subject.unit).to eq("Item") + end + + it "returns the unit if a unit is specified" do + allow(product).to receive(:variant_unit_name) { "bunch" } + allow(product).to receive(:variant_unit_scale) { nil } + allow(product).to receive(:variant_unit) { "items" } + expect(subject.unit).to eq("bunch") + end + end + end + + describe "#denominator" do + context "metric" do + it "returns 0.5 for a 500g variant" do + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(product).to receive(:variant_unit) { "weight" } + variant.unit_value = 500 + expect(subject.denominator).to eq(0.5) + end + + it "returns 2 for a 2kg variant" do + allow(product).to receive(:variant_unit_scale) { 1000 } + allow(product).to receive(:variant_unit) { "weight" } + variant.unit_value = 2000 + expect(subject.denominator).to eq(2) + end + + it "returns 0.5 for a 500mL variant" do + allow(product).to receive(:variant_unit_scale) { 0.001 } + allow(product).to receive(:variant_unit) { "volume" } + variant.unit_value = 0.5 + expect(subject.denominator).to eq(0.5) + end + end + + context "imperial" do + it "returns 2 for a 2 pound variant" do + allow(product).to receive(:variant_unit_scale) { 453.6 } + allow(product).to receive(:variant_unit) { "weight" } + variant.unit_value = 2*453.6 + expect(subject.denominator).to eq(2) + end + end + + context "items" do + it "returns 1 if no unit is specified" do + allow(product).to receive(:variant_unit_scale) { nil } + allow(product).to receive(:variant_unit) { "items" } + variant.unit_value = 1 + expect(subject.denominator).to eq(1) + end + + it "returns 2 for multi-item units" do + allow(product).to receive(:variant_unit_scale) { nil } + allow(product).to receive(:variant_unit) { "items" } + variant.unit_value = 2 + expect(subject.denominator).to eq(2) + end + end + end +end diff --git a/spec/services/weights_and_measures_spec.rb b/spec/services/weights_and_measures_spec.rb new file mode 100644 index 0000000000..c6f98e6e5a --- /dev/null +++ b/spec/services/weights_and_measures_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe WeightsAndMeasures do + subject { WeightsAndMeasures.new(variant) } + let(:variant) { Spree::Variant.new } + let(:product) { instance_double(Spree::Product) } + + before do + allow(variant).to receive(:product) { product } + end + + describe "#system" do + context "weight" do + before do + allow(product).to receive(:variant_unit) { "weight" } + end + + it "when scale is for a metric unit" do + allow(product).to receive(:variant_unit_scale) { 1.0 } + expect(subject.system).to eq("metric") + end + + it "when scale is for an imperial unit" do + allow(product).to receive(:variant_unit_scale) { 28.35 } + expect(subject.system).to eq("imperial") + end + end + + context "volume" do + it "when scale is for a metric unit" do + allow(product).to receive(:variant_unit) { "volume" } + allow(product).to receive(:variant_unit_scale) { 1.0 } + expect(subject.system).to eq("metric") + end + end + + context "items" do + it "when variant unit is items" do + allow(product).to receive(:variant_unit) { "items" } + allow(product).to receive(:variant_unit_scale) { nil } + expect(subject.system).to eq("custom") + end + + it "when variant unit is items, even if the scale is present" do + allow(product).to receive(:variant_unit) { "items" } + allow(product).to receive(:variant_unit_scale) { 1.0 } + expect(subject.system).to eq("custom") + end + end + end + + describe "#scale_for_unit_value" do + context "weight" do + before do + allow(product).to receive(:variant_unit) { "weight" } + end + + context "metric" do + it "for a unit value that should display in grams" do + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 500 } + expect(subject.scale_for_unit_value).to eq([1.0, "g"]) + end + + it "for a unit value that should display in kg" do + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 1500 } + expect(subject.scale_for_unit_value).to eq([1000.0, "kg"]) + end + end + end + + context "volume" do + it "for a unit value that should display in L" do + allow(product).to receive(:variant_unit) { "volume" } + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 1500 } + expect(subject.scale_for_unit_value).to eq([1000, "kL"]) + end + end + + context "items" do + it "when scale is for items" do + allow(product).to receive(:variant_unit) { "items" } + allow(product).to receive(:variant_unit_scale) { nil } + allow(variant).to receive(:unit_value) { 4 } + expect(subject.scale_for_unit_value).to eq([nil, nil]) + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c4280c90e4..b483c52be9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -74,6 +74,8 @@ require "paperclip/matchers" # Override setting in Spree engine: Spree::Core::MailSettings ActionMailer::Base.default_url_options[:host] = 'test.host' +require "view_component/test_helpers" + RSpec.configure do |config| # ## Mock Framework # @@ -184,7 +186,6 @@ RSpec.configure do |config| # Helpers config.include Rails.application.routes.url_helpers config.include Spree::UrlHelpers - config.include Spree::CheckoutHelpers config.include Spree::MoneyHelper config.include PreferencesHelper config.include ControllerRequestsHelper, type: :controller @@ -233,6 +234,8 @@ RSpec.configure do |config| # PerfTools::CpuProfiler.stop # end config.infer_spec_type_from_file_location! + + config.include ViewComponent::TestHelpers, type: :component end FactoryBot.use_parent_strategy = false diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index fa02ed71d1..4b992f5949 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -47,9 +47,9 @@ module ControllerRequestsHelper def process_action_with_route(action, params = {}, session = nil, flash = nil, method = "GET") process(action, - method, - params.reverse_merge!(use_route: :main_app), - session, - flash) + method: method, + params: params.reverse_merge!(use_route: :main_app), + session: session, + flash: flash) end end diff --git a/spec/support/i18n_error_raising.rb b/spec/support/i18n_error_raising.rb deleted file mode 100644 index d25faccdc4..0000000000 --- a/spec/support/i18n_error_raising.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -# From: https://robots.thoughtbot.com/better-tests-through-internationalization - -I18n.exception_handler = lambda do |_exception, _locale, key, _options| - raise "missing translation: #{key}" -end diff --git a/spec/support/request/checkout_helper.rb b/spec/support/request/checkout_request_helper.rb similarity index 97% rename from spec/support/request/checkout_helper.rb rename to spec/support/request/checkout_request_helper.rb index e27ffd27ed..3a6de815bd 100644 --- a/spec/support/request/checkout_helper.rb +++ b/spec/support/request/checkout_request_helper.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module CheckoutHelper +module CheckoutRequestsHelper def have_checkout_details have_content "Your details" end diff --git a/spec/support/request/ui_component_helper.rb b/spec/support/request/ui_component_helper.rb index 6b85e51768..bfaee94a40 100644 --- a/spec/support/request/ui_component_helper.rb +++ b/spec/support/request/ui_component_helper.rb @@ -78,7 +78,7 @@ module UIComponentHelper def wait_for_ajax counter = 0 - while page.execute_script("return $.active").to_i > 0 + while page.execute_script("return $.active").to_i.positive? counter += 1 sleep(0.1) raise "AJAX request took longer than 5 seconds." if counter >= 50 diff --git a/spec/support/request/web_helper.rb b/spec/support/request/web_helper.rb index 334b913d4b..86ba297357 100644 --- a/spec/support/request/web_helper.rb +++ b/spec/support/request/web_helper.rb @@ -157,6 +157,6 @@ module WebHelper end def wait_for_ajax - wait_until { page.evaluate_script("$.active") == 0 } + wait_until { page.evaluate_script("$.active").zero? } end end diff --git a/spec/support/spree/checkout_helpers.rb b/spec/support/spree/checkout_helpers.rb deleted file mode 100644 index 7731fe3822..0000000000 --- a/spec/support/spree/checkout_helpers.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Spree - module CheckoutHelpers - def click_checkout_continue_button - page.find('#add_new_save_checkout_button input[type=submit]').click - end - end -end diff --git a/spec/views/spree/admin/orders/edit.html.haml_spec.rb b/spec/views/spree/admin/orders/edit.html.haml_spec.rb index 4394065394..73d62340ab 100644 --- a/spec/views/spree/admin/orders/edit.html.haml_spec.rb +++ b/spec/views/spree/admin/orders/edit.html.haml_spec.rb @@ -4,6 +4,9 @@ require "spec_helper" describe "spree/admin/orders/edit.html.haml" do helper Spree::BaseHelper # required to make pretty_time work + helper Spree::Admin::NavigationHelper + helper Admin::InjectionHelper + helper Admin::OrdersHelper around do |example| original_config = Spree::Config[:enable_invoices?] diff --git a/spec/views/spree/admin/orders/index.html.haml_spec.rb b/spec/views/spree/admin/orders/index.html.haml_spec.rb index d9556bd76a..9087a07b09 100644 --- a/spec/views/spree/admin/orders/index.html.haml_spec.rb +++ b/spec/views/spree/admin/orders/index.html.haml_spec.rb @@ -3,6 +3,9 @@ require "spec_helper" describe "spree/admin/orders/index.html.haml" do + helper Spree::Admin::NavigationHelper + helper EnterprisesHelper + around do |example| original_config = Spree::Config[:enable_invoices?] example.run diff --git a/spec/views/spree/admin/orders/invoice.html.haml_spec.rb b/spec/views/spree/admin/orders/invoice.html.haml_spec.rb index 32c3dd169d..8b49a142e8 100644 --- a/spec/views/spree/admin/orders/invoice.html.haml_spec.rb +++ b/spec/views/spree/admin/orders/invoice.html.haml_spec.rb @@ -21,6 +21,10 @@ describe "spree/admin/orders/invoice.html.haml" do before do assign(:order, order) + allow(view).to receive_messages checkout_adjustments_for: [], + display_checkout_tax_total: '10', + display_checkout_total_less_tax: '8', + outstanding_balance_label: 'Outstanding Balance' end it "displays the customer code" do diff --git a/spec/views/spree/admin/payment_methods/index.html.haml_spec.rb b/spec/views/spree/admin/payment_methods/index.html.haml_spec.rb index 3b6b6d5aba..2fb34ef37e 100644 --- a/spec/views/spree/admin/payment_methods/index.html.haml_spec.rb +++ b/spec/views/spree/admin/payment_methods/index.html.haml_spec.rb @@ -4,6 +4,8 @@ require "spec_helper" describe "spree/admin/payment_methods/index.html.haml" do include AuthenticationHelper + helper Spree::Admin::NavigationHelper + helper Spree::Admin::BaseHelper before do controller.singleton_class.class_eval do diff --git a/spec/views/spree/orders/edit.html.haml_spec.rb b/spec/views/spree/orders/edit.html.haml_spec.rb index 38b112a759..f51f3ec05e 100644 --- a/spec/views/spree/orders/edit.html.haml_spec.rb +++ b/spec/views/spree/orders/edit.html.haml_spec.rb @@ -3,6 +3,14 @@ require "spec_helper" describe "spree/orders/edit.html.haml" do + helper InjectionHelper + helper ShopHelper + helper ApplicationHelper + helper CheckoutHelper + helper SharedHelper + helper FooterLinksHelper + helper MarkdownHelper + let(:order) { create(:completed_order_with_fees) } before do diff --git a/spec/views/spree/shared/_order_details.html.haml_spec.rb b/spec/views/spree/shared/_order_details.html.haml_spec.rb index d1b7986203..5a37c4519e 100644 --- a/spec/views/spree/shared/_order_details.html.haml_spec.rb +++ b/spec/views/spree/shared/_order_details.html.haml_spec.rb @@ -5,6 +5,8 @@ require "spec_helper" describe "spree/shared/_order_details.html.haml" do include AuthenticationHelper helper Spree::BaseHelper + helper CheckoutHelper + helper OrderHelper let(:order) { create(:completed_order_with_fees) } @@ -12,7 +14,7 @@ describe "spree/shared/_order_details.html.haml" do assign(:order, order) allow(view).to receive_messages( order: order, - current_order: order, + current_order: order ) end diff --git a/yarn.lock b/yarn.lock index 89026669fc..9247b5b5f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,40 +2,2434 @@ # yarn lockfile v1 -accepts@1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" - integrity sha1-w8p0NJOGSMPg2cHjKN1otiLChMo= +"@babel/code-frame@7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: - mime-types "~2.1.11" - negotiator "0.6.1" + "@babel/highlight" "^7.10.4" -after@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" - integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= - -anymatch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" + "@babel/highlight" "^7.12.13" -arr-diff@^2.0.0: +"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" + integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== + +"@babel/core@7.12.9": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" + integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.5" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.9" + "@babel/types" "^7.12.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06" + integrity sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.9" + "@babel/helper-compilation-targets" "^7.13.13" + "@babel/helper-module-transforms" "^7.13.14" + "@babel/helpers" "^7.13.10" + "@babel/parser" "^7.13.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" + 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.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== + dependencies: + "@babel/types" "^7.13.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.10.4", "@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.10", "@babel/helper-compilation-targets@^7.13.13", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz#2b2972a0926474853f41e4adbc69338f520600e5" + integrity sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ== + dependencies: + "@babel/compat-data" "^7.13.12" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.13.0": + version "7.13.11" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" + integrity sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.0" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.0" + "@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.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" + integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== + 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.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8" + integrity sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g== + dependencies: + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helper-member-expression-to-functions@^7.13.0", "@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": + 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.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" + integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== + 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.12.11" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" + +"@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.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@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.12.13", "@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": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@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.12.5", "@babel/helpers@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" + integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.12.11", "@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.13.13": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" + integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== + +"@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.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1" + integrity sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA== + 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.12.1", "@babel/plugin-proposal-class-properties@^7.13.0": + 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-decorators@^7.12.12": + version "7.13.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.13.5.tgz#d28071457a5ba8ee1394b23e38d5dcf32ea20ef7" + integrity sha512-i0GDfVNuoapwiheevUOuSW67mInqJ8qw7uWfpjNVeHMn143kXblEy/bmL9AdZ/0yf/4BMQeWXezK0tQIvNPqag== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@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-default-from@^7.12.1": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.13.tgz#f110284108a9b2b96f01b15b3be9e54c2610a989" + integrity sha512-idIsBT+DGXdOHL82U+8bwX4goHm/z10g8sGGrQroh+HCRcm7mDv/luaGdWJQMTuCX2FsdXS7X0Nyyzp4znAPJA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-export-default-from" "^7.12.13" + +"@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.12.1", "@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.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" + +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@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.12.7", "@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.12.1", "@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-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-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-default-from@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.12.13.tgz#3c807d37efaf0a806f1deb556ccb3b2f562ae9c2" + integrity sha512-gVry0zqoums0hA+EniCYK3gABhjYSLX1dVuwYpPw9DrLNA4/GovXySHVg4FGRsZht09ON/5C2NVx3keq+qqVGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@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.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-jsx@^7.12.13": + 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", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@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-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-syntax-typescript@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" + integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-arrow-functions@^7.12.1", "@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.12.12", "@babel/plugin-transform-block-scoping@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" + integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-classes@^7.12.1", "@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.12.1", "@babel/plugin-transform-destructuring@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963" + integrity sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA== + 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.12.1", "@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.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3" + integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ== + dependencies: + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" + integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw== + dependencies: + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.12.13" + 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.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b" + integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw== + dependencies: + "@babel/helper-module-transforms" "^7.13.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.12.1", "@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-react-display-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" + integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-react-jsx-development@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz#f510c0fa7cd7234153539f9a362ced41a5ca1447" + integrity sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.12.17" + +"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.12.17", "@babel/plugin-transform-react-jsx@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz#1df5dfaf0f4b784b43e96da6f28d630e775f68b3" + integrity sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-jsx" "^7.12.13" + "@babel/types" "^7.13.12" + +"@babel/plugin-transform-react-pure-annotations@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" + integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-regenerator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5" + integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA== + 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-shorthand-properties@^7.12.1", "@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.12.1", "@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.12.1", "@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-typescript@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" + integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-typescript" "^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.12.11": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.12.tgz#6dff470478290582ac282fb77780eadf32480237" + integrity sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA== + dependencies: + "@babel/compat-data" "^7.13.12" + "@babel/helper-compilation-targets" "^7.13.10" + "@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.8" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@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-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-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-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.12.13" + "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.0" + "@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.13.0" + "@babel/plugin-transform-modules-commonjs" "^7.13.8" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.13.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.12.13" + "@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.13.12" + babel-plugin-polyfill-corejs2 "^0.1.4" + babel-plugin-polyfill-corejs3 "^0.1.3" + babel-plugin-polyfill-regenerator "^0.1.2" + 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/preset-react@^7.12.10": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.13.13.tgz#fa6895a96c50763fe693f9148568458d5a839761" + integrity sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-transform-react-display-name" "^7.12.13" + "@babel/plugin-transform-react-jsx" "^7.13.12" + "@babel/plugin-transform-react-jsx-development" "^7.12.17" + "@babel/plugin-transform-react-pure-annotations" "^7.12.1" + +"@babel/preset-typescript@^7.12.7": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz#ab107e5f050609d806fbb039bec553b33462c60a" + integrity sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-transform-typescript" "^7.13.0" + +"@babel/register@^7.12.1": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.13.14.tgz#bbfa8f4f027c2ebc432e8e69e078b632605f2d9b" + integrity sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q== + dependencies: + find-cache-dir "^2.0.0" + lodash "^4.17.19" + make-dir "^2.1.0" + pirates "^4.0.0" + source-map-support "^0.5.16" + +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.12.13", "@babel/template@^7.12.7": + 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.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" + integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.9" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.13.13" + "@babel/types" "^7.13.13" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.7", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.4.4": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" + integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@base2/pretty-print-object@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.0.tgz#860ce718b0b73f4009e153541faff2cb6b85d047" + integrity sha512-4Th98KlMHr5+JkxfcoDT//6vY8vM+iSPrLNpHhRyLx2CFYi8e2RfqPLdpbnpo0Q5lQC5hNB79yes07zb02fvCw== + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@emotion/cache@^10.0.27": + version "10.0.29" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" + integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== + dependencies: + "@emotion/sheet" "0.9.4" + "@emotion/stylis" "0.8.5" + "@emotion/utils" "0.11.3" + "@emotion/weak-memoize" "0.2.5" + +"@emotion/core@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" + integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" + +"@emotion/css@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" + integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== + dependencies: + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + babel-plugin-emotion "^10.0.27" + +"@emotion/hash@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/is-prop-valid@0.8.8", "@emotion/is-prop-valid@^0.8.6": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": + version "0.11.16" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" + integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== + dependencies: + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/unitless" "0.7.5" + "@emotion/utils" "0.11.3" + csstype "^2.5.7" + +"@emotion/sheet@0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" + integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== + +"@emotion/styled-base@^10.0.27": + version "10.0.31" + resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a" + integrity sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/is-prop-valid" "0.8.8" + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + +"@emotion/styled@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" + integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== + dependencies: + "@emotion/styled-base" "^10.0.27" + babel-plugin-emotion "^10.0.27" + +"@emotion/stylis@0.8.5": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + +"@emotion/utils@0.11.3": + version "0.11.3" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" + integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== + +"@emotion/weak-memoize@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" + integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@mdx-js/loader@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.22.tgz#d9e8fe7f8185ff13c9c8639c048b123e30d322c4" + integrity sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q== + dependencies: + "@mdx-js/mdx" "1.6.22" + "@mdx-js/react" "1.6.22" + loader-utils "2.0.0" + +"@mdx-js/mdx@1.6.22", "@mdx-js/mdx@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" + integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== + dependencies: + "@babel/core" "7.12.9" + "@babel/plugin-syntax-jsx" "7.12.1" + "@babel/plugin-syntax-object-rest-spread" "7.8.3" + "@mdx-js/util" "1.6.22" + babel-plugin-apply-mdx-type-prop "1.6.22" + babel-plugin-extract-import-names "1.6.22" + camelcase-css "2.0.1" + detab "2.0.4" + hast-util-raw "6.0.1" + lodash.uniq "4.5.0" + mdast-util-to-hast "10.0.1" + remark-footnotes "2.0.0" + remark-mdx "1.6.22" + remark-parse "8.0.3" + remark-squeeze-paragraphs "4.0.0" + style-to-object "0.3.0" + unified "9.2.0" + unist-builder "2.0.3" + unist-util-visit "2.0.3" + +"@mdx-js/react@1.6.22", "@mdx-js/react@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" + integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== + +"@mdx-js/util@1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" + integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== + +"@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.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== + dependencies: + "@nodelib/fs.stat" "2.0.4" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== + +"@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== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + dependencies: + "@nodelib/fs.scandir" "2.1.4" + fastq "^1.6.0" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0": + version "2.9.1" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.1.tgz#7f554e7368c9ab679a11f4a042ca17149d70cf12" + integrity sha512-DvJbbn3dUgMxDnJLH+RZQPnXak1h4ZVYQ7CWiFWjQwBFkVajT4rfw2PdpHLTSTwxrYfnoEXkuBiwkDm6tPMQeA== + +"@reach/router@^1.3.4": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c" + integrity sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA== + dependencies: + create-react-context "0.3.0" + invariant "^2.2.3" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + +"@storybook/addon-controls@^6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.2.7.tgz#bfa829106ca4d4247108fe864d7dd96afbec0c97" + integrity sha512-0FFcFtIffQWwV5aTTq7TDn2dq9M0+oU4q48ac+tOc2Ql8RfM4sYhCc8D30PhSCtc0/xH1xw/aHzotCkDqqAcrg== + dependencies: + "@storybook/addons" "6.2.7" + "@storybook/api" "6.2.7" + "@storybook/client-api" "6.2.7" + "@storybook/components" "6.2.7" + "@storybook/node-logger" "6.2.7" + "@storybook/theming" "6.2.7" + core-js "^3.8.2" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@^6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.2.7.tgz#1bcc9b0ac6e1fdb96a8614c93ae2bf11fccb189e" + integrity sha512-IJUldTCrV3zXU9WVRBWDrhB2Gqh1zqXefhCIBt3JznglBZ8ns5XcI6BLPNSLGyzHnP8vv0n4GaWbK2oUq4FbnA== + dependencies: + "@babel/core" "^7.12.10" + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@jest/transform" "^26.6.2" + "@mdx-js/loader" "^1.6.22" + "@mdx-js/mdx" "^1.6.22" + "@mdx-js/react" "^1.6.22" + "@storybook/addons" "6.2.7" + "@storybook/api" "6.2.7" + "@storybook/builder-webpack4" "6.2.7" + "@storybook/client-api" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/components" "6.2.7" + "@storybook/core" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/csf" "0.0.1" + "@storybook/node-logger" "6.2.7" + "@storybook/postinstall" "6.2.7" + "@storybook/source-loader" "6.2.7" + "@storybook/theming" "6.2.7" + acorn "^7.4.1" + acorn-jsx "^5.3.1" + acorn-walk "^7.2.0" + core-js "^3.8.2" + doctrine "^3.0.0" + escodegen "^2.0.0" + fast-deep-equal "^3.1.3" + global "^4.4.0" + html-tags "^3.1.0" + js-string-escape "^1.0.1" + loader-utils "^2.0.0" + lodash "^4.17.20" + prettier "~2.2.1" + prop-types "^15.7.2" + react-element-to-jsx-string "^14.3.2" + regenerator-runtime "^0.13.7" + remark-external-links "^8.0.0" + remark-slug "^6.0.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/addons@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.2.7.tgz#f31343654e564dd91f1ec103f130fa23e996745b" + integrity sha512-OHVGzkS2al/jirChr2otampV3oBvODbisUpHMhgUJQ+fcjKdBOXualJFBHhAI2TNwTODfjld+TsKQlBtiMDNDw== + dependencies: + "@storybook/api" "6.2.7" + "@storybook/channels" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/router" "6.2.7" + "@storybook/theming" "6.2.7" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + +"@storybook/api@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.2.7.tgz#5417dfe0c5a7a49a4e47f5a4c2be7a1bbdb7d5b3" + integrity sha512-GKD9b6OkQi7eDlaPmpjSz7MJsPIY+q7eGvBAWkovLXzvfEY6sE6VqUt9aWn3i6IkzqjYF7c+wgQzpA0JBTzH1Q== + dependencies: + "@reach/router" "^1.3.4" + "@storybook/channels" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/csf" "0.0.1" + "@storybook/router" "6.2.7" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.2.7" + "@types/reach__router" "^1.3.7" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + telejson "^5.1.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/builder-webpack4@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.2.7.tgz#5d10454788d412340e63403e9b7a2defafe377f4" + integrity sha512-cNw/QCauKuye1wmzySHUSaBmtvxK0v627RzX8YDv3M+1vkjZTRPkhhLE6uCZerNETck7doxTKk7x+X0z8nWSeQ== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" + "@storybook/addons" "6.2.7" + "@storybook/api" "6.2.7" + "@storybook/channel-postmessage" "6.2.7" + "@storybook/channels" "6.2.7" + "@storybook/client-api" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/components" "6.2.7" + "@storybook/core-common" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/node-logger" "6.2.7" + "@storybook/router" "6.2.7" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.2.7" + "@storybook/ui" "6.2.7" + "@types/node" "^14.0.10" + "@types/webpack" "^4.41.26" + autoprefixer "^9.8.6" + babel-loader "^8.2.2" + babel-plugin-macros "^2.8.0" + babel-plugin-polyfill-corejs3 "^0.1.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^3.6.0" + dotenv-webpack "^1.8.0" + file-loader "^6.2.0" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^4.1.6" + fs-extra "^9.0.1" + glob "^7.1.6" + glob-promise "^3.4.0" + global "^4.4.0" + html-webpack-plugin "^4.0.0" + pnp-webpack-plugin "1.6.4" + postcss "^7.0.35" + postcss-flexbugs-fixes "^4.2.1" + postcss-loader "^4.2.0" + raw-loader "^4.0.2" + react-dev-utils "^11.0.3" + stable "^0.1.8" + style-loader "^1.3.0" + terser-webpack-plugin "^3.1.0" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-filter-warnings-plugin "^1.2.1" + webpack-hot-middleware "^2.25.0" + webpack-virtual-modules "^0.2.2" + +"@storybook/channel-postmessage@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.2.7.tgz#4025d3746fac9b1c2264001606c7a361d1144417" + integrity sha512-l+62q/oZrDeuU3xhqVKnyk7FoUZKwr+4ZG6fXc/uXKCryoACiHT1RvStoX4AZqua9xIxMPpQr36UpHUElNHtyg== + dependencies: + "@storybook/channels" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/core-events" "6.2.7" + core-js "^3.8.2" + global "^4.4.0" + qs "^6.10.0" + telejson "^5.1.0" + +"@storybook/channels@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.2.7.tgz#b6b64e9f7318afe3a005042395356fd0a878001c" + integrity sha512-s79ghVFrbhj4hEt/HPNz7VgOqKQx8S8JozndHQuiE/KSNxfcgGihUXWxIVr7RGAzQcMT3HsAZ0nDbKdusV9jAg== + dependencies: + core-js "^3.8.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/client-api@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.2.7.tgz#7e788314582b9fc09fbd150ef95d0714d5d22b9c" + integrity sha512-ZeKNkI1lXW55RnREDYt/wmHi34iMYdRNpybE9QqPBEcFLyvpB7m1bifXxFSgqyMbK+eSTYOfPB1NGQJi77P/iQ== + dependencies: + "@storybook/addons" "6.2.7" + "@storybook/channel-postmessage" "6.2.7" + "@storybook/channels" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/csf" "0.0.1" + "@types/qs" "^6.9.5" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + stable "^0.1.8" + store2 "^2.12.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/client-logger@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.2.7.tgz#deca6d5b157d6ea22ec8f271399e9d10bb293a2c" + integrity sha512-IhTaZ3NPrV2g7vnoSuq5yb6QLuXQgD5+iuwzOAXlP8vU5X/Tm3zNr5PtqNjrKg1A3ls6A0pCBa5QctWdN/tnuQ== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + +"@storybook/components@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.2.7.tgz#03ee5e22c48631fe17829299d2da61bb4e0598ce" + integrity sha512-ccKOwGIkuhEHFLzjZvaZG11GIbMvk56bNdCAG8iINKYUjJE3l0PsO5xPhNsyTlwpDScZGwEBKB48Vn54UjiS8g== + dependencies: + "@popperjs/core" "^2.6.0" + "@storybook/client-logger" "6.2.7" + "@storybook/csf" "0.0.1" + "@storybook/theming" "6.2.7" + "@types/color-convert" "^2.0.0" + "@types/overlayscrollbars" "^1.12.0" + "@types/react-syntax-highlighter" "11.0.5" + color-convert "^2.0.1" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" + markdown-to-jsx "^7.1.0" + memoizerific "^1.11.3" + overlayscrollbars "^1.13.1" + polished "^4.0.5" + prop-types "^15.7.2" + react-colorful "^5.0.1" + react-popper-tooltip "^3.1.1" + react-syntax-highlighter "^13.5.3" + react-textarea-autosize "^8.3.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/core-client@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.2.7.tgz#3ee8c85035cf0006ef2151f25f215779f20580a4" + integrity sha512-te3gyGehNanWZDOoevH93Wl+iLTUBLK2jjw/B7Wf8sNegUauDQYXPR9YmI0wUQrn1Dz8Xz8bdMnD/GwzyXpGVQ== + dependencies: + "@storybook/addons" "6.2.7" + "@storybook/channel-postmessage" "6.2.7" + "@storybook/client-api" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/csf" "0.0.1" + "@storybook/ui" "6.2.7" + ansi-to-html "^0.6.11" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" + +"@storybook/core-common@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.2.7.tgz#596bfc3e87f5d8299f0e3bd7390de1c54d05a5e6" + integrity sha512-44pbzV0dyRsypWaS7Nstv4TXiLXaTX2Wif0otwtOudmSz3eYbWt3JQMBrQnkkEegJo7XPRFI9HzT1SvdbwTR+w== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" + "@babel/register" "^7.12.1" + "@storybook/node-logger" "6.2.7" + "@storybook/semver" "^7.3.2" + "@types/glob-base" "^0.3.0" + "@types/micromatch" "^4.0.1" + "@types/node" "^14.0.10" + "@types/pretty-hrtime" "^1.0.0" + babel-loader "^8.2.2" + babel-plugin-macros "^3.0.1" + babel-plugin-polyfill-corejs3 "^0.1.0" + chalk "^4.1.0" + core-js "^3.8.2" + express "^4.17.1" + file-system-cache "^1.0.5" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.0.4" + glob "^7.1.6" + glob-base "^0.3.0" + interpret "^2.2.0" + json5 "^2.1.3" + lazy-universal-dotenv "^3.0.1" + micromatch "^4.0.2" + pkg-dir "^5.0.0" + pretty-hrtime "^1.0.3" + resolve-from "^5.0.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "4" + +"@storybook/core-events@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.2.7.tgz#47f9bbbf7f5959eab9ffcf6e2893f09014297608" + integrity sha512-CwMftGVwWDqFva48rs5TlTSkimO7Q42dAuKKmUVHaN2tPacs8NdxhjqHmj+ls+5cxZuDnJy1x3JAo1PyHGyWiw== + dependencies: + core-js "^3.8.2" + +"@storybook/core-server@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.2.7.tgz#15408617d5bd98187938d5ac79a9456cfea2bc3d" + integrity sha512-WAHZo9xiTxbMvQtyLYBz88hXRqGsYWM6xFUAK+orSOQrmM/8P6zvTqc8p1Pf2Kfly7TnQuNcARvrQR0HGAeO0g== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.2.7" + "@storybook/builder-webpack4" "6.2.7" + "@storybook/core-client" "6.2.7" + "@storybook/core-common" "6.2.7" + "@storybook/node-logger" "6.2.7" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.2.7" + "@storybook/ui" "6.2.7" + "@types/node" "^14.0.10" + "@types/node-fetch" "^2.5.7" + "@types/pretty-hrtime" "^1.0.0" + "@types/webpack" "^4.41.26" + airbnb-js-shims "^2.2.1" + babel-loader "^8.2.2" + better-opn "^2.1.1" + boxen "^4.2.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + cli-table3 "0.6.0" + commander "^6.2.1" + core-js "^3.8.2" + cpy "^8.1.1" + css-loader "^3.6.0" + detect-port "^1.3.0" + dotenv-webpack "^1.8.0" + express "^4.17.1" + file-loader "^6.2.0" + file-system-cache "^1.0.5" + find-up "^5.0.0" + fs-extra "^9.0.1" + global "^4.4.0" + html-webpack-plugin "^4.0.0" + ip "^1.1.5" + node-fetch "^2.6.1" + pnp-webpack-plugin "1.6.4" + pretty-hrtime "^1.0.3" + prompts "^2.4.0" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + serve-favicon "^2.5.0" + style-loader "^1.3.0" + telejson "^5.1.0" + terser-webpack-plugin "^3.1.0" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-virtual-modules "^0.2.2" + +"@storybook/core@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.2.7.tgz#7eb7727523134303ab2733a196bb71b53dea4e9f" + integrity sha512-E40ezV3/bNn3y2I76n0LTmw4FLd5RrRbx4YPe5/2rOWozwErd7qHbDFRaAq6fW5dYQOC07iQNK5nneckD7id3w== + dependencies: + "@storybook/core-client" "6.2.7" + "@storybook/core-server" "6.2.7" + +"@storybook/csf@0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" + integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== + dependencies: + lodash "^4.17.15" + +"@storybook/node-logger@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.2.7.tgz#2329042e44eba1efcc6bb0689c8566a555d5b0ee" + integrity sha512-dzsFKn/3as6Nf21/9whh4HHfKOFfKlZaG5FxuhRlB3g3j61sAlE5LI4DXHgc0NoyfV5Ymbj3BPbtlCsNOy2i5A== + dependencies: + "@types/npmlog" "^4.1.2" + chalk "^4.1.0" + core-js "^3.8.2" + npmlog "^4.1.2" + pretty-hrtime "^1.0.3" + +"@storybook/postinstall@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.2.7.tgz#2d3a5d63fb9413452f05a9030d3f02febc48ef9a" + integrity sha512-Sj5FLHlbkeYYnkfs11EYyDzxMn59EeToZzNiwzXNDc2zDyyLNrV9ouVwW2Fb/hHwf9wypD1maHUShhXCKGc+cw== + dependencies: + core-js "^3.8.2" + +"@storybook/router@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.2.7.tgz#b6bfedc237f0b3834f8fa9eb724d91bd3eaff832" + integrity sha512-ZHz5T/IvpsXq0O/frdZN6kNltzy7QiL1TgekwY5evjtRWFAX6vRBQXfQH9opGQ3dThZIhMUi7kA9h9utrHp8HA== + dependencies: + "@reach/router" "^1.3.4" + "@storybook/client-logger" "6.2.7" + "@types/reach__router" "^1.3.7" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" + memoizerific "^1.11.3" + qs "^6.10.0" + ts-dedent "^2.0.0" + +"@storybook/semver@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" + integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== + dependencies: + core-js "^3.6.5" + find-up "^4.1.0" + +"@storybook/server@^6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/server/-/server-6.2.7.tgz#ecf284d6f0ca98a905155567fd0d6aa9deb23aa3" + integrity sha512-mx1UZcIFYtg+dsTyWKUofBb/uFzrQx2lGjE96813uu9ovh/IicW1FXKM0bAAqHl2ZLCXzNhCQP2kDlpHQrGq+Q== + dependencies: + "@storybook/addons" "6.2.7" + "@storybook/api" "6.2.7" + "@storybook/client-api" "6.2.7" + "@storybook/core" "6.2.7" + "@storybook/core-common" "6.2.7" + "@storybook/node-logger" "6.2.7" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + react "16.14.0" + react-dom "16.14.0" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + safe-identifier "^0.4.1" + ts-dedent "^2.0.0" + +"@storybook/source-loader@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.2.7.tgz#0e66eea339c3829030ec63e7729dc68f1d531885" + integrity sha512-fngRG28agjVleUBLhXhF4VzCmHzlq3XmSRB/IbT+kxgdWr9+QP9+i75HRQx5YIy4znnNkWojpv+0LVkVqQBHZw== + dependencies: + "@storybook/addons" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/csf" "0.0.1" + core-js "^3.8.2" + estraverse "^5.2.0" + global "^4.4.0" + loader-utils "^2.0.0" + lodash "^4.17.20" + prettier "~2.2.1" + regenerator-runtime "^0.13.7" + +"@storybook/theming@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.2.7.tgz#7dbbcde537099b1fe65ec63a517fd54a3dd587f5" + integrity sha512-0zTw1DhPWuNsk/fSg7rqLa/99+dxUfwjDnCYu4WJAUjfBWP/++0VWtQJVtt8ogyHKsY2dUzm5mhUg8EtqnGePg== + dependencies: + "@emotion/core" "^10.1.1" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.27" + "@storybook/client-logger" "6.2.7" + core-js "^3.8.2" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.27" + global "^4.4.0" + memoizerific "^1.11.3" + polished "^4.0.5" + resolve-from "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/ui@6.2.7": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.2.7.tgz#ff526d02d5785dd9cfbcb9bd6688b7293abe271f" + integrity sha512-Ys60G+g4leag/cNPTTC9wp9JRYY2LgXREs4HE4tybo4Ga/ZhQZrWzgKXuEeqM3GJZgLcsKz+qtPVQJibDBbOMg== + dependencies: + "@emotion/core" "^10.1.1" + "@storybook/addons" "6.2.7" + "@storybook/api" "6.2.7" + "@storybook/channels" "6.2.7" + "@storybook/client-logger" "6.2.7" + "@storybook/components" "6.2.7" + "@storybook/core-events" "6.2.7" + "@storybook/router" "6.2.7" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.2.7" + "@types/markdown-to-jsx" "^6.11.3" + copy-to-clipboard "^3.3.1" + core-js "^3.8.2" + core-js-pure "^3.8.2" + downshift "^6.0.15" + emotion-theming "^10.0.27" + fuse.js "^3.6.1" + global "^4.4.0" + lodash "^4.17.20" + markdown-to-jsx "^6.11.4" + memoizerific "^1.11.3" + polished "^4.0.5" + qs "^6.10.0" + react-draggable "^4.4.3" + react-helmet-async "^1.0.7" + react-sizeme "^3.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + store2 "^2.12.0" + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/braces@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" + integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw== + +"@types/color-convert@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.0.tgz#8f5ee6b9e863dcbee5703f5a517ffb13d3ea4e22" + integrity sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ== dependencies: - arr-flatten "^1.0.1" + "@types/color-name" "*" + +"@types/color-name@*": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/component-emitter@^1.2.10": + version "1.2.10" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea" + integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg== + +"@types/cookie@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108" + integrity sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg== + +"@types/cors@^2.8.8": + version "2.8.10" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.10.tgz#61cc8469849e5bcdd0c7044122265c39cec10cf4" + integrity sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ== + +"@types/glob-base@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/glob-base/-/glob-base-0.3.0.tgz#a581d688347e10e50dd7c17d6f2880a10354319d" + integrity sha1-pYHWiDR+EOUN18F9byiAoQNUMZ0= + +"@types/glob@*", "@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/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/hast@^2.0.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9" + integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q== + dependencies: + "@types/unist" "*" + +"@types/html-minifier-terser@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" + integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== + +"@types/is-function@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.0.tgz#1b0b819b1636c7baf0d6785d030d12edf70c3e83" + integrity sha512-iTs9HReBu7evG77Q4EC8hZnqRt57irBDkK9nvmHroiOIVwYMQc4IvYvdRgwKfYepunIY7Oh/dBuuld+Gj9uo6w== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + +"@types/markdown-to-jsx@^6.11.3": + version "6.11.3" + resolved "https://registry.yarnpkg.com/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz#cdd1619308fecbc8be7e6a26f3751260249b020e" + integrity sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw== + dependencies: + "@types/react" "*" + +"@types/mdast@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" + integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw== + dependencies: + "@types/unist" "*" + +"@types/micromatch@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" + integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw== + dependencies: + "@types/braces" "*" + +"@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-fetch@^2.5.7": + version "2.5.8" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.8.tgz#e199c835d234c7eb0846f6618012e558544ee2fb" + integrity sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*", "@types/node@^14.0.10": + version "14.14.37" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" + integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== + +"@types/node@>=10.0.0": + version "14.14.35" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313" + integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/npmlog@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.2.tgz#d070fe6a6b78755d1092a3dc492d34c3d8f871c4" + integrity sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA== + +"@types/overlayscrollbars@^1.12.0": + version "1.12.0" + resolved "https://registry.yarnpkg.com/@types/overlayscrollbars/-/overlayscrollbars-1.12.0.tgz#98456caceca8ad73bd5bb572632a585074e70764" + integrity sha512-h/pScHNKi4mb+TrJGDon8Yb06ujFG0mSg12wIO0sWMUF3dQIe2ExRRdNRviaNt9IjxIiOfnRr7FsQAdHwK4sMg== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/parse5@^5.0.0": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/pretty-hrtime@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.0.tgz#c5a2d644a135e988b2932f99737e67b3c62528d0" + integrity sha512-xl+5r2rcrxdLViAYkkiLMYsoUs3qEyrAnHFyEzYysgRxdVp3WbhysxIvJIxZp9FvZ2CYezh0TaHZorivH+voOQ== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/qs@^6.9.5": + version "6.9.6" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1" + integrity sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA== + +"@types/reach__router@^1.3.7": + version "1.3.7" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.7.tgz#de8ab374259ae7f7499fc1373b9697a5f3cd6428" + integrity sha512-cyBEb8Ef3SJNH5NYEIDGPoMMmYUxROatuxbICusVRQIqZUB85UCt6R2Ok60tKS/TABJsJYaHyNTW3kqbpxlMjg== + dependencies: + "@types/react" "*" + +"@types/react-syntax-highlighter@11.0.5": + version "11.0.5" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz#0d546261b4021e1f9d85b50401c0a42acb106087" + integrity sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "17.0.3" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79" + integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@^1", "@types/tapable@^1.0.5": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.7.tgz#545158342f949e8fd3bfd813224971ecddc3fac4" + integrity sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ== + +"@types/uglify-js@*": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124" + integrity sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q== + dependencies: + source-map "^0.6.1" + +"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + +"@types/webpack-env@^1.16.0": + version "1.16.0" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4" + integrity sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw== + +"@types/webpack-sources@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10" + integrity sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.41.26", "@types/webpack@^4.41.8": + version "4.41.27" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.27.tgz#f47da488c8037e7f1b2dbf2714fbbacb61ec0ffc" + integrity sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@types/yargs-parser@*": + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + +"@types/yargs@^15.0.0": + version "15.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" + integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + dependencies: + "@types/yargs-parser" "*" + +"@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== + +accepts@~1.3.4, 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-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn-walk@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +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== + +acorn@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +airbnb-js-shims@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" + integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + array.prototype.flatmap "^1.2.1" + es5-shim "^4.5.13" + es6-shim "^0.35.5" + function.prototype.name "^1.1.0" + globalthis "^1.0.0" + object.entries "^1.1.0" + object.fromentries "^2.0.0 || ^1.0.0" + object.getownpropertydescriptors "^2.0.3" + object.values "^1.1.0" + promise.allsettled "^1.0.0" + promise.prototype.finally "^3.1.0" + string.prototype.matchall "^4.0.0 || ^3.0.1" + string.prototype.padend "^3.0.0" + string.prototype.padstart "^3.0.0" + symbol.prototype.description "^1.0.0" + +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.2, ajv@^6.12.4, ajv@^6.12.5: + 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" + +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-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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +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@^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.0.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" + +ansi-to-html@^0.6.11: + version "0.6.14" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.14.tgz#65fe6d08bba5dd9db33f44a20aec331e0010dad8" + integrity sha512-7ZslfB1+EnFSDO5Ju+ue5Y6It19DRnZXWv8jrGHgIlPna5Mh4jz7BV5jCbQneXNFurQcKoolaaAjHtgSBfOIuA== + dependencies: + entities "^1.1.2" + +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.0.3, anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +app-root-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" + integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg= + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +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.0.1, arr-flatten@^1.1.0: +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== @@ -45,60 +2439,265 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= +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-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= +array-includes@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" + is-string "^1.0.5" + +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-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +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= -arraybuffer.slice@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" - integrity sha1-8zshWfBTKj8xB6JywMz70a0peco= +array.prototype.flat@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +array.prototype.flatmap@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + function-bind "^1.1.1" + +array.prototype.map@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.3.tgz#1609623618d3d84134a37d4a220030c2bd18420b" + integrity sha512-nNcb30v0wfDyIe26Yif3PcV1JXQp4zEeEfupG7L4SRjnD6HLbO5b2a7eVSba53bOx4YCHYMBHt+Fp4vYstneRA== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.5" + +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + +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" + +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.0: +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== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + 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== -backo2@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= +autoprefixer@^9.8.6: + 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" + +babel-loader@^8.2.2: + 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-apply-mdx-type-prop@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" + integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + "@mdx-js/util" "1.6.22" + +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-emotion@^10.0.27: + version "10.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz#a1fe3503cff80abfd0bdda14abd2e8e57a79d17d" + integrity sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/serialize" "^0.11.16" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" + +babel-plugin-extract-import-names@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" + integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + +babel-plugin-macros@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.0.1.tgz#0d412d68f5b3d1b64358f24ab099bd148724e2a9" + integrity sha512-CKt4+Oy9k2wiN+hT1uZzOw7d8zb1anbQpf7KLwaaXRCi/4pzKdFKHf7v5mvoPmjkmxshh7eKZQuRop06r5WP4w== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +babel-plugin-polyfill-corejs2@^0.1.4: + version "0.1.10" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz#a2c5c245f56c0cac3dbddbf0726a46b24f0f81d1" + integrity sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA== + dependencies: + "@babel/compat-data" "^7.13.0" + "@babel/helper-define-polyfill-provider" "^0.1.5" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.1.0, babel-plugin-polyfill-corejs3@^0.1.3: + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" + integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.1.5" + core-js-compat "^3.8.1" + +babel-plugin-polyfill-regenerator@^0.1.2: + version "0.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz#0fe06a026fe0faa628ccc8ba3302da0a6ce02f3f" + integrity sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.1.5" + +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-arraybuffer@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" - integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= -base64id@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" - integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= +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== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== base@^0.11.1: version "0.11.2" @@ -113,23 +2712,33 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -batch@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" - integrity sha1-PzQU84AyF0O/wQQvmoP/HVgk1GQ= +batch-processor@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8" + integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg= -better-assert@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" - integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= +better-opn@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== dependencies: - callsite "1.0.0" + open "^7.0.3" + +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" @@ -137,17 +2746,22 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -blob@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" - integrity sha1-vPEwUspURj8w+fx+lbmkdjCpSSE= +bluebird@^3.3.5, 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== -bluebird@^2.9.27: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= +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== -body-parser@^1.12.4: +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, 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== @@ -163,6 +2777,25 @@ body-parser@^1.12.4: raw-body "2.4.0" type-is "~1.6.17" +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" @@ -171,23 +2804,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^0.1.2: - version "0.1.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" - integrity sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY= - dependencies: - expand-range "^0.1.0" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^2.3.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== @@ -203,29 +2820,180 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== +braces@^3.0.1, braces@^3.0.2, 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: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" + fill-range "^7.0.1" -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= +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.14.2: + version "4.14.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" + integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== + dependencies: + caniuse-lite "^1.0.30001125" + electron-to-chromium "^1.3.564" + escalade "^3.0.2" + node-releases "^1.1.61" + +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.3: + version "4.16.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" + integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== + dependencies: + caniuse-lite "^1.0.30001181" + colorette "^1.2.1" + electron-to-chromium "^1.3.649" + escalade "^3.1.1" + node-releases "^1.1.70" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +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-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.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +cacache@^12.0.2: + 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" + +cacache@^15.0.5: + version "15.0.6" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" + integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -241,26 +3009,167 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -callsite@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= - -chokidar@^1.4.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= +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: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" + 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= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +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== + +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: + version "1.0.30001204" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz#256c85709a348ec4d175e847a3b515c66e79f2aa" + integrity sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +ccount@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" + integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== + +chalk@2.4.2, chalk@^2.0.0, 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" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + +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 "^2.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.0.0" + fsevents "^1.2.7" + +chokidar@^3.4.1, chokidar@^3.4.2: + 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== + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +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== + +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" @@ -272,11 +3181,71 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +clean-css@^4.2.3: + 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" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +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== + +cli-table3@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== + dependencies: + object-assign "^4.1.0" + string-width "^4.2.0" + optionalDependencies: + colors "^1.1.2" + +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@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + coffee-script@~1: version "1.12.7" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw== +collapse-white-space@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -285,42 +3254,98 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -colors@^1.1.0: +color-convert@^1.9.0: + 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.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== + +colorette@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +colors@^1.1.2, colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -component-bind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" - integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= +combined-stream@^1.0.8: + 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" -component-emitter@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" - integrity sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM= +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -component-emitter@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= +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== -component-emitter@^1.2.1: +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +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, component-emitter@~1.3.0: 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== -component-inherit@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" - integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +compute-scroll-into-view@^1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz#6a88f18acd9d42e9cf4baa6bec7e0522607ab7ab" + integrity sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg== 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= -connect@^3.3.5: +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" + +connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== @@ -330,62 +3355,355 @@ connect@^3.3.5: parseurl "~1.3.3" utils-merge "1.0.1" +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== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +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== -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +convert-source-map@^1.4.0, convert-source-map@^1.5.0, 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== + +cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +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= -core-js@^2.1.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== +copy-to-clipboard@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== + dependencies: + toggle-selection "^1.0.6" + +core-js-compat@^3.8.1, core-js-compat@^3.9.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.1.tgz#4e572acfe90aff69d76d8c37759d21a5c59bb455" + integrity sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA== + dependencies: + browserslist "^4.16.3" + semver "7.0.0" + +core-js-pure@^3.8.2: + version "3.10.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.10.0.tgz#dab9d6b141779b622b40567e7a536d2276646c15" + integrity sha512-CC582enhrFZStO4F8lGI7QL3SYx7/AIRc+IdSi3btrQGrVsTawo5K/crmKbRrQ+MOMhNX4v+PATn0k2NN6wI7A== + +core-js@^3.0.4, core-js@^3.6.5: + version "3.9.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae" + integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg== + +core-js@^3.8.2: + version "3.10.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3" + integrity sha512-MQx/7TLgmmDVamSyfE+O+5BHvG1aUGj/gHhLn1wVtm2B5u1eVIPvh7vkfjwWKNCjrTJB8+He99IntSQ1qP+vYQ== 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= +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cp-file@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" + integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== + dependencies: + graceful-fs "^4.1.2" + make-dir "^3.0.0" + nested-error-stacks "^2.0.0" + p-event "^4.1.0" + +cpy@^8.1.1: + version "8.1.2" + resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" + integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== + dependencies: + arrify "^2.0.1" + cp-file "^7.0.0" + globby "^9.2.0" + has-glob "^1.0.0" + junk "^3.1.0" + nested-error-stacks "^2.1.0" + p-all "^2.1.0" + p-filter "^2.1.0" + p-map "^3.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" + +create-react-context@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + +cross-spawn@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cross-spawn@^6.0.0: + 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" + +css-loader@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.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-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== + +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== + +csstype@^2.5.7: + version "2.6.16" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.16.tgz#544d69f547013b85a40d15bff75db38f34fe9c39" + integrity sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q== + +csstype@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" + integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== + custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= - dependencies: - ms "0.7.1" +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -debug@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" - integrity sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w= - dependencies: - ms "0.7.2" +date-format@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" + integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +date-format@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" + integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: 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.0.0: + 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, debug@~4.3.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" + 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= +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deep-object-diff@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a" + integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +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" @@ -408,17 +3726,105 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +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== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + 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= + +detab@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" + integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== + dependencies: + repeat-string "^1.5.4" + +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= -dom-serialize@^2.2.0: +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.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" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +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-serialize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= @@ -428,88 +3834,407 @@ dom-serialize@^2.2.0: extend "^3.0.0" void-elements "^2.0.0" +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.1.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" + integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== + +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-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dotenv-defaults@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-1.1.1.tgz#032c024f4b5906d9990eb06d722dc74cc60ec1bd" + integrity sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q== + dependencies: + dotenv "^6.2.0" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv-webpack@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-1.8.0.tgz#7ca79cef2497dd4079d43e81e0796bc9d0f68a5e" + integrity sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg== + dependencies: + dotenv-defaults "^1.0.2" + +dotenv@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" + integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== + +dotenv@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +downshift@^6.0.15: + version "6.1.2" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-6.1.2.tgz#99d9a03d4da4bf369df766effc3b70f7e789950e" + integrity sha512-WnPoQ6miic4+uEzPEfqgeen0t5YREOUabMopU/Juo/UYDMZl0ZACkO6ykWCRg48dlEUmEt6zfaJlj1x7kEy78g== + dependencies: + "@babel/runtime" "^7.13.10" + compute-scroll-into-view "^1.0.17" + prop-types "^15.7.2" + react-is "^17.0.2" + +duplexer@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +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" + 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.564, electron-to-chromium@^1.3.649: + version "1.3.702" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.702.tgz#39b8b6860b22806482ad07a8eaf35f861d4f3ce0" + integrity sha512-qJVUKFWQnF6wP7MmTngDkmm8/KPzaiTXNFOAg5j7DSa6J7kPou7mTBqC8jpUOxauQWwHR3pn4dMRdV8IE1xdtA== + +element-resize-detector@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.2.tgz#bf7c3ff915957e4e62e86241ed2f9c86b078892b" + integrity sha512-+LOXRkCJc4I5WhEJxIDjhmE3raF8jtOMBDqSCgZTMz2TX3oXAX5pE2+MDeopJlGdXzP7KzPbBJaUGfNaP9HG4A== + dependencies: + batch-processor "1.0.0" + +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@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= + +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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +emotion-theming@^10.0.27: + version "10.0.27" + resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.27.tgz#1887baaec15199862c89b1b984b79806f2b9ab10" + integrity sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/weak-memoize" "0.2.5" + hoist-non-react-statics "^3.3.0" + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -engine.io-client@~1.8.4: - version "1.8.5" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.5.tgz#fe7fb60cb0dcf2fa2859489329cb5968dedeb11f" - integrity sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg== +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: - component-emitter "1.2.1" - component-inherit "0.0.3" - debug "2.3.3" - engine.io-parser "1.3.2" - has-cors "1.1.0" - indexof "0.0.1" - parsejson "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" - ws "~1.1.5" - xmlhttprequest-ssl "1.5.3" - yeast "0.1.2" + once "^1.4.0" -engine.io-parser@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a" - integrity sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo= +engine.io-parser@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.2.tgz#e41d0b3fb66f7bf4a3671d2038a154024edb501e" + integrity sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg== dependencies: - after "0.8.2" - arraybuffer.slice "0.0.6" - base64-arraybuffer "0.1.5" - blob "0.0.4" - has-binary "0.1.7" - wtf-8 "1.0.0" + base64-arraybuffer "0.1.4" -engine.io@~1.8.4: - version "1.8.5" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.5.tgz#4ebe5e75c6dc123dee4afdce6e5fdced21eb93f6" - integrity sha512-j1DWIcktw4hRwrv6nWx++5nFH2X64x16MAG2P0Lmi5Dvdfi3I+Jhc7JKJIdAmDJa+5aZ/imHV7dWRPy2Cqjh3A== +engine.io@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" + integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== dependencies: - accepts "1.3.3" - base64id "1.0.0" - cookie "0.3.1" - debug "2.3.3" - engine.io-parser "1.3.2" - ws "~1.1.5" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~4.0.0" + ws "~7.4.2" + +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" ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= +entities@^1.1.1, entities@^1.1.2: + 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== + +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.0-next.0, es-abstract@^1.18.0-next.1, 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-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + +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" + +es5-shim@^4.5.13: + version "4.5.15" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.15.tgz#6a26869b261854a3b045273f5583c52d390217fe" + integrity sha512-FYpuxEjMeDvU4rulKqFdukQyZSTpzhg4ScQHrAosrlVpR6GFyaw14f74yn2+4BugniIS0Frpg7TvwZocU4ZMTw== + +es6-shim@^0.35.5: + version "0.35.6" + resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.6.tgz#d10578301a83af2de58b9eadb7c2c9945f7388a0" + integrity sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA== + +escalade@^3.0.2, 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-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@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== + +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= + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +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, esprima@^4.0.1: + 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== -expand-braces@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" - integrity sha1-SIsdHSRRyz06axks/AMPRMWFX+o= - dependencies: - array-slice "^0.2.3" - array-unique "^0.2.1" - braces "^0.1.2" +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== -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= +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: - is-posix-bracket "^0.1.0" + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== + +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" @@ -524,20 +4249,41 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" - integrity sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ= +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: - is-number "^0.1.1" - repeat-string "^0.2.2" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" + 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" @@ -559,13 +4305,6 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -580,26 +4319,97 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + 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-glob@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +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== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + dependencies: + reusify "^1.0.4" + +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.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== + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +file-system-cache@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" + integrity sha1-hCWbNqK7uNPW6xAh0xMv/mTP/08= + dependencies: + bluebird "^3.3.5" + fs-extra "^0.30.0" + ramda "^0.21.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== -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" +filesize@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" + integrity sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg== fill-range@^4.0.0: version "4.0.0" @@ -611,7 +4421,14 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -finalhandler@1.1.2: +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, finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== @@ -624,27 +4441,129 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-cache-dir@^2.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-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.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" + +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@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flatpickr@^4.6.9: version "4.6.9" resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.9.tgz#9a13383e8a6814bda5d232eae3fcdccb97dc1499" integrity sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw== +flatted@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +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.13.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== -for-in@^1.0.1, for-in@^1.0.2: +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= -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= +fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== dependencies: - for-in "^1.0.1" + "@babel/code-frame" "^7.5.5" + chalk "^2.4.1" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +fork-ts-checker-webpack-plugin@^6.0.4: + version "6.2.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.2.0.tgz#d13af02e24d1b17f769af6bdf41c1e849e1615cc" + integrity sha512-DTNbOhq6lRdjYprukX54JMeYJgQ0zMow+R5BMLwWxEX2NAXthIkwnV8DBmsWjwNLSUItKZM4TCCJbtgrtKBu2Q== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= + +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" @@ -653,12 +4572,77 @@ fragment-cache@^0.2.1: 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@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +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-extra@^9.0.0, fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-monkey@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.1.tgz#4a82f36944365e619f4454d9fff106553067b781" + integrity sha512-fcSa+wyTqZa46iWweI7/ZiUfegOZl0SG8+dltIwFXo7+zYU9J9kpS3NB6pZcSlJdhvIwp81Adx2XhZorncxiaA== + +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.0.0: +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== @@ -666,11 +4650,93 @@ fsevents@^1.0.0: bindings "^1.5.0" nan "^2.12.1" +fsevents@^2.1.2, 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== + +function.prototype.name@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.4.tgz#e4ea839b9d3672ae99d0efd9f38d9191c5eaac83" + integrity sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" + integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + +fuse.js@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c" + integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gensync@^1.0.0-beta.1, 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.5: + 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.0, 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-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^4.0.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-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= +github-slugger@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" + integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -686,7 +4752,34 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.0, glob@^7.1.3: +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, 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-promise@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== + dependencies: + "@types/glob" "*" + +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.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== @@ -698,22 +4791,124 @@ glob@^7.0.0, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -has-binary@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" - integrity sha1-aOYesWIQyVRaClzOBqhzkS/h5ow= +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== dependencies: - isarray "0.0.1" + global-prefix "^3.0.0" -has-cors@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" - integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@^4.4.0: + 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== + +globalthis@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" + integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== + dependencies: + define-properties "^1.1.3" + +globby@11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.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" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + +gzip-size@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +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-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" + integrity sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc= + dependencies: + is-glob "^3.0.0" + +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-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" @@ -746,6 +4941,184 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.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.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" + +hast-to-hyperscript@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" + integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== + dependencies: + "@types/unist" "^2.0.3" + comma-separated-tokens "^1.0.0" + property-information "^5.3.0" + space-separated-tokens "^1.0.0" + style-to-object "^0.3.0" + unist-util-is "^4.0.0" + web-namespaces "^1.0.0" + +hast-util-from-parse5@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" + integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== + dependencies: + "@types/parse5" "^5.0.0" + hastscript "^6.0.0" + property-information "^5.0.0" + vfile "^4.0.0" + vfile-location "^3.2.0" + web-namespaces "^1.0.0" + +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== + +hast-util-raw@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" + integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== + dependencies: + "@types/hast" "^2.0.0" + hast-util-from-parse5 "^6.0.0" + hast-util-to-parse5 "^6.0.0" + html-void-elements "^1.0.0" + parse5 "^6.0.0" + unist-util-position "^3.0.0" + vfile "^4.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hast-util-to-parse5@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" + integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== + dependencies: + hast-to-hyperscript "^9.0.0" + property-information "^5.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +highlight.js@^10.1.1, highlight.js@~10.7.0: + version "10.7.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.1.tgz#a8ec4152db24ea630c90927d6cae2a45f8ecb955" + integrity sha512-S6G97tHGqJ/U8DsXcEdnACbirtbx58Bx9CzIVeYli8OuswCfYI/LsXH2EiGcoGio1KAC3x4mmUwulOllJ2ZyRA== + +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" + +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-entities@^1.2.0: + 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-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +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== + +html-void-elements@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== + +html-webpack-plugin@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" + integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.20" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +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-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -757,7 +5130,18 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-proxy@^1.13.0: +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-proxy@^1.18.1: 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== @@ -766,6 +5150,11 @@ http-proxy@^1.13.0: follow-redirects "^1.0.0" requires-port "^1.0.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" @@ -773,10 +5162,65 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= +icss-utils@^4.0.0, icss-utils@^4.1.1: + 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@^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== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +immer@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" + integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== + +import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.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@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +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, infer-owner@^1.0.4: + 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" @@ -786,16 +5230,67 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, 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.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +invariant@^2.2.3, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.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: + 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@^3.0.0: + 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" @@ -810,6 +5305,36 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-alphabetical@1.0.4, is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arguments@^1.1.0: + 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-bigint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" + integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + 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" @@ -817,11 +5342,49 @@ is-binary-path@^1.0.0: 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-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +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-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + 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" @@ -836,6 +5399,16 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -854,17 +5427,10 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" +is-docker@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" + integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" @@ -883,24 +5449,73 @@ is-extglob@^1.0.0: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= -is-glob@^2.0.0, is-glob@^2.0.1: +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@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +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-function@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= dependencies: is-extglob "^1.0.0" -is-number@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" - integrity sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY= - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= +is-glob@^3.0.0, 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: - kind-of "^3.0.2" + 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-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + +is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +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-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" @@ -909,10 +5524,20 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== +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-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b" + integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" @@ -921,37 +5546,87 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= +is-regex@^1.1.1, 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-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= +is-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +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: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-whitespace-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== 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== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= +is-word-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== -isarray@1.0.0, isarray@~1.0.0: +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-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +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= -isbinaryfile@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" - integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== - dependencies: - buffer-alloc "^1.2.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isbinaryfile@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b" + integrity sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg== isexe@^2.0.0: version "2.0.0" @@ -970,15 +5645,183 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + +istanbul-lib-instrument@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +iterate-iterator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" + integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== + +iterate-value@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" + jasmine-core@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.4.1.tgz#6f83ab3a0f16951722ce07d206c773d57cc838be" integrity sha1-b4OrOg8WlRcizgfSBsdz1XzIOL4= -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + +jest-worker@^26.2.1, jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +"js-tokens@^3.0.0 || ^4.0.0", 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" + +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-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-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +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== + +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, json5@^2.1.3: + 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@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +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" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +junk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" + integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== karma-chrome-launcher@~3.1.0: version "3.1.0" @@ -1000,34 +5843,34 @@ karma-jasmine@~0.3.8: resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-0.3.8.tgz#5b6457791ad9b89aa173f079e3ebe1b8c805236c" integrity sha1-W2RXeRrZuJqhc/B54+vhuMgFI2w= -karma@~0.13.22: - version "0.13.22" - resolved "https://registry.yarnpkg.com/karma/-/karma-0.13.22.tgz#07750b1bd063d7e7e7b91bcd2e6354d8f2aa8744" - integrity sha1-B3ULG9Bj1+fnuRvNLmNU2PKqh0Q= +karma@~6.3.2: + version "6.3.2" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.2.tgz#24b62fbae3e8b5218cc32a0dac49ad08a541e76d" + integrity sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw== dependencies: - batch "^0.5.3" - bluebird "^2.9.27" - body-parser "^1.12.4" - chokidar "^1.4.1" - colors "^1.1.0" - connect "^3.3.5" - core-js "^2.1.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.4.2" + colors "^1.4.0" + connect "^3.7.0" di "^0.0.1" - dom-serialize "^2.2.0" - expand-braces "^0.1.1" - glob "^7.0.0" - graceful-fs "^4.1.2" - http-proxy "^1.13.0" - isbinaryfile "^3.0.0" - lodash "^3.8.0" - log4js "^0.6.31" - mime "^1.3.4" - minimatch "^3.0.0" - optimist "^0.6.1" - rimraf "^2.3.3" - socket.io "^1.4.5" - source-map "^0.5.3" - useragent "^2.1.6" + dom-serialize "^2.2.1" + glob "^7.1.6" + graceful-fs "^4.2.4" + http-proxy "^1.18.1" + isbinaryfile "^4.0.6" + lodash "^4.17.19" + log4js "^6.2.1" + mime "^2.4.5" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^3.1.0" + source-map "^0.6.1" + tmp "0.2.1" + ua-parser-js "^0.7.23" + yargs "^16.1.1" kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" @@ -1053,32 +5896,186 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lodash@^3.8.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" - integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + optionalDependencies: + graceful-fs "^4.1.9" -log4js@^0.6.31: - version "0.6.38" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" - integrity sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0= - dependencies: - readable-stream "~1.0.2" - semver "~4.3.3" +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lru-cache@4.1.x: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== +klona@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + +lazy-universal-dotenv@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" + integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" + "@babel/runtime" "^7.5.0" + app-root-dir "^1.0.2" + core-js "^3.0.4" + dotenv "^8.0.0" + dotenv-expand "^5.1.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +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@2.0.0, loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +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@^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" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +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.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.15, lodash@^4.17.19, lodash@^4.17.20: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log4js@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" + integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== + dependencies: + date-format "^3.0.0" + debug "^4.1.1" + flatted "^2.0.1" + rfdc "^1.1.4" + streamroller "^2.2.4" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lowlight@^1.14.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" + +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" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^2.0.0, make-dir@^2.1.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" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" 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-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha1-beJlMXSt+12e3DPGnT6Sobdvrwg= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -1086,36 +6083,132 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -math-random@^1.0.1: +markdown-escapes@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" - integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== + +markdown-to-jsx@^6.11.4: + version "6.11.4" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz#b4528b1ab668aef7fe61c1535c27e837819392c5" + integrity sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw== + dependencies: + prop-types "^15.6.2" + unquote "^1.1.0" + +markdown-to-jsx@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.2.tgz#19d3da4cd8864045cdd13a0d179147fbd6a088d4" + integrity sha512-O8DMCl32V34RrD+ZHxcAPc2+kYytuDIoQYjY36RVdsLK7uHjgNVvFec4yv0X6LgB4YEZgSvK5QtFi5YVqEpoMA== + +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" + +mdast-squeeze-paragraphs@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" + integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== + dependencies: + unist-util-remove "^2.0.0" + +mdast-util-definitions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" + integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== + dependencies: + unist-util-visit "^2.0.0" + +mdast-util-to-hast@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" + integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + mdast-util-definitions "^4.0.0" + mdurl "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + +mdurl@^1.0.0: + 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= -micromatch@^2.1.5: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= +memfs@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.2.0.tgz#f9438e622b5acd1daa8a4ae160c496fdd1325b26" + integrity sha512-f/xxz2TpdKv6uDn6GtHee8ivFyxwxmPuXatBb1FBwxYNuVpbM3k/Y1Z+vC0mH/dIXXrukYfe3qe5J32Dfjg93A== dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" + fs-monkey "1.0.1" -micromatch@^3.1.10: +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha1-fIekZGREwy11Q4VwkF8tvRsagFo= + dependencies: + map-or-similar "^1.5.0" + +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" + +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-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3, merge2@^1.3.0: + 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= + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + +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== @@ -1134,34 +6227,136 @@ micromatch@^3.1.10: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +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.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-types@~2.1.11, mime-types@~2.1.24: +mime-db@1.46.0: + version "1.46.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" + integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== + +mime-types@^2.1.12, mime-types@^2.1.27: + version "2.1.29" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" + integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== + dependencies: + mime-db "1.46.0" + +mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: mime-db "1.44.0" -mime@^1.3.4: +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== -minimatch@^3.0.0, minimatch@^3.0.4: +mime@^2.4.4, mime@^2.4.5: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + +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" + +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, 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@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +minimist@^1.1.1, 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== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +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" @@ -1171,30 +6366,59 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp@^0.5.1, mkdirp@^0.5.3: + 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.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + moment@^2.29.1: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= - -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - integrity sha1-riXPJRKziFodldfwN4aNhDESR2U= +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== + nan@^2.12.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + 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" @@ -1213,33 +6437,149 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= +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== -normalize-path@^2.0.0, normalize-path@^2.0.1: +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== + +nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" + integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== + +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@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +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-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-releases@^1.1.61, node-releases@^1.1.70: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + +normalize-package-data@^2.5.0: + 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" -object-assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" - integrity sha1-ejs9DpgGPUP0wD8uiubNUahog6A= +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== -object-assign@^4.1.0: +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= + +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" + +npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +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= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4, 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-component@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" - integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= - object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -1249,6 +6589,16 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + +object-keys@^1.0.12, 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" @@ -1256,13 +6606,44 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= +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: - for-own "^0.1.4" - is-extendable "^0.1.1" + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.entries@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" + integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + has "^1.0.3" + +"object.fromentries@^2.0.0 || ^1.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8" + integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + has "^1.0.3" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: + 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" @@ -1271,6 +6652,16 @@ object.pick@^1.3.0: 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" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -1278,110 +6669,648 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0: +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" -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= +open@^7.0.2, open@^7.0.3: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" + is-docker "^2.0.0" + is-wsl "^2.1.1" -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +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= -parse-glob@^3.0.4: +overlayscrollbars@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz#0b840a88737f43a946b9d87875a2f9e421d0338a" + integrity sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ== + +p-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" + integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== + dependencies: + p-map "^2.0.0" + +p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" + integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== + dependencies: + p-map "^2.0.0" + +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@^2.0.0, p-limit@^2.2.0: + 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-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.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-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +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-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + +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== + +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@^3.0.3: version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" + dot-case "^3.0.4" + tslib "^2.0.3" -parsejson@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" - integrity sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs= +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: - better-assert "~1.0.0" + callsites "^3.0.0" -parseqs@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" - integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= +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: - better-assert "~1.0.0" + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" -parseuri@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" - integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== dependencies: - better-assert "~1.0.0" + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" -parseurl@~1.3.3: +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +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== +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + 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-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-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +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" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + 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" + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +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== + +pirates@^4.0.0, pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +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" + +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + +pkg-up@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +polished@^4.0.5: + version "4.1.1" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.1.1.tgz#40442cc973348e466f2918cdf647531bb6c29bfb" + integrity sha512-4MZTrfPMPRLD7ac8b+2JZxei58zw6N1hFkdBDERif5Tlj19y3vPoPusrLG+mJIlPTGnUlKw3+yWz0BazvMx1vg== + dependencies: + "@babel/runtime" "^7.12.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= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== + dependencies: + postcss "^7.0.26" + +postcss-loader@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.2.0.tgz#f6993ea3e0f46600fb3ee49bbd010448123a7db4" + integrity sha512-mqgScxHqbiz1yxbnNcPdKYo/6aVt+XExURmEbQlviFVWogDbM4AJ0A/B+ZBpYsJrTRxKw7HyRazg9x0Q9SWwLA== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.4" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" + +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@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^2.2.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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" + integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + util-deprecate "^1.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.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, 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" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + +pretty-error@^2.1.1: + 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-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +prismjs@^1.21.0, prismjs@~1.23.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== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +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= + +promise.allsettled@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.4.tgz#65e71f2a604082ed69c548b68603294090ee6803" + integrity sha512-o73CbvQh/OnPFShxHcHxk0baXR2a1m4ozb85ha0H14VEoi/EJJLa9mnPfEWJx9RjA9MLfhdjZ8I6HhWtBa64Ag== + dependencies: + array.prototype.map "^1.0.3" + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.0.2" + iterate-value "^1.0.2" + +promise.prototype.finally@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" + integrity sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.0" + function-bind "^1.1.1" + +prompts@2.4.0, prompts@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7" + integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +property-information@^5.0.0, property-information@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== + dependencies: + xtend "^4.0.0" + +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= + +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: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== 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== -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== +qs@^6.10.0: + version "6.10.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" + side-channel "^1.0.4" + +querystring-es3@^0.2.0: + 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= + +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +ramda@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" + integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= + +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" @@ -1393,7 +7322,187 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.0.2: +raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +react-colorful@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.1.0.tgz#45c8044d80bc0e7ee08dc78c760e6694f3745ca2" + integrity sha512-ZXKcQbSuuHaN5tOHORI+G9/tXsGxk/6qlAbfETfZILwwWwngyJiyYRhUJjI+Esk71BhhQRdj0v7cFHDnD95jtQ== + +react-dev-utils@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" + integrity sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A== + dependencies: + "@babel/code-frame" "7.10.4" + address "1.1.2" + browserslist "4.14.2" + chalk "2.4.2" + cross-spawn "7.0.3" + detect-port-alt "1.1.6" + escape-string-regexp "2.0.0" + filesize "6.1.0" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "4.1.6" + global-modules "2.0.0" + globby "11.0.1" + gzip-size "5.1.1" + immer "8.0.1" + is-root "2.1.0" + loader-utils "2.0.0" + open "^7.0.2" + pkg-up "3.1.0" + prompts "2.4.0" + react-error-overlay "^6.0.9" + recursive-readdir "2.2.2" + shell-quote "1.7.2" + strip-ansi "6.0.0" + text-table "0.2.0" + +react-dom@16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" + integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-draggable@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3" + integrity sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w== + dependencies: + classnames "^2.2.5" + prop-types "^15.6.0" + +react-element-to-jsx-string@^14.3.2: + version "14.3.2" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.2.tgz#c0000ed54d1f8b4371731b669613f2d4e0f63d5c" + integrity sha512-WZbvG72cjLXAxV7VOuSzuHEaI3RHj10DZu8EcKQpkKcAj7+qAkG5XUeSdX5FXrA0vPrlx0QsnAzZEBJwzV0e+w== + dependencies: + "@base2/pretty-print-object" "1.0.0" + is-plain-object "3.0.1" + +react-error-overlay@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" + integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== + +react-fast-compare@^3.0.1, react-fast-compare@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" + integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + +react-helmet-async@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.9.tgz#5b9ed2059de6b4aab47f769532f9fbcbce16c5ca" + integrity sha512-N+iUlo9WR3/u9qGMmP4jiYfaD6pe9IvDTapZLFJz2D3xlTlCM1Bzy4Ab3g72Nbajo/0ZyW+W9hdz8Hbe4l97pQ== + dependencies: + "@babel/runtime" "^7.12.5" + invariant "^2.2.4" + prop-types "^15.7.2" + react-fast-compare "^3.2.0" + shallowequal "^1.1.0" + +react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-popper-tooltip@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz#329569eb7b287008f04fcbddb6370452ad3f9eac" + integrity sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ== + dependencies: + "@babel/runtime" "^7.12.5" + "@popperjs/core" "^2.5.4" + react-popper "^2.2.4" + +react-popper@^2.2.4: + version "2.2.5" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96" + integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw== + dependencies: + react-fast-compare "^3.0.1" + warning "^4.0.2" + +react-sizeme@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-3.0.1.tgz#4d12f4244e0e6a0fb97253e7af0314dc7c83a5a0" + integrity sha512-9Hf1NLgSbny1bha77l9HwvwwxQUJxFUqi44Ih+y3evA+PezBpGdCGlnvye6avss2cIgs9PgdYgMnfuzJWn/RUw== + dependencies: + element-resize-detector "^1.2.2" + invariant "^2.2.4" + shallowequal "^1.1.0" + throttle-debounce "^3.0.1" + +react-syntax-highlighter@^13.5.3: + version "13.5.3" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz#9712850f883a3e19eb858cf93fad7bb357eea9c6" + integrity sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.1.1" + lowlight "^1.14.0" + prismjs "^1.21.0" + refractor "^3.1.0" + +react-textarea-autosize@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz#4f9374d357b0a6f6469956726722549124a1b2db" + integrity sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q== + dependencies: + "@babel/runtime" "^7.10.2" + use-composed-ref "^1.0.0" + use-latest "^1.0.0" + +react@16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, 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== @@ -1406,17 +7515,16 @@ readable-stream@^2.0.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@~1.0.2: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= +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: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" -readdirp@^2.0.0: +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== @@ -1425,12 +7533,52 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== +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: - is-equal-shallow "^0.1.3" + picomatch "^2.2.1" + +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +refractor@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.3.1.tgz#ebbc04b427ea81dc25ad333f7f67a0b5f4f0be3a" + integrity sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw== + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.23.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, regenerator-runtime@^0.13.7: + 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" @@ -1440,53 +7588,246 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp.prototype.flags@^1.3.1: + 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" + +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.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^4.0.0" + space-separated-tokens "^1.0.0" + unist-util-visit "^2.0.0" + +remark-footnotes@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" + integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== + +remark-mdx@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" + integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== + dependencies: + "@babel/core" "7.12.9" + "@babel/helper-plugin-utils" "7.10.4" + "@babel/plugin-proposal-object-rest-spread" "7.12.1" + "@babel/plugin-syntax-jsx" "7.12.1" + "@mdx-js/util" "1.6.22" + is-alphabetical "1.0.4" + remark-parse "8.0.3" + unified "9.2.0" + +remark-parse@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" + integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== + dependencies: + ccount "^1.0.0" + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^2.0.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^2.0.0" + vfile-location "^3.0.0" + xtend "^4.0.1" + +remark-slug@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.0.0.tgz#2b54a14a7b50407a5e462ac2f376022cce263e2c" + integrity sha512-ln67v5BrGKHpETnm6z6adlJPhESFJwfuZZ3jrmi+lKTzeZxh2tzFzUfDD4Pm2hRGOarHLuGToO86MNMZ/hA67Q== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + +remark-squeeze-paragraphs@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" + integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== + dependencies: + mdast-squeeze-paragraphs "^4.0.0" + 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.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" - integrity sha1-x6jTI2BoNiBZp+RlH8aITosftK4= - -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.5.4, 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= +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= + 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-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +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.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.3.2: + 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" + 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== -rimraf@^2.3.3: +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.1.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^2.2.8, 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" -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + 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" + +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +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.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +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.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-identifier@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/safe-identifier/-/safe-identifier-0.4.2.tgz#cf6bfca31c2897c588092d1750d30ef501d59fcb" + integrity sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -1494,15 +7835,148 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", 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== -semver@~4.3.3: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +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, schema-utils@^2.6.6, schema-utils@^2.7.0: + 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" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, 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.1, semver@^6.1.2, 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== + +semver@^7.3.2, semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +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@^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-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha1-k10kDN/g9YBTB/3+ln2IlCosvPA= + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + +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" @@ -1514,16 +7988,92 @@ set-value@^2.0.0, set-value@^2.0.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.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" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +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-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.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= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + shortcut-buttons-flatpickr@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/shortcut-buttons-flatpickr/-/shortcut-buttons-flatpickr-0.3.1.tgz#25ec705db8e7c80f0f81f5e160783102775ef529" integrity sha512-zZRLJXF7WSeQJ0ZES+PdD1FI+yjBOufqOQ4AU5przR71Rhyekiw/6/JLA33zOqVkgR7QQ1NbVcuuSqNHHGneEg== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +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== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -1554,53 +8104,39 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -socket.io-adapter@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b" - integrity sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s= - dependencies: - debug "2.3.3" - socket.io-parser "2.3.1" +socket.io-adapter@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" + integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== -socket.io-client@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.4.tgz#ec9f820356ed99ef6d357f0756d648717bdd4281" - integrity sha1-7J+CA1btme9tNX8HVtZIcXvdQoE= +socket.io-parser@~4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== dependencies: - backo2 "1.0.2" - component-bind "1.0.0" - component-emitter "1.2.1" - debug "2.3.3" - engine.io-client "~1.8.4" - has-binary "0.1.7" - indexof "0.0.1" - object-component "0.0.3" - parseuri "0.0.5" - socket.io-parser "2.3.1" - to-array "0.1.4" + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" -socket.io-parser@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" - integrity sha1-3VMgJRA85Clpcya+/WQAX8/ltKA= +socket.io@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" + integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== dependencies: - component-emitter "1.1.2" - debug "2.2.0" - isarray "0.0.1" - json3 "3.3.2" + "@types/cookie" "^0.4.0" + "@types/cors" "^2.8.8" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.1" + engine.io "~4.1.0" + socket.io-adapter "~2.1.0" + socket.io-parser "~4.0.3" -socket.io@^1.4.5: - version "1.7.4" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.4.tgz#2f7ecedc3391bf2d5c73e291fe233e6e34d4dd00" - integrity sha1-L37O3DORvy1cc+KR/iM+bjTU3QA= - dependencies: - debug "2.3.3" - engine.io "~1.8.4" - has-binary "0.1.7" - object-assign "4.1.0" - socket.io-adapter "0.5.0" - socket.io-client "1.7.4" - socket.io-parser "2.3.1" +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: version "0.5.3" @@ -1613,16 +8149,65 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map-support@^0.5.16, 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@^0.5.3, source-map@^0.5.6: +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.0, source-map@^0.5.6, source-map@^0.5.7: 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== + +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + +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== + 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" @@ -1630,6 +8215,35 @@ split-string@^3.0.1, split-string@^3.0.2: 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= + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.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== + +state-toggle@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -1643,10 +8257,140 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= +store2@^2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf" + integrity sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw== + +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== + +streamroller@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" + integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== + dependencies: + date-format "^2.1.0" + debug "^4.1.1" + fs-extra "^8.1.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.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, string-width@^4.2.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.matchall@^4.0.0 || ^3.0.1": + version "4.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz#608f255e93e072107f5de066f81a2dfb78cf6b29" + integrity sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + has-symbols "^1.0.1" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.3.1" + side-channel "^1.0.4" + +string.prototype.padend@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz#6858ca4f35c5268ebd5e8615e1327d55f59ee311" + integrity sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +string.prototype.padstart@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.2.tgz#f9b9ce66bedd7c06acb40ece6e34c6046e1a019d" + integrity sha512-HDpngIP3pd0DeazrfqzuBrQZa+D2arKWquEHfGt5LzVjd+roLC3cjqVI0X8foaZz5rrrhcu8oJAQamW8on9dqw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +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" @@ -1655,17 +8399,220 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -tmp@0.0.x: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== +strip-ansi@6.0.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: - os-tmpdir "~1.0.2" + ansi-regex "^5.0.0" -to-array@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" - integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= +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@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.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-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= + +style-loader@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.7.0" + +style-to-object@0.3.0, style-to-object@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== + dependencies: + inline-style-parser "0.1.1" + +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.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" + +symbol.prototype.description@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.4.tgz#c30edd3fe8c040d941cf7dc15842be15adf66855" + integrity sha512-fZkHwJ8ZNRVRzF/+/2OtygyyH06CjC0YZAQRHu9jKKw8RXlJpbizEHvGRUu22Qkg182wJk1ugb5Aovcv3UPrww== + dependencies: + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.2" + +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== + +tar@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +telejson@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.1.0.tgz#cc04e4c2a355f9eb6af557e37acd6449feb1d146" + integrity sha512-Yy0N2OV0mosmr1SCZEm3Ezhu/oi5Dbao5RqauZu4+VI5I/XtVBHXajRk0txuqbFYtKdzzWGDZFGSif9ovVLjEA== + dependencies: + "@types/is-function" "^1.0.0" + global "^4.4.0" + is-function "^1.0.2" + is-regex "^1.1.1" + is-symbol "^1.0.3" + isobject "^4.0.0" + lodash "^4.17.20" + memoizerific "^1.11.3" + +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-webpack-plugin@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz#91e6d39571460ed240c0cf69d295bcf30ebf98cb" + integrity sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.2.1" + p-limit "^3.0.2" + schema-utils "^2.6.6" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.8.0" + webpack-sources "^1.4.3" + +terser@^4.1.2, terser@^4.6.3, terser@^4.8.0: + 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" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +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= + +throttle-debounce@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" + integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== + +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" + +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" + +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== + +tmp@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +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-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" @@ -1682,6 +8629,13 @@ to-regex-range@^2.1.0: 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" @@ -1692,12 +8646,79 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= + 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== -type-is@~1.6.17: +trim-trailing-lines@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" + integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + +ts-dedent@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.1.0.tgz#2df17a997ee5310a96d2be7adca0ba7c3eabf36a" + integrity sha512-HbmrG+lCgk5W8LQTALxBxQRBDeAhQKRzdqVhHLUkVd5nYT+b6zDzbRMjiA8wqrWDa33X09WdnW4zEsdwQArTaw== + +ts-essentials@^2.0.3: + version "2.0.12" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" + integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +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= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +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== @@ -1705,10 +8726,80 @@ type-is@~1.6.17: media-typer "0.3.0" mime-types "~2.1.24" -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= +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= + +ua-parser-js@^0.7.23: + version "0.7.25" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.25.tgz#67689fa263a87a52dabbc251ede89891f59156ce" + integrity sha512-8NFExdfI24Ny8R3Vc6+uUytP/I7dpqk3JERlvxPWlrtx5YboqCgxAXYKPAifbPLV2zKbgmmPL53ufW7mUC/VOQ== + +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" + +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + +unherit@^1.0.4: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== + dependencies: + inherits "^2.0.0" + xtend "^4.0.0" + +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== + +unified@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" + integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" union-value@^1.0.0: version "1.0.1" @@ -1720,11 +8811,103 @@ union-value@^1.0.0: 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= + +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" + +unist-builder@2.0.3, unist-builder@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== + +unist-util-generated@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" + integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== + +unist-util-is@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" + integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== + +unist-util-position@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== + +unist-util-remove-position@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" + integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== + dependencies: + unist-util-visit "^2.0.0" + +unist-util-remove@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.0.1.tgz#fa13c424ff8e964f3aa20d1098b9a690c6bfaa39" + integrity sha512-YtuetK6o16CMfG+0u4nndsWpujgsHDHHLyE0yGpJLLn5xSjKeyGyzEBOI2XbmoUHCYabmNgX52uxlWoQhcvR7Q== + dependencies: + unist-util-is "^4.0.0" + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-visit-parents@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@2.0.3, unist-util-visit@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.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== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + 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.0: + 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" @@ -1733,80 +8916,408 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.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== + +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@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.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-composed-ref@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" + integrity sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg== + dependencies: + ts-essentials "^2.0.3" + +use-isomorphic-layout-effect@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225" + integrity sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ== + +use-latest@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" + integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== + dependencies: + use-isomorphic-layout-effect "^1.0.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== -useragent@^2.1.6: - version "2.3.0" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" - integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== - dependencies: - lru-cache "4.1.x" - tmp "0.0.x" - -util-deprecate@~1.0.1: +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@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: + 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, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vfile-location@^3.0.0, vfile-location@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" + integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== + +vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" + integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.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== + void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -which@^1.2.1: +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +warning@^4.0.2, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.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" + +web-namespaces@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== + +webpack-dev-middleware@^3.7.3: + 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-filter-warnings-plugin@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" + integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + +webpack-hot-middleware@^2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" + integrity sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA== + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + +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-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + 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-virtual-modules@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" + integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== + dependencies: + debug "^3.0.0" + +webpack@4: + 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" + +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@^1.2.1, which@^1.2.9, which@^1.3.1: 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" -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +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" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +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" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@~1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" - integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w== +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: - options ">=0.0.5" - ultron "1.0.x" + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -wtf-8@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" - integrity sha1-OS2LotDxw00e4tYw8V0O+2jhBIo= +ws@~7.4.2: + version "7.4.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" + integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== -xmlhttprequest-ssl@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" - integrity sha1-GFqIjATspGw+QHDZn3tJ3jUomS0= +xtend@^4.0.0, xtend@^4.0.1, 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== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== -yeast@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" - integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.2: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==